Як використовувати RESTRICT для зовнішнього ключа в mysql?


11

У структурі бази даних

  CREATE TABLE Country (
  name varchar(40) NOT NULL,
  PRIMARY KEY  (name)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE City (
  name varchar(40) NOT NULL,
  PRIMARY KEY  (name)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE Map (
  country varchar(40) NOT NULL,
  city varchar(100) NOT NULL,
  PRIMARY KEY  (country,city),
  FOREIGN KEY (country) REFERENCES Country (name) ON DELETE CASCADE,
  FOREIGN KEY (city) REFERENCES City (name) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Я очікую, щоб видалити родитель з City, залишивши відповідне значення у доторкнутому ці три рівні команди

  FOREIGN KEY (city) REFERENCES City (name) ON DELETE NO ACTION
  FOREIGN KEY (city) REFERENCES City (name) ON DELETE RESTRICT
  FOREIGN KEY (city) REFERENCES City (name)

Але при використанні NO ACTIONАБО RESTRICTабо пропущенні ON DELETE. MySQL не дозволяє мені видаляти з батьківського стовпця з цією помилкою:

ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails 
('test'.'Map', CONSTRAINT 'Map_ibfk_2' FOREIGN KEY ('city') REFERENCES 'City'('name')
 ON DELETE RESTRICT

Де я помиляюся? Чи не відповідальність SQL за NO ACTIONвидалення батьків та залишення дитини-сироти?

Відповіді:


13

Відповідно до документації MySQL про DELETE RESTRICT

• RESTRICT: Відхиляє операцію видалення або оновлення для батьківської таблиці. Вказівка ​​RESTRICT (або NO ACTION) така ж, як і упущення пункту ON DELETE або ON UPDATE.

Щодо НЕ ДІЇ

• NO ACTION: Ключове слово зі стандартного SQL. У MySQL, що еквівалентно RESTRICT. InnoDB відхиляє операцію видалення або оновлення для батьківської таблиці, якщо в посилається таблиці є відповідне значення зовнішнього ключа. Деякі системи баз даних мають відкладені чеки, а NO ACTION - відкладена перевірка. У MySQL обмеження зовнішніх ключів перевіряються негайно, так що НЕ ДІЯ є таким самим, як RESTRICT.

DELETE RESTRICT захищає батьків від видалення, а не дітей.


5

Якщо ви хочете видалити батька та залишити дитину, то, ймовірно, ви бажаєте цього ON DELETE SET NULLваріанта:

SET NULL: Видаліть або оновіть рядок з батьківської таблиці та встановіть стовпчик або стовпці з іноземним ключем у дочірній таблиці на NULL. Підтримуються як пункти ON DELETE SET NULL, так і ON UPDATE SET NULL.

Якщо ви вказали дію SET NULL, переконайтесь, що ви не оголосили стовпці в дочірній таблиці як NOT NULL.

У цьому останньому реченні багато "не", тому просто переконайтеся, що parent_id може бути NULL.

Дивіться також пов’язане питання: Яка мета SET NULL у обмеженнях видалення / оновлення зовнішніх ключів?

Визначивши іноземний ключ, ви сказали базі даних не приймати записи в дочірній таблиці, які не мають відповідного значення в батьківській.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.