SQLite
 sql >> Datenbank >  >> RDS >> SQLite

SQLite-Fremdschlüssel

Zusammenfassung :In diesem Tutorial erfahren Sie, wie Sie die SQLite-Fremdschlüsseleinschränkung verwenden, um die Beziehungen zwischen verwandten Tabellen zu erzwingen.

Unterstützung von SQLite-Fremdschlüsselbeschränkungen

SQLite unterstützt die Fremdschlüsselbeschränkung seit Version 3.6.19. Die SQLite-Bibliothek darf auch weder mit SQLITE_OMIT_FOREIGN_KEY noch mit SQLITE_OMIT_TRIGGER kompiliert werden.

Um zu überprüfen, ob Ihre aktuelle Version von SQLite Foreign Key Constraints unterstützt oder nicht, verwenden Sie den folgenden Befehl.

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

Der Befehl gibt einen ganzzahligen Wert zurück:1:aktiviert, 0:deaktiviert. Wenn der Befehl nichts zurückgibt, bedeutet dies, dass Ihre SQLite-Version keine Fremdschlüsselbeschränkungen unterstützt.

Wenn die SQLite-Bibliothek mit Unterstützung für Fremdschlüsseleinschränkungen kompiliert wird, kann die Anwendung die PRAGMA foreign_keys verwenden Befehl zum Aktivieren oder Deaktivieren von Fremdschlüsselbeschränkungen zur Laufzeit.

So deaktivieren Sie die Fremdschlüsselbeschränkung:

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

So aktivieren Sie die Fremdschlüsselbeschränkung:

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

Einführung in die SQLite-Fremdschlüsseleinschränkungen

Beginnen wir mit zwei Tabellen:suppliers und 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)

Unter der Annahme, dass jeder Lieferant zu genau einer Lieferantengruppe gehört. Und jede Lieferantengruppe kann null oder viele Lieferanten haben. Die Beziehung zwischen supplier_groups und suppliers Tabellen ist eins-zu-viele. Mit anderen Worten, für jede Zeile in suppliers Tabelle gibt es eine entsprechende Zeile in der supplier_groups Tabelle.

Derzeit gibt es keine Möglichkeit, Sie daran zu hindern, eine Zeile zu den suppliers hinzuzufügen Tabelle ohne entsprechende Zeile in supplier_groups Tabelle.

Außerdem können Sie eine Zeile in den supplier_groups entfernen Tabelle, ohne die entsprechenden Zeilen in suppliers zu löschen oder zu aktualisieren Tisch. Dadurch können verwaiste Zeilen in suppliers zurückbleiben Tabelle.

Um die Beziehung zwischen Zeilen in den suppliers zu erzwingen und supplier_groups Tabelle verwenden Sie die Fremdschlüsseleinschränkungen .

Zum Hinzufügen der Fremdschlüsseleinschränkung zu den suppliers Tabelle ändern Sie die Definition der CREATE TABLE Anweisung oben wie folgt:

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)

Die supplier_groups Tabelle wird als Elterntabelle bezeichnet , das ist die Tabelle, auf die ein Fremdschlüssel verweist. Die suppliers Tabelle wird als untergeordnete Tabelle bezeichnet , das ist die Tabelle, für die die Fremdschlüsseleinschränkung gilt.

Die group_id Spalte in der supplier_groups Tabelle wird als Elternschlüssel bezeichnet , bei der es sich um eine Spalte oder einen Satz von Spalten in der übergeordneten Tabelle handelt, auf die die Fremdschlüsseleinschränkung verweist. Normalerweise ist der Elternschlüssel der Primärschlüssel der Elterntabelle.

Die group_id Spalte suppliers Tabelle wird als untergeordneter Schlüssel bezeichnet. Im Allgemeinen verweist der untergeordnete Schlüssel auf den Primärschlüssel der übergeordneten Tabelle.

Beispiel für SQLite-Fremdschlüsseleinschränkung

Fügen Sie zuerst drei Zeilen in die supplier_groups ein Tabelle.

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

Zweitens fügen Sie einen neuen Lieferanten in den suppliers ein Tabelle mit der Lieferantengruppe, die in supplier_groups vorhanden ist Tabelle.

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

Diese Anweisung funktioniert einwandfrei.

Versuchen Sie drittens, einen neuen Lieferanten in die suppliers einzufügen Tabelle mit der Lieferantengruppe, die nicht in der supplier_groups existiert Tabelle.

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

SQLite überprüfte die Fremdschlüsseleinschränkung, lehnte die Änderung ab und gab die folgende Fehlermeldung aus:

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

SQLite Foreign Key Constraint Actions

Was würde passieren, wenn Sie eine Zeile in supplier_groups löschen Tisch? Sollten alle entsprechenden Zeilen in den suppliers Tabelle werden auch gelöscht? Die gleichen Fragen zum Update-Vorgang.

