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.