sql >> Databáze >  >> RDS >> SQLite

cizí klíč SQLite

Shrnutí :v tomto tutoriálu se naučíte, jak používat omezení cizího klíče SQLite k vynucení vztahů mezi souvisejícími tabulkami.

Podpora omezení cizího klíče SQLite

SQLite podporuje omezení cizího klíče od verze 3.6.19. Knihovna SQLite musí být také zkompilována bez SQLITE_OMIT_FOREIGN_KEY ani SQLITE_OMIT_TRIGGER.

Chcete-li zkontrolovat, zda vaše aktuální verze SQLite podporuje omezení cizích klíčů nebo ne, použijte následující příkaz.

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

Příkaz vrací celočíselnou hodnotu:1:povolení, 0:zakázáno. Pokud příkaz nevrací nic, znamená to, že vaše verze SQLite nepodporuje omezení cizích klíčů.

Pokud je knihovna SQLite zkompilována s podporou omezení cizího klíče, aplikace může použít PRAGMA foreign_keys příkaz k povolení nebo zakázání omezení cizích klíčů za běhu.

Chcete-li zakázat omezení cizího klíče:

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

Chcete-li povolit omezení cizího klíče:

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

Úvod do omezení cizího klíče SQLite

Začněme dvěma tabulkami:suppliers a 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)

Za předpokladu, že každý dodavatel patří do jedné a pouze jedné skupiny dodavatelů. A každá skupina dodavatelů může mít nula nebo mnoho dodavatelů. Vztah mezi supplier_groups a suppliers tabulky je jedna k mnoha. Jinými slovy, pro každý řádek v suppliers v tabulce supplier_groups je odpovídající řádek tabulka.

V současné době neexistuje žádný způsob, jak vám zabránit v přidání řádku do suppliers tabulka bez odpovídajícího řádku v supplier_groups tabulka.

Kromě toho můžete odstranit řádek v supplier_groups tabulky bez vymazání nebo aktualizace odpovídajících řádků v suppliers stůl. To může zanechat osamocené řádky v suppliers tabulka.

Pro vynucení vztahu mezi řádky v suppliers a supplier_groups tabulky, použijete omezení cizího klíče .

Chcete-li přidat omezení cizího klíče do suppliers tabulky, změníte definici CREATE TABLE prohlášení výše takto:

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 tabulka se nazývá nadřazená tabulka , což je tabulka, na kterou odkazuje cizí klíč. suppliers tabulka je známá jako dětská tabulka , což je tabulka, na kterou se vztahuje omezení cizího klíče.

group_id ve sloupci supplier_groups tabulka se nazývá nadřazený klíč , což je sloupec nebo sada sloupců v nadřazené tabulce, na kterou odkazuje omezení cizího klíče. Nadřazený klíč je obvykle primárním klíčem nadřazené tabulky.

group_id ve sloupci suppliers tabulka se nazývá podřízený klíč. Obecně platí, že podřízený klíč odkazuje na primární klíč nadřazené tabulky.

Příklad omezení cizího klíče SQLite

Nejprve vložte tři řádky do supplier_groups tabulka.

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

Za druhé, vložte nového dodavatele do suppliers tabulka se skupinou dodavatelů, která existuje v supplier_groups tabulka.

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

Toto prohlášení funguje naprosto dobře.

Za třetí, pokuste se vložit nového dodavatele do suppliers tabulka se skupinou dodavatelů, která neexistuje v supplier_groups tabulka.

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

SQLite zkontroloval omezení cizího klíče, odmítl změnu a vydal následující chybovou zprávu:

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

Akce omezení cizího klíče SQLite

Co by se stalo, kdybyste odstranili řádek ve skupině supplier_groups stůl? Měly by všechny odpovídající řádky v suppliers jsou také smazány tabulky? Stejné otázky k operaci aktualizace.

Chcete-li určit, jak se chová omezení cizího klíče, kdykoli je nadřazený klíč odstraněn nebo aktualizován, použijte ON DELETE nebo ON UPDATE postupujte následovně:

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 podporuje následující akce:

  • NASTAVTE NULL
  • NASTAVIT VÝCHOZÍ
  • OMEZIT
  • ŽÁDNÁ AKCE
  • KASKÁDA

