Подтвердить что ты не робот

MySQL при удалении каскада. Пример испытания

Мне интересно об этом тестовом вопросе. Я сам подготовил этот пример и протестировал его, но я все еще чувствую неуверенность в ответе.

Со следующим:

CREATE TABLE foo (
  id INT PRIMARY KEY AUTO_INCREMENT, 
  name INT
)

CREATE TABLE foo2 (
  id INT PRIMARY KEY AUTO_INCREMENT, 
  foo_id INT REFERENCES foo(id) ON DELETE CASCADE
)

Насколько я вижу, ответ:

а. Созданы две таблицы

Хотя есть также:

б. Если строка в таблице foo2 с foo_id из 2 удалена, то строка с id = 2 в таблице foo автоматически удаляется

d. Если строка с id = 2 в таблице foo удалена, все строки с foo_id = 2 в таблице foo2 удаляются

В моем примере я бы использовал синтаксис delete:

DELETE FROM foo WHERE id = 2;
DELETE FROM foo2 WHERE foo_id = 2;

По какой-то причине мне не удалось найти какую-либо связь между таблицами, хотя кажется, что она должна быть такой. Может быть, есть какой-то параметр MySQL или, возможно, ON DELETE CASCADE не используется должным образом в запросах создания таблицы? Мне осталось интересно...

4b9b3361

Ответ 1

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

Если таблицы создаются с помощью Engine=MyISAM, то ни b. или d. правильно.

Если таблицы создаются с помощью Engine=InnoDB, то d. является правильным.

Примечание:

Это верно для InnoDB тогда и только тогда, когда FOREIGN_KEY_CHECKS = 1; если FOREIGN_KEY_CHECKS = 0, то a DELETE из родительской таблицы (foo) не удалит строки из дочерней таблицы (foo2), которые ссылаются на строку, удаленную из родительской таблицы.

Проверьте это с помощью выхода SHOW VARIABLES LIKE 'foreign_key_checks' (1 = ВКЛ, 0 = ВЫКЛ) (Нормальное значение по умолчанию - для этого.)

Выход из SHOW CREATE TABLE foo покажет, какой движок использует таблица.

На выходе из SHOW VARIABLES LIKE 'storage_engine' будет отображаться двигатель по умолчанию, используемый при создании таблицы, и двигатель не указан.

Ответ 2

У вас есть связь между двумя таблицами, это в команде создания foo2: ... foo_id int references foo(id) on delete cascade.

В соответствии с ссылкой на внешние ограничения MySQL MySQL:

CASCADE: удалить или обновить строку из родительской таблицы и автоматически удалить или обновить соответствующие строки в дочерней таблице. Поддерживаются как ON DELETE CASCADE, так и ON UPDATE CASCADE.

Кроме того, в соответствии с ссылкой на внешние ключи MySQL:

Для систем хранения, отличных от InnoDB, при определении столбца можно использовать предложение LINK tbl_name (col_name), которое не имеет фактического эффекта и служит только как памятка или комментарий к вам, что столбец, который вы сейчас используете определение предназначено для ссылки на столбец в другой таблице.

Так как внешний ключ находится из дочерней таблицы в родительскую таблицу, она делает foo родительскую таблицу и foo2 дочернюю таблицу, поэтому удаление строки из foo приведет к каскадной удалению в foo2, при условии, что вы используете InnoDB или какой-либо другой механизм хранения, который его поддерживает.