SQLite
 sql >> Database >  >> RDS >> SQLite

Chiave esterna SQLite

Riepilogo :in questo tutorial imparerai come utilizzare il vincolo di chiave esterna SQLite per rafforzare le relazioni tra tabelle correlate.

Supporto per vincoli di chiave esterna SQLite

SQLite ha supportato il vincolo della chiave esterna dalla versione 3.6.19. Anche la libreria SQLite deve essere compilata né con SQLITE_OMIT_FOREIGN_KEY né con SQLITE_OMIT_TRIGGER.

Per verificare se la versione corrente di SQLite supporta o meno i vincoli di chiave esterna, utilizzare il comando seguente.

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

Il comando restituisce un valore intero:1:abilitato, 0:disabilitato. Se il comando non restituisce nulla, significa che la tua versione di SQLite non supporta i vincoli di chiave esterna.

Se la libreria SQLite è compilata con il supporto del vincolo di chiave esterna, l'applicazione può utilizzare il PRAGMA foreign_keys comando per abilitare o disabilitare i vincoli di chiave esterna in fase di esecuzione.

Per disabilitare il vincolo di chiave esterna:

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

Per abilitare il vincolo di chiave esterna:

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

Introduzione ai vincoli di chiave esterna di SQLite

Iniziamo con due tabelle:suppliers e 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)

Supponendo che ogni fornitore appartenga a uno e un solo gruppo di fornitori. E ogni gruppo di fornitori può avere zero o molti fornitori. La relazione tra supplier_groups e suppliers i tavoli sono uno a molti. In altre parole, per ogni riga di suppliers tabella, c'è una riga corrispondente in supplier_groups tabella.

Al momento, non c'è modo di impedirti di aggiungere una riga ai suppliers tabella senza una riga corrispondente nei supplier_groups tabella.

Inoltre, puoi rimuovere una riga in supplier_groups tabella senza eliminare o aggiornare le righe corrispondenti nei suppliers tavolo. Ciò potrebbe lasciare righe orfane nei suppliers tabella.

Per imporre la relazione tra le righe nei suppliers e supplier_groups tabella, utilizzi i vincoli di chiave esterna .

Per aggiungere il vincolo di chiave esterna ai suppliers table, si cambia la definizione di CREATE TABLE dichiarazione di cui sopra come segue:

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)

I supplier_groups table è chiamata tabella padre , che è la tabella a cui fa riferimento una chiave esterna. I suppliers table è noto come tabella figlio , che è la tabella a cui si applica il vincolo di chiave esterna.

Il group_id colonna nel supplier_groups la tabella è chiamata chiave principale , che è una colonna o un insieme di colonne nella tabella padre a cui fa riferimento il vincolo di chiave esterna. In genere, la chiave padre è la chiave primaria della tabella padre.

Il group_id nella colonna suppliers tabella è chiamata chiave figlio. In genere, la chiave figlio fa riferimento alla chiave primaria della tabella padre.

Esempio di vincolo di chiave esterna SQLite

Innanzitutto, inserisci tre righe in supplier_groups tabella.

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

In secondo luogo, inserisci un nuovo fornitore nei suppliers tabella con il gruppo di fornitori che esiste in supplier_groups tabella.

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

Questa affermazione funziona perfettamente.

Terzo, prova a inserire un nuovo fornitore nei suppliers tabella con il gruppo di fornitori che non esiste in supplier_groups tabella.

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

SQLite ha verificato il vincolo di chiave esterna, ha rifiutato la modifica e ha emesso il seguente messaggio di errore:

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

Azioni di vincolo di chiave esterna SQLite

Cosa accadrebbe se elimini una riga in supplier_groups tavolo? Dovrebbero tutte le righe corrispondenti nei suppliers anche la tabella viene eliminata? Le stesse domande all'operazione di aggiornamento.

