Samenvatting :in deze zelfstudie leert u hoe u de SQLite-externe-sleutelbeperking kunt gebruiken om de relaties tussen gerelateerde tabellen af te dwingen.
SQLite-ondersteuning voor externe sleutelbeperkingen
SQLite ondersteunt sinds versie 3.6.19 de beperking van externe sleutels. De SQLite-bibliotheek moet ook worden gecompileerd met noch SQLITE_OMIT_FOREIGN_KEY noch SQLITE_OMIT_TRIGGER.
Om te controleren of uw huidige versie van SQLite externe-sleutelbeperkingen ondersteunt of niet, gebruikt u de volgende opdracht.
PRAGMA foreign_keys;
Code language: SQL (Structured Query Language) (sql)
De opdracht retourneert een geheel getal:1:inschakelen, 0:uitgeschakeld. Als de opdracht niets retourneert, betekent dit dat uw SQLite-versie geen beperkingen voor externe sleutels ondersteunt.
Als de SQLite-bibliotheek is gecompileerd met ondersteuning voor externe-sleutelbeperkingen, kan de toepassing de PRAGMA foreign_keys
gebruiken commando om beperkingen voor externe sleutels tijdens runtime in of uit te schakelen.
Beperking van externe sleutels uitschakelen:
PRAGMA foreign_keys = OFF;
Code language: SQL (Structured Query Language) (sql)
Beperking van externe sleutels inschakelen:
PRAGMA foreign_keys = ON;
Code language: SQL (Structured Query Language) (sql)
Inleiding tot de SQLite externe sleutelbeperkingen
Laten we beginnen met twee tabellen:suppliers
en 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)
Ervan uitgaande dat elke leverancier tot één en slechts één leveranciersgroep behoort. En elke leveranciersgroep kan nul of veel leveranciers hebben. De relatie tussen supplier_groups
en suppliers
tabellen is een-op-veel. Met andere woorden, voor elke rij in de suppliers
tabel, is er een overeenkomstige rij in de supplier_groups
tafel.
Momenteel is er geen manier om te voorkomen dat u een rij toevoegt aan de suppliers
tabel zonder een bijbehorende rij in de supplier_groups
tafel.
Daarnaast kunt u een rij verwijderen in de supplier_groups
tabel zonder de corresponderende rijen in de suppliers
. te verwijderen of bij te werken tafel. Dit kan verweesde rijen achterlaten in de suppliers
tafel.
Om de relatie tussen rijen in de suppliers
af te dwingen en supplier_groups
tabel, gebruik je de buitenlandse sleutelbeperkingen .
De beperking van de refererende sleutel toevoegen aan de suppliers
tabel, wijzigt u de definitie van de CREATE TABLE
verklaring hierboven als volgt:
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)
De supplier_groups
tabel heet een bovenliggende tabel , wat de tabel is waarnaar een refererende sleutel verwijst. De suppliers
tafel staat bekend als een kindertafel , de tabel waarop de beperking van de refererende sleutel van toepassing is.
De group_id
kolom in de supplier_groups
tabel heet de oudersleutel , wat een kolom of een reeks kolommen in de bovenliggende tabel is waarnaar de refererende-sleutelbeperking verwijst. Meestal is de bovenliggende sleutel de primaire sleutel van de bovenliggende tabel.
De group_id
kolom in de suppliers
tabel wordt de onderliggende sleutel genoemd. Over het algemeen verwijst de onderliggende sleutel naar de primaire sleutel van de bovenliggende tabel.
Voorbeeld van beperking van SQLite externe sleutel
Voeg eerst drie rijen toe aan de supplier_groups
tafel.
INSERT INTO supplier_groups (group_name)
VALUES
('Domestic'),
('Global'),
('One-Time');
Code language: SQL (Structured Query Language) (sql)
Ten tweede, voeg een nieuwe leverancier toe aan de suppliers
tabel met de leveranciersgroep die bestaat in de supplier_groups
tafel.
INSERT INTO suppliers (supplier_name, group_id)
VALUES ('HP', 2);
Code language: SQL (Structured Query Language) (sql)
Deze verklaring werkt prima.
Ten derde, probeer een nieuwe leverancier in te voegen in de suppliers
tabel met de leveranciersgroep die niet bestaat in de supplier_groups
tafel.
INSERT INTO suppliers (supplier_name, group_id)
VALUES('ABC Inc.', 4);
Code language: SQL (Structured Query Language) (sql)
SQLite controleerde de externe sleutelbeperking, verwierp de wijziging en gaf de volgende foutmelding:
[SQLITE_CONSTRAINT] Abort due to constraint violation (FOREIGN KEY constraint failed)
Code language: CSS (css)
SQLite-beperkingsacties voor externe sleutels
Wat zou er gebeuren als u een rij in de supplier_groups
. verwijdert? tafel? Moeten alle corresponderende rijen in de suppliers
tabel ook verwijderd? Dezelfde vragen voor de update-bewerking.
Om aan te geven hoe de externe-sleutelbeperking zich gedraagt wanneer de bovenliggende sleutel wordt verwijderd of bijgewerkt, gebruikt u de ON DELETE
of ON UPDATE
actie als volgt:
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 ondersteunt de volgende acties:
- STEL NULL IN
- STANDAARD INSTELLEN
- BEPERK
- GEEN ACTIE
- CASCADE
In de praktijk veranderen de waarden van de primaire sleutel in de bovenliggende tabel niet, daarom zijn de updateregels minder belangrijk. De belangrijkste regel is de DELETE
regel die de actie specificeert wanneer de bovenliggende sleutel wordt verwijderd.
We zullen elke actie onderzoeken aan de hand van het volgende voorbeeld
STEL NULL IN
Wanneer de bovenliggende sleutel wordt gewijzigd, verwijderd of bijgewerkt, worden de bijbehorende onderliggende sleutels van alle rijen in de onderliggende tabel ingesteld op NULL.
Plaats eerst de tabel suppliers
en maak deze aan met behulp van de SET NULL
actie voor de group_id
buitenlandse sleutel:
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)
Ten tweede, voeg enkele rijen toe aan de suppliers
tafel:
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)
Ten derde, verwijder de leveranciersgroep-ID 3 uit de supplier_groups
tafel:
DELETE FROM supplier_groups
WHERE group_id = 3;
Code language: SQL (Structured Query Language) (sql)
Ten vierde, gegevens opvragen bij de suppliers
tafel.
SELECT * FROM suppliers;
Code language: SQL (Structured Query Language) (sql)
De waarden van de group_id
kolom van de corresponderende rijen in de suppliers
tabel ingesteld op NULL.
STANDAARD INSTELLEN
De SET DEFAULT
action stelt de waarde van de refererende sleutel in op de standaardwaarde die is opgegeven in de kolomdefinitie wanneer u de tabel maakt.
Omdat de waarden in de kolom group_id
standaard ingesteld op NULL, als u een rij verwijdert uit de supplier_groups
tabel, de waarden van de group_id
wordt ingesteld op NULL.
Nadat de standaardwaarde is toegewezen, treedt de beperking van de refererende sleutel in werking en wordt de controle uitgevoerd.
BEPERK
De RESTRICT
actie staat u niet toe om waarden in de bovenliggende sleutel van de bovenliggende tabel te wijzigen of te verwijderen.
Verwijder en maak eerst de suppliers
tabel met de RESTRICT
actie in de refererende sleutel 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)
Ten tweede, plaats een rij in de tabel suppliers
met de group_id 1.
INSERT INTO suppliers (supplier_name, group_id)
VALUES('XYZ Corp', 1);
Code language: SQL (Structured Query Language) (sql)
Ten derde, verwijder de leveranciersgroep met id 1 uit de supplier_groups
tafel:
DELETE FROM supplier_groups
WHERE group_id = 1;
Code language: SQL (Structured Query Language) (sql)
SQLite gaf de volgende fout:
[SQLITE_CONSTRAINT] Abort due to constraint violation (FOREIGN KEY constraint failed)
Code language: CSS (css)
Om dit op te lossen, moet u eerst alle rijen verwijderen uit de suppliers
tabel met group_id
1:
DELETE FROM suppliers
WHERE group_id =1;
Code language: SQL (Structured Query Language) (sql)
Vervolgens kunt u de leveranciersgroep 1 verwijderen uit de supplier_groups
tafel:
DELETE FROM supplier_groups
WHERE group_id = 1;
Code language: SQL (Structured Query Language) (sql)
GEEN ACTIE
De NO ACTION
betekent niet dat de beperking van de externe sleutel wordt omzeild. Het heeft hetzelfde effect als de RESTRICT
.
CASCADE
De CASCADE
actie verspreidt de wijzigingen van de bovenliggende tabel naar de onderliggende tabel wanneer u de bovenliggende sleutel bijwerkt of verwijdert.
Voer eerst de supplier
in groepen in de supplier_groups
tafel:
INSERT INTO supplier_groups (group_name)
VALUES
('Domestic'),
('Global'),
('One-Time');
Code language: SQL (Structured Query Language) (sql)
Ten tweede, drop en maak de tabel suppliers
met de CASCADE
actie in de refererende sleutel 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)
Ten derde, voeg enkele leveranciers toe aan de tabel 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)
Ten vierde, update group_id
van de Domestic
leveranciersgroep tot 100:
UPDATE supplier_groups
SET group_id = 100
WHERE group_name = 'Domestic';
Code language: SQL (Structured Query Language) (sql)
Ten vijfde, gegevens opvragen uit de tabel suppliers
:
SELECT * FROM suppliers;
Code language: SQL (Structured Query Language) (sql)
Zoals je kunt zien in de group_id
kolom van de XYZ Corp
in de tabel suppliers
veranderd van 1 naar 100 toen we de group_id
. bijwerkten in de suplier_groups
tafel. Dit is het resultaat van ON UPDATE CASCADE
actie.
Ten zesde, verwijder leveranciersgroep-ID 2 uit de supplier_groups
tafel:
DELETE FROM supplier_groups
WHERE group_id = 2;
Code language: SQL (Structured Query Language) (sql)
Ten zevende, vraag gegevens op uit de tabel suppliers
:
SELECT * FROM suppliers;
Code language: SQL (Structured Query Language) (sql)
De leverancier-ID 2 waarvan group_id
is 2 werd verwijderd toen de leveranciersgroep-ID 2 werd verwijderd uit de supplier_groups
tafel. Dit is het effect van de ON DELETE CASCADE
actie.
In deze zelfstudie hebt u geleerd over SQLite-beperkingen voor externe sleutels en hoe u deze kunt gebruiken om de relatie tussen gerelateerde tabellen af te dwingen.