sql >> Base de Datos >  >> RDS >> SQLite

Clave foránea de SQLite

Resumen :en este tutorial, aprenderá cómo usar la restricción de clave externa de SQLite para hacer cumplir las relaciones entre tablas relacionadas.

Soporte de restricción de clave externa de SQLite

SQLite admite la restricción de clave externa desde la versión 3.6.19. La biblioteca SQLite también debe compilarse sin SQLITE_OMIT_FOREIGN_KEY ni SQLITE_OMIT_TRIGGER.

Para verificar si su versión actual de SQLite admite restricciones de clave externa o no, use el siguiente comando.

PRAGMA foreign_keys;Code language: SQL (Structured Query Language) (sql)

El comando devuelve un valor entero:1:habilitado, 0:deshabilitado. Si el comando no devuelve nada, significa que su versión de SQLite no admite restricciones de clave externa.

Si la biblioteca SQLite se compila con compatibilidad con restricciones de clave externa, la aplicación puede usar PRAGMA foreign_keys comando para habilitar o deshabilitar las restricciones de clave externa en tiempo de ejecución.

Para deshabilitar la restricción de clave externa:

PRAGMA foreign_keys = OFF;Code language: SQL (Structured Query Language) (sql)

Para habilitar la restricción de clave externa:

PRAGMA foreign_keys = ON;Code language: SQL (Structured Query Language) (sql)

Introducción a las restricciones de clave externa de SQLite

Comencemos con dos tablas:suppliers y supplier_groups :

CREATE TABLE suppliers (
	supplier_id integer PRIMARY KEY,
	supplier_name text NOT NULL,
	group_id integer NOT NULL
);

CREATE TABLE supplier_groups (
	group_id integer PRIMARY KEY,
	group_name text NOT NULL
);Code language: SQL (Structured Query Language) (sql)

Suponiendo que cada proveedor pertenece a un único grupo de proveedores. Y cada grupo de proveedores puede tener cero o muchos proveedores. La relación entre supplier_groups y suppliers tablas es de uno a muchos. En otras palabras, para cada fila en los suppliers tabla, hay una fila correspondiente en supplier_groups mesa.

Actualmente, no hay forma de evitar que agregue una fila a los suppliers tabla sin una fila correspondiente en supplier_groups mesa.

Además, puede eliminar una fila en supplier_groups tabla sin eliminar o actualizar las filas correspondientes en suppliers mesa. Esto puede dejar filas huérfanas en los suppliers mesa.

Para hacer cumplir la relación entre filas en los suppliers y supplier_groups tabla, utiliza las restricciones de clave externa .

Para agregar la restricción de clave externa a los suppliers tabla, cambia la definición de CREATE TABLE declaración anterior de la siguiente manera:

DROP TABLE suppliers;

CREATE TABLE suppliers (
    supplier_id   INTEGER PRIMARY KEY,
    supplier_name TEXT    NOT NULL,
    group_id      INTEGER NOT NULL,
    FOREIGN KEY (group_id)
       REFERENCES supplier_groups (group_id) 
);
Code language: SQL (Structured Query Language) (sql)

Los supplier_groups la tabla se denomina tabla principal , que es la tabla a la que hace referencia una clave externa. Los suppliers la tabla se conoce como tabla secundaria , que es la tabla a la que se aplica la restricción de clave externa.

El group_id columna en supplier_groups la tabla se denomina clave principal , que es una columna o un conjunto de columnas en la tabla principal a la que hace referencia la restricción de clave externa. Normalmente, la clave principal es la clave principal de la tabla principal.

El group_id columna en los suppliers la tabla se llama clave secundaria. Generalmente, la clave secundaria hace referencia a la clave principal de la tabla principal.

Ejemplo de restricción de clave externa de SQLite

Primero, inserte tres filas en supplier_groups mesa.