Per specificare come si comporta il vincolo di chiave esterna ogni volta che la chiave genitore viene eliminata o aggiornata, utilizzare ON DELETE o ON UPDATE azione come segue:

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 supporta le seguenti azioni:

  • IMPOSTA NULLA
  • IMPOSTA PREDEFINITO
  • LIMITI
  • NESSUNA AZIONE
  • CASCATA

In pratica i valori della chiave primaria nella tabella padre non cambiano quindi le regole di aggiornamento sono meno importanti. La regola più importante è DELETE regola che specifica l'azione quando la chiave padre viene eliminata.

Esamineremo ogni azione con il seguente esempio

IMPOSTA NULLA

Quando la chiave padre cambia, elimina o aggiorna, le chiavi figlio corrispondenti di tutte le righe nella tabella figlio vengono impostate su NULL.

Per prima cosa, rilascia e crea la tabella suppliers utilizzando il SET NULL azione per group_id chiave esterna:

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)

In secondo luogo, inserisci alcune righe nei suppliers tabella:

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)

Terzo, elimina l'ID del gruppo di fornitori 3 da supplier_groups tabella:

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

In quarto luogo, interroga i dati dai suppliers tabella.

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

I valori di group_id colonna delle righe corrispondenti in suppliers tabella impostata su NULL.

IMPOSTA PREDEFINITO

Il SET DEFAULT action imposta il valore della chiave esterna sul valore predefinito specificato nella definizione di colonna quando crei la tabella.

Perché i valori nella colonna group_id il valore predefinito è NULL, se elimini una riga da supplier_groups tabella, i valori di group_id verrà impostato su NULL.

Dopo aver assegnato il valore di default, il vincolo di chiave esterna si attiva e porta il controllo.

RESTRIZIONE

Il RESTRICT action non consente di modificare o eliminare i valori nella chiave padre della tabella padre.

Per prima cosa, rilascia e crea i suppliers tabella con il RESTRICT azione nella chiave esterna 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)

In secondo luogo, inserisci una riga nella tabella suppliers con il gruppo_id 1.

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

Terzo, elimina il gruppo di fornitori con ID 1 da supplier_groups tabella:

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

SQLite ha emesso il seguente errore:

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

Per risolverlo, devi prima eliminare tutte le righe dai suppliers tabella che ha group_id 1:

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

Quindi, puoi eliminare il gruppo di fornitori 1 da supplier_groups tabella:

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

NESSUNA AZIONE

Il NO ACTION non significa bypassare il vincolo della chiave esterna. Ha l'effetto simile a RESTRICT .

CASCATA

La CASCADE action propaga le modifiche dalla tabella padre alla tabella figlio quando aggiorni o elimini la chiave padre.

Innanzitutto, inserisci il supplier gruppi nei supplier_groups tabella:

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

In secondo luogo, rilascia e crea la tabella suppliers con la CASCADE azione nella chiave esterna 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)

Terzo, inserisci alcuni fornitori nella tabella 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)

In quarto luogo, aggiorna group_id del Domestic gruppo fornitori a 100:

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

Quinto, interroga i dati dalla tabella suppliers :

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

Come puoi vedere il valore nel group_id colonna della XYZ Corp nella tabella suppliers cambiato da 1 a 100 quando abbiamo aggiornato il group_id nei supplier_groups tavolo. Questo è il risultato di ON UPDATE CASCADE azione.

Sesto, elimina l'ID del gruppo di fornitori 2 da supplier_groups tabella:

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

Settimo, interroga i dati dalla tabella suppliers :

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

L'ID fornitore 2 il cui group_id è 2 è stato eliminato quando l'ID del gruppo di fornitori 2 è stato rimosso da supplier_groups tavolo. Questo è l'effetto di ON DELETE CASCADE azione.

In questo tutorial, hai imparato a conoscere i vincoli di chiave esterna SQLite e come usarli per rafforzare la relazione tra tabelle correlate.