sql >> Databasteknik >  >> RDS >> SQLite

SQLite främmande nyckel

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.


  1. Automatisk ökning för Oracle

  2. Få rad-ID för en SQLite FTS3-tabell

  3. Kontrollera om ett objekt inte finns i en annan tabell

  4. Procedur för att exportera tabell till flera csv-filer