SQLite
 sql >> база данни >  >> RDS >> SQLite

Външен ключ на SQLite

Резюме :в този урок ще научите как да използвате ограничението на външния ключ на SQLite, за да наложите връзките между свързани таблици.

Поддръжка на ограничения на външния ключ на SQLite

SQLite поддържа ограничение на външния ключ от версия 3.6.19. Библиотеката SQLite също трябва да бъде компилирана нито с SQLITE_OMIT_FOREIGN_KEY, нито с SQLITE_OMIT_TRIGGER.

За да проверите дали текущата ви версия на SQLite поддържа ограничения на външния ключ или не, използвайте следната команда.

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

Командата връща цяло число:1:активиране, 0:деактивирано. Ако командата не връща нищо, това означава, че вашата версия на SQLite не поддържа ограничения за външни ключове.

Ако библиотеката на SQLite е компилирана с поддръжка за ограничаване на външния ключ, приложението може да използва PRAGMA foreign_keys команда за активиране или деактивиране на ограниченията на външния ключ по време на изпълнение.

За да деактивирате ограничаването на външния ключ:

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

За да активирате ограничение на външния ключ:

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

Въведение в ограниченията на външния ключ на SQLite

Нека започнем с две таблици:suppliers и 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)

Ако приемем, че всеки доставчик принадлежи към една и само една група доставчици. И всяка група доставчици може да има нула или много доставчици. Връзката между supplier_groups и suppliers таблици е едно към много. С други думи, за всеки ред в suppliers таблица, има съответен ред в supplier_groups таблица.

Понастоящем няма начин да ви попречим да добавите ред към suppliers таблица без съответен ред в supplier_groups таблица.

В допълнение, можете да премахнете ред в supplier_groups таблица без изтриване или актуализиране на съответните редове в suppliers маса. Това може да остави осиротели редове в suppliers таблица.

За да наложите връзката между редовете в suppliers и supplier_groups таблица, използвате ограниченията на външния ключ .

За да добавите ограничението на външния ключ към suppliers таблица, променяте дефиницията на CREATE TABLE изявление по-горе, както следва:

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 таблицата се наричародителска таблица , което е таблицата, която препраща външният ключ. suppliers таблицата е известна като детска маса , което е таблицата, към която се прилага ограничението за външния ключ.

group_id колона в supplier_groups таблицата се нарича родителски ключ , което е колона или набор от колони в родителската таблица, към която се позовава ограничението на външния ключ. Обикновено родителският ключ е първичният ключ на родителската таблица.

group_id колона в suppliers таблицата се нарича дъщерен ключ. Като цяло, дъщерният ключ се позовава на първичния ключ на родителската таблица.

Пример за ограничение на външния ключ в SQLite

Първо, поставете три реда в supplier_groups таблица.

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

Второ, поставете нов доставчик в suppliers таблица с групата на доставчиците, която съществува в supplier_groups таблица.

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

Това твърдение работи перфектно.

Трето, опитайте се да вмъкнете нов доставчик в suppliers таблица с групата на доставчиците, която не съществува в supplier_groups таблица.

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

SQLite провери ограничението на външния ключ, отхвърли промяната и издаде следното съобщение за грешка:

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

Действия за ограничаване на външния ключ на SQLite

Какво ще се случи, ако изтриете ред в supplier_groups маса? Трябва ли всички съответни редове в suppliers таблицата също се изтриват? Същите въпроси към операцията за актуализиране.

За да посочите как се държи ограничението на външния ключ всеки път, когато родителският ключ бъде изтрит или актуализиран, използвате ON DELETE или ON UPDATE действие, както следва:

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 поддържа следните действия:

  • ЗАДАВАНЕ НА NULL
  • ЗАДАВАНЕ ПО ПОДРАЗБИРАНЕ
  • ОГРАНИЧАВАНЕ
  • БЕЗ ДЕЙСТВИЕ
  • КАСКАДА

На практика стойностите на първичния ключ в родителската таблица не се променят, следователно правилата за актуализиране са по-малко важни. По-важното правило е DELETE правило, което определя действието при изтриване на родителския ключ.

Ще разгледаме всяко действие чрез следния пример

ЗАДАВАНЕ НА NULL

Когато родителският ключ се промени, изтрие или актуализира, съответните дъщерни ключове на всички редове в дъщерната таблица се задават на NULL.

Първо пуснете и създайте таблицата suppliers като използвате SET NULL действие за 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 SET NULL
       ON DELETE SET NULL
);
Code language: SQL (Structured Query Language) (sql)

Второ, поставете няколко реда в suppliers таблица:

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)

Трето, изтрийте идентификатора на групата на доставчиците 3 от supplier_groups таблица:

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

Четвърто, потърсете данни от suppliers таблица.

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

Стойностите на group_id колона на съответните редове в suppliers таблицата е зададена на NULL.

ЗАДАВАНЕ ПО ПОДРАЗБИРАНЕ

SET DEFAULT action задава стойността на външния ключ на стойността по подразбиране, посочена в дефиницията на колоната, когато създавате таблицата.

Тъй като стойностите в колоната group_id по подразбиране е NULL, ако изтриете ред от supplier_groups таблица, стойностите на group_id ще бъде зададено на NULL.

След присвояване на стойността по подразбиране, ограничението на външния ключ се включва и носи проверката.

ОГРАНИЧВАНЕ

RESTRICT действието не ви позволява да променяте или изтривате стойности в родителския ключ на родителската таблица.

Първо, пуснете и създайте suppliers таблица с RESTRICT действие във външния ключ 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)

Второ, поставете ред в таблицата suppliers с group_id 1.

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

Трето, изтрийте групата на доставчиците с идентификатор 1 от supplier_groups таблица:

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

SQLite издаде следната грешка:

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

За да го поправите, първо трябва да изтриете всички редове от suppliers таблица, която има group_id 1:

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

След това можете да изтриете групата на доставчиците 1 от supplier_groups таблица:

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

БЕЗ ДЕЙСТВИЕ

NO ACTION не означава заобикаляне на ограничението за външния ключ. Той има подобен ефект като RESTRICT .

КАСКАДА

CASCADE action разпространява промените от родителската таблица към дъщерната таблица, когато актуализирате или изтриете родителския ключ.

Първо поставете supplier групи в supplier_groups таблица:

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

Второ, пуснете и създайте таблицата suppliers с CASCADE действие във външния ключ 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)

Трето, вмъкнете някои доставчици в таблицата 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)

Четвърто, актуализирайте group_id на Domestic група доставчици до 100:

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

Пето, потърсете данни от таблицата suppliers :

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

Както можете да видите стойността в group_id колона на XYZ Corp в таблицата suppliers се промени от 1 на 100, когато актуализирахме group_id в supplier_groups маса. Това е резултатът от ON UPDATE CASCADE действие.

Шесто, изтрийте идентификатор на групата на доставчиците 2 от supplier_groups таблица:

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

Седмо, заявете данни от таблицата suppliers :

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

Идентификаторът на доставчика 2, чийто group_id е 2 беше изтрит, когато идентификаторът на групата на доставчиците 2 беше премахнат от supplier_groups маса. Това е ефектът от ON DELETE CASCADE действие.

В този урок научихте за ограниченията на външния ключ на SQLite и как да ги използвате, за да наложите връзката между свързани таблици.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да извлечете деня, месеца и годината от дата в SQLite

  2. sqlite върна:код на грешка =1, msg =няма такава колона:кухня1

  3. PowerManager.PARTIAL_WAKE_LOCK android

  4. Как работи ON CONFLICT в SQLite

  5. GROUP_CONCAT в SQLite