Um anzugeben, wie sich die Fremdschlüsseleinschränkung verhält, wenn der übergeordnete Schlüssel gelöscht oder aktualisiert wird, verwenden Sie den ON DELETE oder ON UPDATE Aktion wie folgt:

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 unterstützt die folgenden Aktionen:

  • NULL SETZEN
  • STANDARD EINSTELLEN
  • BESCHRÄNKEN
  • KEINE AKTION
  • KASKADE

In der Praxis ändern sich die Werte des Primärschlüssels in der übergeordneten Tabelle nicht, daher sind die Aktualisierungsregeln weniger wichtig. Die wichtigere Regel ist das DELETE Regel, die die Aktion angibt, wenn der übergeordnete Schlüssel gelöscht wird.

Wir werden jede Aktion anhand des folgenden Beispiels untersuchen

NULL SETZEN

Wenn sich der übergeordnete Schlüssel ändert, löscht oder aktualisiert, werden die entsprechenden untergeordneten Schlüssel aller Zeilen in der untergeordneten Tabelle auf NULL gesetzt.

Löschen und erstellen Sie zunächst die Tabelle suppliers mit dem SET NULL Aktion für group_id Fremdschlüssel:

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)

Zweitens fügen Sie einige Zeilen in suppliers ein Tabelle:

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)

Drittens löschen Sie die Lieferantengruppen-ID 3 aus supplier_groups Tabelle:

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

Viertens, fragen Sie Daten von den suppliers ab Tabelle.

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

Die Werte der group_id Spalte der entsprechenden Zeilen in den suppliers Tabelle auf NULL gesetzt.

STANDARD EINSTELLEN

Der SET DEFAULT Aktion setzt den Wert des Fremdschlüssels auf den in der Spaltendefinition angegebenen Standardwert, wenn Sie die Tabelle erstellen.

Da die Werte in der Spalte group_id ist standardmäßig NULL, wenn Sie eine Zeile aus supplier_groups löschen Tabelle, die Werte der group_id wird auf NULL gesetzt.

Nach dem Zuweisen des Standardwerts tritt die Fremdschlüsselbeschränkung ein und führt die Überprüfung durch.

EINSCHRÄNKUNG

Das RESTRICT Aktion erlaubt es Ihnen nicht, Werte im übergeordneten Schlüssel der übergeordneten Tabelle zu ändern oder zu löschen.

Löschen und erstellen Sie zuerst die suppliers Tabelle mit dem RESTRICT Aktion im Fremdschlüssel 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)

Zweitens fügen Sie eine Zeile in die Tabelle suppliers ein mit der Gruppen-ID 1.

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

Drittens löschen Sie die Lieferantengruppe mit der ID 1 aus den supplier_groups Tabelle:

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

SQLite hat den folgenden Fehler ausgegeben:

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

Um dies zu beheben, müssen Sie zuerst alle Zeilen von suppliers löschen Tabelle mit group_id 1:

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

Anschließend können Sie die Lieferantengruppe 1 aus den supplier_groups löschen Tabelle:

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

KEINE AKTION

Die NO ACTION bedeutet nicht, die Fremdschlüsseleinschränkung zu umgehen. Es hat eine ähnliche Wirkung wie RESTRICT .

KASKADE

Die CASCADE Aktion überträgt die Änderungen von der übergeordneten Tabelle an die untergeordnete Tabelle, wenn Sie den übergeordneten Schlüssel aktualisieren oder löschen.

Fügen Sie zuerst den suppliers ein Gruppen in die supplier_groups Tabelle:

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

Zweitens, löschen und erstellen Sie die Tabelle suppliers mit dem CASCADE Aktion im Fremdschlüssel 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)

Drittens fügen Sie einige Lieferanten in die Tabelle suppliers ein :

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)

Als viertes aktualisieren Sie group_id des Domestic Lieferantengruppe auf 100:

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

Fragen Sie fünftens Daten aus der Tabelle suppliers ab :

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

Wie Sie den Wert in der group_id sehen können Spalte der XYZ Corp in der Tabelle suppliers von 1 auf 100 geändert, als wir die group_id aktualisiert haben in den suplier_groups Tisch. Dies ist das Ergebnis von ON UPDATE CASCADE Aktion.

Sechstens:Lieferantengruppen-ID 2 aus supplier_groups löschen Tabelle:

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

Siebtens fragen Sie Daten aus der Tabelle suppliers ab :

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

Die Lieferanten-ID 2, deren group_id is 2 wurde gelöscht, als die Lieferantengruppen-ID 2 aus den supplier_groups entfernt wurde Tisch. Dies ist die Auswirkung von ON DELETE CASCADE Aktion.

In diesem Lernprogramm haben Sie etwas über SQLite-Fremdschlüsseleinschränkungen gelernt und wie Sie sie verwenden, um die Beziehung zwischen verwandten Tabellen zu erzwingen.