У меня есть две таблицы в MySQL database- parent
, child
. Я пытаюсь добавить ссылки на внешние ключи в мою дочернюю таблицу на основе родительской таблицы. Есть ли существенная разница между ON UPDATE CASCADE
иON DELETE CASCADE
Мой родительский стол
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
Мой вопрос: в чем разница между следующими SQL-запросами.
ON DELETE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ) ENGINE=INNODB;
ON UPDATE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE ) ENGINE=INNODB;
ON UPDATE CASCADE ON DELETE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=INNODB;
Есть ли ошибки в запросах? Что означают эти запросы (1,2 и 3) ?? Они такие же ???
mysql
innodb
mysql-5.5
foreign-key
Одинокий волк
источник
источник
Ответы:
Очень хорошая тема на эту тему можно найти здесь, а также здесь . Полное руководство по MySQL - это, конечно, документация, которую можно найти здесь .
В стандарте SQL 2003 есть 5 различных ссылочных действий:
Чтобы ответить на вопрос:
CASCADE
ON DELETE CASCADE
означает, что если родительская запись удалена, любые дочерние записи также будут удалены. На мой взгляд, это не очень хорошая идея. Вы должны отслеживать все данные, которые когда-либо были в базе данных, хотя это можно сделать с помощьюTRIGGER
s. (Тем не менее, см. Предостережение в комментариях ниже).ON UPDATE CASCADE
означает, что при изменении родительского первичного ключа значение потомка также изменится, чтобы отразить это. Опять же, на мой взгляд, не очень хорошая идея. Если вы меняетеPRIMARY KEY
s с какой-либо регулярностью (или даже вообще!), Значит, что-то не так с вашим дизайном. Снова смотрите комментарии.ON UPDATE CASCADE ON DELETE CASCADE
означает, что если выUPDATE
ИЛИDELETE
родитель, изменения каскадно относятся к ребенку. Это эквивалентноAND
результатам первых двух утверждений.RESTRICT
RESTRICT
означает, что любая попытка удалить и / или обновить родителя приведет к ошибке. Это поведение по умолчанию в том случае, если ссылочное действие не указано явно.БЕЗДЕЙСТВИЕ
NO ACTION
: С ручной . Ключевое слово из стандартного SQL. В MySQL эквивалентноRESTRICT
. MySQL Server отклоняет операцию удаления или обновления для родительской таблицы, если в ссылочной таблице есть соответствующее значение внешнего ключа. Некоторые системы баз данных имеют отложенные проверки иNO ACTION
являются отложенными проверками. В MySQL ограничения внешнего ключа проверяются немедленно, такNO ACTION
же, как иRESTRICT
.SET NULL
SET NULL
- опять из руководства. Удалите или обновите строку из родительской таблицы и установите для столбца или столбца внешнего ключа в дочерней таблице значениеNULL
. ИМХО, это не лучшая идея, в первую очередь потому, что нет способа «путешествовать во времени», то есть заглянуть в дочерние таблицы и связать записи сNULL
s с соответствующей родительской записью, либоCASCADE
использоватьTRIGGER
s для заполнения таблиц журналов для отслеживания. изменения (но см. комментарии).УСТАНОВИТЬ ПО УМОЛЧАНИЮ
SET DEFAULT
, Еще одна (потенциально очень полезная) часть стандарта SQL, которую MySQL не потрудился реализовать! Позволяет разработчику указать значение, для которого необходимо установить столбцы внешнего ключа в UPDATE или DELETE. InnoDB и NDB отклонят определения таблиц сSET DEFAULT
предложением.Как уже упоминалось выше, вы должны потратить некоторое время на просмотр документации здесь .
источник
Эти два действия выполняются соответственно, когда ссылка на запись в родительской таблице меняет свой идентификатор и когда она удаляется.
Если вы выполните:
И есть по крайней мере одна запись
child
сparent_id = 1
1) потерпит неудачу; в случаях 2) и 3) все записи с parent_id = 1 обновляются до parent_id = -1.Если вы выполните:
И есть по крайней мере одна запись
child
сparent_id = 1
, 2) потерпит неудачу; в случаях 1) и 3) все записи сparent_id = 1
удаляются.3) синтаксически правильно.
Полную документацию можно найти в руководстве .
источник
У меня недостаточно репутации, чтобы комментировать предыдущие ответы. Поэтому я подумал, что немного уточню.
1) ON DELETE CASCADE означает, что если родительская запись удалена, то все ссылки на дочерние записи также удаляются. ON UPDATE по умолчанию - RESTRICT, что означает, что UPDATE родительской записи завершится ошибкой.
2) Действие ON DELETE по умолчанию равно RESTRICT, что означает, что DELETE для родительской записи завершится ошибкой. ON UPDATE CASCADE обновит все ссылающиеся дочерние записи при обновлении родительской записи.
3) См. Действия КАСКАДА в 1) и 2) выше.
Об использовании идентификаторов родительских записей в качестве внешних ключей (в дочерних таблицах) - опыт подсказывает: а) если идентификаторы являются автоматически генерируемыми порядковыми номерами, то НЕ используйте их в качестве внешних ключей. Вместо этого используйте другой уникальный родительский ключ. б) если идентификаторы являются GUID, то их можно использовать в качестве внешних ключей. Вы увидите мудрость этого предложения при экспорте и импорте записей или копировании записей в другую базу данных. Слишком сложно работать с автоматически генерируемыми порядковыми номерами во время переноса данных, когда на них ссылаются как на внешние ключи.
источник