SQLite
 sql >> Baza danych >  >> RDS >> SQLite

Klucz obcy SQLite

Podsumowanie :w tym samouczku dowiesz się, jak używać ograniczenia klucza obcego SQLite do wymuszania relacji między powiązanymi tabelami.

Obsługa ograniczeń klucza obcego SQLite

SQLite obsługuje ograniczenie klucza obcego od wersji 3.6.19. Biblioteka SQLite musi być również skompilowana bez SQLITE_OMIT_FOREIGN_KEY ani SQLITE_OMIT_TRIGGER.

Aby sprawdzić, czy twoja aktualna wersja SQLite obsługuje ograniczenia klucza obcego, czy nie, użyj następującego polecenia.

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

Polecenie zwraca wartość całkowitą:1:włącz, 0:wyłącz. Jeśli polecenie nic nie zwraca, oznacza to, że twoja wersja SQLite nie obsługuje ograniczeń kluczy obcych.

Jeśli biblioteka SQLite jest skompilowana z obsługą ograniczeń kluczy obcych, aplikacja może użyć PRAGMA foreign_keys polecenie, aby włączyć lub wyłączyć ograniczenia klucza obcego w czasie wykonywania.

Aby wyłączyć ograniczenie klucza obcego:

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

Aby włączyć ograniczenie klucza obcego:

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

Wprowadzenie do ograniczeń kluczy obcych SQLite

Zacznijmy od dwóch tabel:suppliers i 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)

Przy założeniu, że każdy dostawca należy do jednej i tylko jednej grupy dostawców. Każda grupa dostawców może mieć zero lub wielu dostawców. Związek między supplier_groups i suppliers tabele to jeden do wielu. Innymi słowy, dla każdego wiersza w suppliers tabeli, odpowiedni wiersz znajduje się w supplier_groups tabela.

Obecnie nie ma sposobu, aby uniemożliwić dodanie wiersza do suppliers tabela bez odpowiedniego wiersza w supplier_groups tabela.

Ponadto możesz usunąć wiersz w supplier_groups tabela bez usuwania lub aktualizowania odpowiednich wierszy w suppliers stół. Może to pozostawić osierocone wiersze u suppliers tabela.

Aby wymusić relację między wierszami u suppliers i supplier_groups tabeli, używasz ograniczeń kluczy obcych .

Aby dodać ograniczenie klucza obcego do suppliers tabeli, zmieniasz definicję CREATE TABLE oświadczenie powyżej w następujący sposób:

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)

supplier_groups tabela nazywana jest tablicą nadrzędną , czyli tabela, do której odwołuje się klucz obcy. suppliers tabela jest znana jako tabela podrzędna , czyli tabela, do której stosuje się ograniczenie klucza obcego.

group_id kolumna w supplier_groups tabela nazywa się kluczem nadrzędnym , czyli kolumna lub zestaw kolumn w tabeli nadrzędnej, do której odwołuje się ograniczenie klucza obcego. Zazwyczaj klucz nadrzędny jest kluczem podstawowym tabeli nadrzędnej.

group_id kolumna w suppliers tabela nazywana jest kluczem potomnym. Ogólnie klucz potomny odwołuje się do klucza głównego tabeli nadrzędnej.

Przykład ograniczenia klucza obcego SQLite

Najpierw wstaw trzy wiersze do supplier_groups tabela.

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

Po drugie, wstaw nowego dostawcę do suppliers tabela z grupą dostawców istniejącą w supplier_groups tabela.

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

To stwierdzenie działa doskonale.

Po trzecie, spróbuj wstawić nowego dostawcę do suppliers tabela z grupą dostawców, która nie istnieje w supplier_groups tabela.

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

SQLite sprawdził ograniczenie klucza obcego, odrzucił zmianę i wysłał następujący komunikat o błędzie:

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

Działania ograniczające klucze obce SQLite

Co się stanie, jeśli usuniesz wiersz w supplier_groups stół? Czy wszystkie odpowiednie wiersze w suppliers? tabela również została usunięta? Te same pytania dotyczące operacji aktualizacji.

Aby określić, jak zachowuje się ograniczenie klucza obcego, gdy klucz nadrzędny jest usuwany lub aktualizowany, użyj ON DELETE lub ON UPDATE działanie w następujący sposób:

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 obsługuje następujące akcje:

  • USTAW NULL
  • USTAW DOMYŚLNE
  • OGRANICZONE
  • BRAK DZIAŁANIA
  • KASKADA