INSERT INTO supplier_groups (group_name)
VALUES
   ('Domestic'),
   ('Global'),
   ('One-Time');Code language: SQL (Structured Query Language) (sql)

En segundo lugar, inserte un nuevo proveedor en suppliers tabla con el grupo de proveedores que existe en supplier_groups mesa.

INSERT INTO suppliers (supplier_name, group_id)
VALUES ('HP', 2);Code language: SQL (Structured Query Language) (sql)

Esta declaración funciona perfectamente bien.

En tercer lugar, intente insertar un nuevo proveedor en los suppliers tabla con el grupo de proveedores que no existe en los supplier_groups mesa.

INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Inc.', 4);Code language: SQL (Structured Query Language) (sql)

SQLite verificó la restricción de clave externa, rechazó el cambio y emitió el siguiente mensaje de error:

[SQLITE_CONSTRAINT]  Abort due to constraint violation (FOREIGN KEY constraint failed)Code language: CSS (css)

Acciones de restricción de clave externa de SQLite

¿Qué sucedería si elimina una fila en supplier_groups? ¿mesa? Deben todas las filas correspondientes en los suppliers tabla también se eliminan? Las mismas preguntas a la operación de actualización.

Para especificar cómo se comporta la restricción de clave externa cada vez que se elimina o actualiza la clave principal, utilice ON DELETE o ON UPDATE acción de la siguiente manera:

FOREIGN KEY (foreign_key_columns)
   REFERENCES parent_table(parent_key_columns)
      ON UPDATE action 
      ON DELETE action;Code language: SQL (Structured Query Language) (sql)

SQLite admite las siguientes acciones:

  • ESTABLECER NULO
  • ESTABLECER PREDETERMINADO
  • RESTRINGIR
  • SIN ACCIÓN
  • CASCADA

En la práctica, los valores de la clave principal en la tabla principal no cambian, por lo que las reglas de actualización son menos importantes. La regla más importante es DELETE regla que especifica la acción cuando se elimina la clave principal.

Examinaremos cada acción con el siguiente ejemplo

ESTABLECER NULO

Cuando la clave principal cambia, elimina o actualiza, las claves secundarias correspondientes de todas las filas en la tabla secundaria se establecen en NULL.

Primero, suelte y cree la tabla suppliers usando el SET NULL acción para el group_id clave foránea:

DROP TABLE suppliers;

CREATE TABLE suppliers (
    supplier_id   INTEGER PRIMARY KEY,
    supplier_name TEXT    NOT NULL,
    group_id      INTEGER,
    FOREIGN KEY (group_id)
    REFERENCES supplier_groups (group_id) 
       ON UPDATE SET NULL
       ON DELETE SET NULL
);
Code language: SQL (Structured Query Language) (sql)

En segundo lugar, inserte algunas filas en suppliers tabla:

INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 3);

INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Corp', 3);Code language: SQL (Structured Query Language) (sql)

En tercer lugar, elimine el ID de grupo de proveedores 3 de supplier_groups tabla:

DELETE FROM supplier_groups 
WHERE group_id = 3;Code language: SQL (Structured Query Language) (sql)

Cuarto, consulta los datos de los suppliers mesa.

SELECT * FROM suppliers;Code language: SQL (Structured Query Language) (sql)

Los valores del group_id columna de las filas correspondientes en los suppliers tabla establecida en NULL.

ESTABLECER POR DEFECTO

El SET DEFAULT action establece el valor de la clave externa en el valor predeterminado especificado en la definición de la columna cuando crea la tabla.

Porque los valores en la columna group_id el valor predeterminado es NULL, si elimina una fila de supplier_groups tabla, los valores del group_id se establecerá en NULL.

Después de asignar el valor predeterminado, la restricción de clave externa se activa y lleva el control.

RESTRINGIR

El RESTRICT La acción no le permite cambiar o eliminar valores en la clave principal de la tabla principal.

Primero, suelte y cree los suppliers tabla con el RESTRICT acción en la clave foránea group_id :

