Использование ON DELETE CASCADE без обновления внешнего ключа - PullRequest
0 голосов
/ 17 сентября 2018

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

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

Какой самый простой способ удалить данные из нескольких таблиц с отношением FK?

1 Ответ

0 голосов
/ 17 сентября 2018

Хотя on delete cascade является предпочтительным способом сделать это, вы также можете сделать это с помощью одного запроса delete, поскольку он поддерживает удаление из нескольких таблиц. Если вы можете правильно присоединиться к своим таблицам (что вы, как обычно, должны делать через связи с внешними ключами), вы можете сразу удалить из них:

Вы можете указать несколько таблиц в операторе DELETE для удаления строк из одной или нескольких таблиц в зависимости от условия в предложении WHERE. [...] удаляются только совпадающие строки из таблиц, перечисленных перед предложением FROM.

Так что вы можете использовать, например:

CREATE TABLE parent (
    id INT PRIMARY KEY
);
CREATE TABLE child (
    id INT PRIMARY KEY,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES parent (id)
);

INSERT INTO parent(id) VALUES (1), (2), (3);
INSERT INTO child(id, parent_id) VALUES (1,1), (2,1), (3,2), (4,2), (5,3), (6,3);

SET FOREIGN_KEY_CHECKS=0;

DELETE child, parent 
FROM child
JOIN parent ON child.parent_id = parent.id 
WHERE parent.id = 1;

SET FOREIGN_KEY_CHECKS=1;

У вас очень мало контроля над порядком удаления, и почти во всех случаях MySQL предпочитает порядок выполнения, который нарушает ограничения внешнего ключа (поскольку это, вероятно, единственный жизнеспособный способ объединения ваших таблиц), поэтому для этого для работы вам нужно временно отключить FOREIGN_KEY_CHECKS ; см. также замечание в руководстве :

Если вы используете оператор DELETE для нескольких таблиц, включающий таблицы InnoDB, для которых существуют ограничения внешнего ключа, оптимизатор MySQL может обрабатывать таблицы в порядке, отличном от порядка их родительских / дочерних отношений. В этом случае утверждение не выполняется и выполняется откат. Вместо этого вы должны удалить из одной таблицы и полагаться на возможности ON DELETE, которые предоставляет InnoDB, чтобы другие таблицы были изменены соответствующим образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...