V praxi se hodnoty primárního klíče v nadřazené tabulce nemění, proto jsou pravidla aktualizace méně důležitá. Důležitější pravidlo je DELETE pravidlo, které určuje akci při odstranění nadřazeného klíče.

Každou akci prozkoumáme na následujícím příkladu

SET NULL

Když se nadřazený klíč změní, odstraní nebo aktualizuje, odpovídající podřízené klíče všech řádků v podřízené tabulce se nastaví na hodnotu NULL.

Nejprve vypusťte a vytvořte tabulku suppliers pomocí SET NULL akci pro group_id cizí klíč:

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)

Za druhé vložte několik řádků do suppliers tabulka:

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)

Za třetí, odstraňte ID skupiny dodavatelů 3 z supplier_groups tabulka:

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

Za čtvrté, dotazujte se na data od suppliers tabulka.

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

Hodnoty group_id sloupec odpovídajících řádků v suppliers tabulka nastavena na NULL.

NASTAVIT VÝCHOZÍ

SET DEFAULT action nastaví hodnotu cizího klíče na výchozí hodnotu zadanou v definici sloupce při vytváření tabulky.

Protože hodnoty ve sloupci group_id výchozí hodnota NULL, pokud odstraníte řádek ze skupiny supplier_groups tabulky, hodnoty group_id se nastaví na NULL.

Po přiřazení výchozí hodnoty se spustí omezení cizího klíče a provede kontrolu.

OMEZIT

RESTRICT akce vám neumožňuje měnit nebo mazat hodnoty v nadřazeném klíči nadřazené tabulky.

Nejprve stáhněte a vytvořte suppliers tabulka s RESTRICT akce v cizím klíči 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)

Za druhé vložte řádek do tabulky suppliers s group_id 1.

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

Za třetí, odstraňte skupinu dodavatelů s ID 1 z supplier_groups tabulka:

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

SQLite vydal následující chybu:

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

Chcete-li to opravit, musíte nejprve odstranit všechny řádky od suppliers tabulka, která má group_id 1:

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

Poté můžete odstranit skupinu dodavatelů 1 z supplier_groups tabulka:

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

ŽÁDNÁ AKCE

NO ACTION neznamená obejít omezení cizího klíče. Má podobný účinek jako RESTRICT .

KASKÁDA

CASCADE action přenese změny z nadřazené tabulky do podřízené tabulky, když aktualizujete nebo odstraníte nadřazený klíč.

Nejprve vložte suppliers seskupí do supplier_groups tabulka:

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

Za druhé, vypusťte a vytvořte tabulku suppliers pomocí CASCADE akce v cizím klíči 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)

Za třetí, vložte některé dodavatele do tabulky 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)

Za čtvrté, aktualizujte group_id z Domestic skupina dodavatelů na 100:

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

Za páté, dotazujte se na data z tabulky suppliers :

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

Jak můžete vidět hodnotu v group_id sloupec XYZ Corp v tabulce suppliers změněno z 1 na 100, když jsme aktualizovali group_id v supplier_groups stůl. Toto je výsledek ON UPDATE CASCADE akce.

Za šesté, odstraňte id skupiny dodavatelů 2 z supplier_groups tabulka:

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

Za sedmé, dotazujte se na data z tabulky suppliers :

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

ID dodavatele 2, jehož group_id is 2 bylo odstraněno, když bylo id skupiny dodavatelů 2 odstraněno z supplier_groups stůl. Toto je efekt ON DELETE CASCADE akce.

V tomto tutoriálu jste se dozvěděli o omezení cizího klíče SQLite a jak je použít k vynucení vztahu mezi souvisejícími tabulkami.


  1. Jak deklarovat proměnnou a používat ji ve stejném skriptu Oracle SQL?

  2. Porovnání dat v Oracle SQL

  3. OPENJSON „Nesprávná syntaxe poblíž klíčového slova ‚s‘.“ v SQL Server (VYŘEŠENO)

  4. Vytváření aktivačních událostí auditu na serveru SQL Server