DROP TABLE suppliers;

CREATE TABLE suppliers (
    supplier_id   INTEGER PRIMARY KEY,
    supplier_name TEXT    NOT NULL,
    group_id      INTEGER,
    FOREIGN KEY (group_id)
    REFERENCES supplier_groups (group_id) 
       ON UPDATE RESTRICT
       ON DELETE RESTRICT
);Code language: SQL (Structured Query Language) (sql)

En segundo lugar, inserte una fila en la tabla suppliers con el group_id 1.

INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 1);Code language: SQL (Structured Query Language) (sql)

Tercero, elimine el grupo de proveedores con id 1 de supplier_groups tabla:

DELETE FROM supplier_groups 
WHERE group_id = 1;Code language: SQL (Structured Query Language) (sql)

SQLite emitió el siguiente error:

[SQLITE_CONSTRAINT]  Abort due to constraint violation (FOREIGN KEY constraint failed)Code language: CSS (css)

Para solucionarlo, primero debe eliminar todas las filas de los suppliers tabla que tiene group_id 1:

DELETE FROM suppliers 
WHERE group_id =1;Code language: SQL (Structured Query Language) (sql)

Luego, puede eliminar el grupo de proveedores 1 de supplier_groups tabla:

DELETE FROM supplier_groups 
WHERE group_id = 1;Code language: SQL (Structured Query Language) (sql)

SIN ACCIÓN

El NO ACTION no significa eludir la restricción de clave externa. Tiene un efecto similar al RESTRICT .

CASCADA

La CASCADE La acción propaga los cambios de la tabla principal a la tabla secundaria cuando actualiza o elimina la clave principal.

Primero, inserte el supplier grupos en supplier_groups tabla:

INSERT INTO supplier_groups (group_name)
VALUES
   ('Domestic'),
   ('Global'),
   ('One-Time');Code language: SQL (Structured Query Language) (sql)

En segundo lugar, suelte y cree la tabla suppliers con la CASCADE acción en la clave foránea group_id :

DROP TABLE suppliers;

CREATE TABLE suppliers (
    supplier_id   INTEGER PRIMARY KEY,
    supplier_name TEXT    NOT NULL,
    group_id      INTEGER,
    FOREIGN KEY (group_id)
    REFERENCES supplier_groups (group_id) 
       ON UPDATE CASCADE
       ON DELETE CASCADE
);Code language: SQL (Structured Query Language) (sql)

Tercero, inserte algunos proveedores en la tabla suppliers :

INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 1);

INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Corp', 2);Code language: SQL (Structured Query Language) (sql)

Cuarto, actualice group_id del Domestic grupo de proveedores a 100:

UPDATE supplier_groups
SET group_id = 100
WHERE group_name = 'Domestic';Code language: SQL (Structured Query Language) (sql)

Quinto, consulta los datos de la tabla suppliers :

SELECT * FROM suppliers;Code language: SQL (Structured Query Language) (sql)

Como puede ver el valor en el group_id columna de la XYZ Corp en la tabla suppliers cambió de 1 a 100 cuando actualizamos el group_id en los supplier_groups mesa. Este es el resultado de ON UPDATE CASCADE acción.

Sexto, elimine el ID de grupo de proveedores 2 de supplier_groups tabla:

DELETE FROM supplier_groups 
WHERE group_id = 2;Code language: SQL (Structured Query Language) (sql)

Séptimo, consulta los datos de la tabla suppliers :

SELECT * FROM suppliers;Code language: SQL (Structured Query Language) (sql)

El proveedor id 2 cuyo group_id is 2 se eliminó cuando el ID de grupo de proveedores 2 se eliminó de supplier_groups mesa. Este es el efecto de ON DELETE CASCADE acción.

En este tutorial, aprendió sobre la restricción de clave externa de SQLite y cómo usarla para hacer cumplir la relación entre tablas relacionadas.