W praktyce wartości klucza podstawowego w tabeli nadrzędnej nie zmieniają się, dlatego zasady aktualizacji są mniej ważne. Ważniejszą zasadą jest DELETE reguła określająca akcję po usunięciu klucza nadrzędnego.

Przeanalizujemy każdą akcję na poniższym przykładzie

USTAW NULL

Gdy klucz nadrzędny zostanie zmieniony, usunięty lub zaktualizowany, odpowiednie klucze podrzędne wszystkich wierszy w tabeli podrzędnej zostaną ustawione na NULL.

Najpierw upuść i utwórz tabelę suppliers używając SET NULL akcja dla group_id klucz obcy:

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)

Po drugie, wstaw kilka wierszy do suppliers tabela:

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)

Po trzecie, usuń identyfikator grupy dostawców 3 z supplier_groups tabela:

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

Po czwarte, zapytaj o dane od suppliers tabela.

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

Wartości group_id kolumna odpowiednich wierszy w suppliers tabela ustawiona na NULL.

USTAW DOMYŚLNE

SET DEFAULT akcja ustawia wartość klucza obcego na wartość domyślną określoną w definicji kolumny podczas tworzenia tabeli.

Ponieważ wartości w kolumnie group_id domyślnie NULL, jeśli usuniesz wiersz z supplier_groups tabeli, wartości group_id zostanie ustawiony na NULL.

Po przypisaniu wartości domyślnej, ograniczenie klucza obcego uruchamia się i przenosi kontrolę.

OGRANICZ

RESTRICT akcja nie pozwala na zmianę lub usunięcie wartości w kluczu nadrzędnym tabeli nadrzędnej.

Najpierw upuść i utwórz suppliers tabela z RESTRICT akcja w kluczu obcym 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)

Po drugie, wstaw wiersz do tabeli suppliers z identyfikatorem grupy 1.

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

Po trzecie, usuń grupę dostawców o identyfikatorze 1 z supplier_groups tabela:

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

SQLite wysłał następujący błąd:

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

Aby to naprawić, musisz najpierw usunąć wszystkie wiersze od suppliers tabela, która ma group_id 1:

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

Następnie możesz usunąć grupę dostawców 1 z supplier_groups tabela:

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

BRAK DZIAŁANIA

NO ACTION nie oznacza obejścia ograniczenia klucza obcego. Ma podobny efekt jak RESTRICT .

KASKADA

CASCADE akcja propaguje zmiany z tabeli nadrzędnej do tabeli podrzędnej, gdy aktualizujesz lub usuwasz klucz nadrzędny.

Najpierw wstaw supplier grup w supplier_groups tabela:

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

Po drugie, upuść i utwórz tabelę suppliers z CASCADE akcja w kluczu obcym 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)

Po trzecie, wstaw niektórych dostawców do tabeli 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)

Po czwarte, zaktualizuj group_id Domestic grupa dostawców do 100:

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

Po piąte, zapytaj o dane z tabeli suppliers :

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

Jak widać wartość w group_id kolumna XYZ Corp w tabeli suppliers zmieniono z 1 na 100, gdy zaktualizowaliśmy group_id w suplier_groups stół. To jest wynik ON UPDATE CASCADE działanie.

Po szóste, usuń identyfikator grupy dostawców 2 z supplier_groups tabela:

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

Po siódme, zapytaj o dane z tabeli suppliers :

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

Identyfikator dostawcy 2, którego group_id is 2 zostało usunięte, gdy identyfikator grupy dostawców 2 został usunięty z supplier_groups stół. Jest to efekt ON DELETE CASCADE działanie.

W tym samouczku dowiedziałeś się o ograniczeniach kluczy obcych SQLite i jak ich używać do wymuszania relacji między powiązanymi tabelami.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak utworzyć tabelę tylko wtedy, gdy nie istnieje w SQLite

  2. Migracja pokoju Zmień tabelę nie dodając nowej kolumny i migrując, wywoływana wielokrotnie

  3. Uzyskaj identyfikator wiersza tabeli SQLite FTS3

  4. w pobliżu błędu synatx (kod 1) wstaw Android SQLite

  5. Jak utworzyć kolumnę obliczeniową w SQLite