Зачем использовать внешние ключи без каких-либо действий при удалении или обновлении

У меня интересующий вопрос:

У меня есть 2 таблицы в mysql с _1 _.
таблица tbl_a имеет первичный ключ с именем a_id;
таблица tbl_b имеет первичный b_id и внешний ключ на tbl_a.a_id с "ON DELETE NO ACTION".

+-------------+---------------+---------------+
|  Table Name |  Primary Key  |  Foreign Key  |
+-------------+---------------+---------------+
|    tbl_a    |     a_id      |               |
|    tbl_b    |     b_id      |     a_id      |
+-------------+---------------+---------------+

почему я все еще должен использовать InnoDb и внешние ключи, если я действительно не использую магию внешних ключей в конце концов?
Есть ли еще смысл использовать
innodb и внешние ключи
вместо
< em> myisam и без внешних ключей .
Если я просто сделаю «NO ACTION» при удалении или обновлении?

Надеюсь, вы уловили мою точку зрения :)


person Preexo    schedule 23.08.2012    source источник
comment
Разве это не гарантирует, что внешние ключи соответствуют фактическим действительным строкам?   -  person Waleed Khan    schedule 23.08.2012
comment
Если вы удалите внешнюю строку, ваши данные будут неполными, и у вас будет большой беспорядок в БД.   -  person Peter    schedule 23.08.2012
comment
сводка выглядит так, ON DELETE NO ACTION остановит недопустимые удаления / обновления, поэтому неплохо иметь   -  person Manohar Reddy Poreddy    schedule 28.04.2021


Ответы (2)


Я думаю, вы неправильно понимаете, что означает ON DELETE NO ACTION. Это не означает подавление ограничения внешнего ключа.

Когда вы удаляете запись, на которую ссылается внешний ключ, InnoDB имеет возможность предпринять автоматические действия для исправления ситуации:

  • он может CASCADE, то есть удалить ссылающуюся запись. (Это имеет смысл для чего-то вроде user_address.user_id. Если вы жестко удалите пользователя, вы, вероятно, захотите жестко удалить и все его адреса.)
  • он может SET NULL, что означает очистить ссылающийся ключ. (Это может иметь смысл для чего-то вроде file.last_modified_by. Если вы жестко удалите пользователя, вы можете захотеть, чтобы последний измененный файл стал просто «неизвестным».)

Если вы укажете NO ACTION, вы сообщаете InnoDB, что не хотите, чтобы он выполнял любое из этих действий. Итак, InnoDB не может исправить ситуацию за вас; все, что он может сделать, - это отклонить DELETE и вернуть ошибку.

В результате ON DELETE NO ACTION фактически совпадает с ON DELETE RESTRICT (по умолчанию).

(Примечание: в некоторых СУБД и в стандартном SQL ON DELETE NO ACTION немного отличается от ON DELETE RESTRICT: в них ON DELETE NO ACTION означает «принять DELETE в текущей транзакции, но отклонить всю транзакцию, если я попытаюсь зафиксировать ее до устранения проблемы» . Но InnoDB не поддерживает отложенные проверки, поэтому обрабатывает ON DELETE NO ACTION точно так же, как ON DELETE RESTRICT, и всегда отклоняет DELETE немедленно.)

См. 14.2.2.5 «Ограничения FOREIGN KEY» и 13.1.17.2 "Использование ограничений FOREIGN KEY " в Справочном руководстве MySQL 5.6.

