Sammanfattning :i den här handledningen kommer du att lära dig hur du använder SQLites främmande nyckelbegränsning för att upprätthålla relationerna mellan relaterade tabeller.
SQLite-stöd för främmande nyckelbegränsningar
SQLite har stöd för begränsning av främmande nyckel sedan version 3.6.19. SQLite-biblioteket måste också kompileras med varken SQLITE_OMIT_FOREIGN_KEY eller SQLITE_OMIT_TRIGGER.
För att kontrollera om din nuvarande version av SQLite stöder främmande nyckelbegränsningar eller inte, använder du följande kommando.
PRAGMA foreign_keys;
Code language: SQL (Structured Query Language) (sql)
Kommandot returnerar ett heltalsvärde:1:aktivera, 0:avaktiverad. Om kommandot inte returnerar något betyder det att din SQLite-version inte stöder begränsningar för främmande nyckel.
Om SQLite-biblioteket är kompilerat med stöd för främmande nycklar, kan applikationen använda PRAGMA foreign_keys
kommando för att aktivera eller inaktivera begränsningar för främmande nyckel vid körning.
Så här inaktiverar du begränsning av främmande nyckel:
PRAGMA foreign_keys = OFF;
Code language: SQL (Structured Query Language) (sql)
Så här aktiverar du begränsning av främmande nyckel:
PRAGMA foreign_keys = ON;
Code language: SQL (Structured Query Language) (sql)
Introduktion till SQLites främmande nyckelbegränsningar
Låt oss börja med två tabeller:suppliers
och 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)
Förutsatt att varje leverantör tillhör en och endast en leverantörsgrupp. Och varje leverantörsgrupp kan ha noll eller många leverantörer. Relationen mellan supplier_groups
och suppliers
tabeller är en-till-många. Med andra ord, för varje rad i suppliers
tabell, finns det en motsvarande rad i supplier_groups
bord.
För närvarande finns det inget sätt att hindra dig från att lägga till en rad till suppliers
tabell utan en motsvarande rad i supplier_groups
bord.
Dessutom kan du ta bort en rad i supplier_groups
utan att radera eller uppdatera motsvarande rader i suppliers
tabell. Detta kan lämna föräldralösa rader i suppliers
bord.
För att upprätthålla förhållandet mellan rader i suppliers
och supplier_groups
tabell använder du restriktioner för främmande nyckel .
För att lägga till den främmande nyckeln till suppliers
tabell, ändrar du definitionen av CREATE TABLE
uttalande ovan enligt följande:
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
Tabell kallas en överordnad tabell , vilket är tabellen som en främmande nyckel refererar till. suppliers
Tabell är känd som en underordnad tabell , vilket är tabellen som den främmande nyckeln gäller.
group_id
kolumnen i supplier_groups
tabellen kallas överordnad nyckel , som är en kolumn eller en uppsättning kolumner i den överordnade tabellen som den främmande nyckelbegränsningen refererar till. Vanligtvis är den överordnade nyckeln den primära nyckeln i den överordnade tabellen.
group_id
kolumnen i suppliers
tabellen kallas barnnyckeln. I allmänhet refererar den underordnade nyckeln till den primära nyckeln i den överordnade tabellen.
Exempel på SQLite främmande nyckelbegränsning
Först infogar du tre rader i supplier_groups
bord.
INSERT INTO supplier_groups (group_name)
VALUES
('Domestic'),
('Global'),
('One-Time');
Code language: SQL (Structured Query Language) (sql)
För det andra, infoga en ny leverantör i suppliers
tabell med leverantörsgruppen som finns i supplier_groups
bord.
INSERT INTO suppliers (supplier_name, group_id)
VALUES ('HP', 2);
Code language: SQL (Structured Query Language) (sql)
Detta uttalande fungerar alldeles utmärkt.
För det tredje, försök att infoga en ny leverantör i suppliers
tabell med leverantörsgruppen som inte finns i supplier_groups
bord.
INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Inc.', 4);
Code language: SQL (Structured Query Language) (sql)
SQLite kontrollerade den främmande nyckeln, avvisade ändringen och utfärdade följande felmeddelande:
[SQLITE_CONSTRAINT] Abort due to constraint violation (FOREIGN KEY constraint failed)
Code language: CSS (css)
SQLite främmande nyckelbegränsningsåtgärder
Vad skulle hända om du tar bort en rad i supplier_groups
tabell? Bör alla motsvarande rader i suppliers
tabell raderas också? Samma frågor till uppdateringsoperationen.
För att ange hur begränsningen för främmande nyckel beter sig när den överordnade nyckeln tas bort eller uppdateras, använder du ON DELETE
eller ON UPDATE
åtgärd enligt följande:
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 stöder följande åtgärder:
- STÄLL IN NULL
- STÄLL IN STANDARD
- BEGRÄNS
- INGEN ÅTGÄRD
- CASCADE
I praktiken ändras inte värdena för primärnyckeln i den överordnade tabellen, därför är uppdateringsreglerna mindre viktiga. Den viktigaste regeln är DELETE
regel som anger åtgärden när den överordnade nyckeln tas bort.
Vi undersöker varje åtgärd med följande exempel
STÄLL IN NULL
När den överordnade nyckeln ändras, raderas eller uppdateras, ställs motsvarande underordnade nycklar på alla rader i den underordnade tabellen in på NULL.
Släpp först och skapa tabellen suppliers
med SET NULL
åtgärd för group_id
främmande nyckel:
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)
För det andra, infoga några rader i suppliers
tabell:
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)
För det tredje, ta bort leverantörsgrupp-id 3 från supplier_groups
tabell:
DELETE FROM supplier_groups
WHERE group_id = 3;
Code language: SQL (Structured Query Language) (sql)
För det fjärde, fråga efter data från suppliers
bord.
SELECT * FROM suppliers;
Code language: SQL (Structured Query Language) (sql)
Värdena för group_id
kolumnen för motsvarande rader i suppliers
tabellen satt till NULL.
STÄLL IN STANDARD
SET DEFAULT
action ställer in värdet på den främmande nyckeln till standardvärdet som anges i kolumndefinitionen när du skapar tabellen.
Eftersom värdena i kolumnen group_id
standard till NULL, om du tar bort en rad från supplier_groups
tabell, värdena för group_id
ställs in på NULL.
Efter att ha tilldelat standardvärdet, startar den främmande nyckelbegränsningen och utför kontrollen.
BEGRÄNS
RESTRICT
action tillåter dig inte att ändra eller ta bort värden i den överordnade nyckeln för den överordnade tabellen.
Släpp först och skapa suppliers
tabell med RESTRICT
åtgärd i den främmande nyckeln 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)
För det andra, infoga en rad i tabellen suppliers
med group_id 1.
INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 1);
Code language: SQL (Structured Query Language) (sql)
För det tredje, ta bort leverantörsgruppen med id 1 från supplier_groups
tabell:
DELETE FROM supplier_groups
WHERE group_id = 1;
Code language: SQL (Structured Query Language) (sql)
SQLite utfärdade följande fel:
[SQLITE_CONSTRAINT] Abort due to constraint violation (FOREIGN KEY constraint failed)
Code language: CSS (css)
För att fixa det måste du först ta bort alla rader från suppliers
tabell som har group_id
1:
DELETE FROM suppliers
WHERE group_id =1;
Code language: SQL (Structured Query Language) (sql)
Sedan kan du ta bort leverantörsgrupp 1 från supplier_groups
tabell:
DELETE FROM supplier_groups
WHERE group_id = 1;
Code language: SQL (Structured Query Language) (sql)
INGEN ÅTGÄRD
NO ACTION
betyder inte att förbigå begränsningen för främmande nyckel. Den har liknande effekt som RESTRICT
.
CASCADE
CASCADE
action överför ändringarna från den överordnade tabellen till den underordnade tabellen när du uppdaterar eller tar bort den överordnade nyckeln.
Sätt först in supplier
grupper i supplier_groups
tabell:
INSERT INTO supplier_groups (group_name)
VALUES
('Domestic'),
('Global'),
('One-Time');
Code language: SQL (Structured Query Language) (sql)
För det andra, släpp och skapa tabellen suppliers
med CASCADE
åtgärd i den främmande nyckeln 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)
För det tredje, infoga några leverantörer i tabellen 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)
För det fjärde, uppdatera group_id
av Domestic
leverantörsgrupp till 100:
UPDATE supplier_groups
SET group_id = 100
WHERE group_name = 'Domestic';
Code language: SQL (Structured Query Language) (sql)
För det femte, fråga data från tabellen suppliers
:
SELECT * FROM suppliers;
Code language: SQL (Structured Query Language) (sql)
Som du kan se värdet i group_id
kolumnen i XYZ Corp
i tabellen suppliers
ändrades från 1 till 100 när vi uppdaterade group_id
i supplier_groups
tabell. Detta är resultatet av ON UPDATE CASCADE
åtgärd.
För det sjätte, ta bort leverantörsgrupp-id 2 från supplier_groups
tabell:
DELETE FROM supplier_groups
WHERE group_id = 2;
Code language: SQL (Structured Query Language) (sql)
För det sjunde, fråga data från tabellen suppliers
:
SELECT * FROM suppliers;
Code language: SQL (Structured Query Language) (sql)
Leverantörs-id 2 vars group_id
is 2 togs bort när leverantörsgrupp-id 2 togs bort från supplier_groups
tabell. Detta är effekten av ON DELETE CASCADE
åtgärd.
I den här handledningen har du lärt dig om SQLite främmande nyckelbegränsningar och hur du använder dem för att upprätthålla relationen mellan relaterade tabeller.