person ruakh    schedule 23.08.2012
comment
оххх хорошо, спасибо тебе большое ... ну тогда я действительно неправильно понял БЕЗ ДЕЙСТВИЙ - person Preexo; 23.08.2012
comment
но почему phpmyadmin предлагает и БЕЗ ДЕЙСТВИЙ, и ОГРАНИЧЕНИЕ? они тоже это неправильно понимают? - person Preexo; 23.08.2012
comment
@ user1011116: MySQL поддерживает обе нотации, поэтому я полагаю, что phpmyadmin считает, что должен предлагать и их обе? И я мог бы представить, как механизм хранения обрабатывает их по-другому - некоторые СУБД обрабатывают их немного по-другому (как указано в документации, на которую я ссылаюсь) - так что, возможно, phpmyadmin считает, что более перспективным является предоставление пользователям возможности выбора. - person ruakh; 23.08.2012
comment
Я согласен с вопросом, задавшим вопрос, здесь. НЕТ ДЕЙСТВИЯ не означает то же самое, что ДЕЙСТВИЕ ПО УМОЛЧАНИЮ. Мне кажется, что NO ACTION указывает на то, что ничего не делать, что также было бы бессмысленным. - person ryvantage; 17.04.2014
comment
@ryvantage: я не уверен, какова цель вашего комментария - я не MySQL, поэтому нет смысла спорить со мной о том, что он должен означать - но позвольте я все равно пытаюсь решить эту проблему. . . Дело не в том, что ОТСУТСТВИЕ ДЕЙСТВИЯ означает ДЕЙСТВИЕ ПО УМОЛЧАНИЮ; скорее дело в том, что нет действия по умолчанию. Когда вы удаляете строку способом, который нарушает ограничение, вы можете указать действие, которое MySQL предпримет для исправления ситуации; но если вы этого не сделаете, он не будет предпринимать никаких действий, поэтому оператор продолжает нарушать ограничение. Итак, он отклонен. - person ruakh; 18.04.2014
comment
@ruakh, это меня еще больше запутало. В вашем исходном ответе было сказано It means the same as ON DELETE RESTRICT (the default). Но теперь вы говорите, что это не означает выполнение действия по умолчанию ?? Я смущен. И да, любая враждебность, которую вы можете почувствовать по отношению к вам, действительно была непреднамеренной. Я даже понял, что комментарий был написан не очень хорошо, когда я впервые его написал, и попытался отредактировать его соответствующим образом. Видимо я потерпел неудачу. Прости. - person ryvantage; 18.04.2014
comment
@ryvantage: нет действия по умолчанию: по умолчанию он не выполняет никаких действий, позволяя произойти ошибке (из-за нарушения ограничения). Если вы хотите явно указать, что не должно быть никаких действий и, следовательно, ошибки, вы можете написать ON DELETE RESTRICT или ON DELETE NO ACTION, но оба они эквивалентны поведению по умолчанию, которое не предпринимает никаких действий, позволяя ошибке произойти. Если вы все еще не видите этого, то я не уверен, что смогу прояснить это. . . - person ruakh; 18.04.2014
comment
Спасибо. Я нахожу это имя довольно запутанным. IIUC, NO ACTION означает, что система ДЕЙСТВИТЕЛЬНО реагирует на уведомление о том, что ограничение внешнего ключа будет нарушено текущим оператором мутации (т.е. обновлением или удалением): реакция заключается в возврате к состоянию, которое существовало до (в процессе) мутации. вводится в действие. Кроме того, IIUC, NO ACTION делает то, что большинство людей сочтут наиболее разумным, что, в частности, имеет смысл, поскольку NO ACTION подразумевается при отсутствии явно заданного действия. - person allyourcode; 15.02.2015
comment
@allyourcode Если вы не хотите никаких действий в этом смысле, зачем вообще определять ограничение? - person tobiv; 11.01.2018
comment
@tobiv: я не думаю, что allyourcode предполагает, что СУБД должна предлагать необязательные ограничения в качестве функции БД; скорее, он говорит, что ON DELETE NO ACTION - плохое название для того, что он делает. - person ruakh; 12.01.2018

Ограничение внешнего ключа даже без ON DELETE / UPDATE CASCADE гарантирует, что если вы вставите значение в дочернюю таблицу, оно будет иметь правильно совпадающее значение в родительской таблице (или будет NULL, если столбец FK допускает значение NULL). Попытка вставить недопустимое значение в столбец FK дочерней таблицы приведет к ошибке при сбое ограничения, поэтому целостность ваших данных будет защищена.

ОШИБКА 1452 (23000): невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа не выполнено.

Определение ограничения внешнего ключа также неявно определяет индекс в столбце FK в дочерней таблице, что, хотя вы могли бы определить индекс вручную, улучшит производительность соединения.

ON DELETE NO ACTION (то же самое, что и исключение предложения ON DELETE) будет активно предотвращать удаление родительской строки, если на нее ссылается какая-либо дочерняя таблица, а не пассивно разрешать ее удаление, не затрагивая дочерние строки.

person Michael Berkowski    schedule 23.08.2012