Когда использовать "ON UPDATE CASCADE"
Я использую "ON DELETE CASCADE" регулярно, но я никогда не использую "ON UPDATE CASCADE", поскольку я не уверен, в какой ситуации это будет полезно.
Для обсуждения рассмотрим некоторый код.
CREATE TABLE parent (
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
);
CREATE TABLE child (
id INT NOT NULL AUTO_INCREMENT, parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id)
REFERENCES parent(id)
ON DELETE CASCADE
);
Для "ВКЛ. УДАЛИТЬ КАСКАД", если родитель с id
удален, запись в дочернем элементе с parent_id = parent.id
будет автоматически удалена. Это не должно быть проблемой.
-
Это означает, что "ON UPDATE CASCADE" будет делать то же самое, когда обновляется id
родителя?
-
Если (1) истинно, это означает, что нет необходимости использовать "ON UPDATE CASCADE", если parent.id
не обновляется (или никогда не обновляется), например, когда он равен AUTO_INCREMENT
или всегда значение TIMESTAMP
. Это правильно?
-
Если (2) неверно, в какой другой ситуации мы должны использовать "ON UPDATE CASCADE"?
-
Что делать, если я (по какой-то причине) обновляю child.parent_id
, чтобы быть чем-то не существующим, будет ли он автоматически удален?
Ну, я знаю, некоторые из вышеперечисленных вопросов могут быть программно понятны, но я хочу также знать, зависит ли какой-либо из этих поставщиков базы данных или нет.
Просветите свет.
Ответы
Ответ 1
Верно, что если ваш первичный ключ - это просто значение, автоматически увеличиваемое, вы бы не использовали его для ON UPDATE CASCADE.
Однако скажем, что ваш первичный ключ - это 10-значный штрих-код UPC, и из-за расширения вам нужно изменить его на 13-значный штрих-код UPC. В этом случае ON UPDATE CASCADE позволит вам изменить значение первичного ключа, и любые таблицы, которые имеют ссылки на внешние ключи к значению, будут соответствующим образом изменены.
В отношении # 4, если вы измените дочерний ID на то, что не существует в родительской таблице (и у вас есть ссылочная целостность), вы должны получить ошибку внешнего ключа.
Ответ 2
-
Да, это означает, что, например, если вы делаете UPDATE parent SET id = 20 WHERE id = 10
, все дети parent_id из 10 также будут обновлены до 20
-
Если вы не обновляете поле, на которое ссылается внешний ключ, этот параметр не нужен
-
Нельзя думать о другом использовании.
-
Вы не можете сделать это, поскольку ограничение внешнего ключа завершится с ошибкой.
Ответ 3
Я думаю, что вы довольно много прикрепили точки!
Если вы будете следовать рекомендациям по дизайну базы данных, и ваш первичный ключ никогда не будет обновляться (что, я думаю, всегда должно быть так или иначе), тогда вам действительно не нужно предложение ON UPDATE CASCADE
.
Zed сделал хороший вывод, что если вы используете в качестве основного ключа натуральный (например, регулярное поле из таблицы базы данных), то может быть определен ситуации, когда вам нужно обновить основные ключи. Еще один недавний пример - это ISBN (Международные стандартные номера книг), который не так давно изменился с 10 до 13 цифр + символов.
Это не тот случай, если вы решите использовать суррогатный (например, искусственно сгенерированный системой) ключ в качестве основного ключа (который был бы моим предпочтительным выбором во всех, кроме самых редких случаев).
Итак, в конце: если ваш первичный ключ никогда не изменяется, вам никогда не понадобится предложение ON UPDATE CASCADE
.
Марк
Ответ 4
Несколько дней назад у меня была проблема с триггерами, и я понял, что ON UPDATE CASCADE
может быть полезен. Взгляните на этот пример (PostgreSQL):
CREATE TABLE club
(
key SERIAL PRIMARY KEY,
name TEXT UNIQUE
);
CREATE TABLE band
(
key SERIAL PRIMARY KEY,
name TEXT UNIQUE
);
CREATE TABLE concert
(
key SERIAL PRIMARY KEY,
club_name TEXT REFERENCES club(name) ON UPDATE CASCADE,
band_name TEXT REFERENCES band(name) ON UPDATE CASCADE,
concert_date DATE
);
В моей проблеме мне пришлось определить некоторые дополнительные операции (триггер) для обновления таблицы концертов. Эти операции должны были изменить имя_группы и имя_группы. Из-за ссылки я не смог этого сделать. Я не мог изменить концерт, а затем заниматься клубными и групповыми столами. Я тоже не мог сделать это по-другому. ON UPDATE CASCADE
был ключом к решению проблемы.
Ответ 5
Мой комментарий в основном относится к пункту № 3: при каких обстоятельствах ON UPDATE CASCADE применим, если мы предполагаем, что родительский ключ не является обновляемым? Вот один случай.
Я имею дело с сценарием репликации, в котором несколько спутниковых баз данных необходимо объединить с мастером. Каждый спутник генерирует данные в одних и тех же таблицах, поэтому слияние таблиц с мастером приводит к нарушениям ограничений уникальности. Я пытаюсь использовать ON UPDATE CASCADE как часть решения, в котором я повторно увеличиваю ключи во время каждого слияния. ON UPDATE CASCADE должен упростить этот процесс, автоматизируя часть процесса.
Ответ 6
Это отличный вопрос, вчера у меня был тот же вопрос. Я подумал об этой проблеме, в частности, ПОИСКОМ, если существует нечто вроде "ON UPDATE CASCADE", и, к счастью, разработчики SQL также подумали об этом. Я согласен с Ted.strauss, и я также прокомментировал дело Норана.
Когда я его использовал? Как указывал Тед, когда вы обрабатываете несколько баз данных за один раз, а модификация в одном из них в одной таблице имеет какое-либо воспроизведение в том, что Тед называет "спутниковой базой данных", не может быть сохранено с очень оригинальным ID, и по какой-либо причине вам нужно создать новую, если вы не можете обновить данные на старой (например, из-за разрешений или в случае, если вы ищете стабильность в случае, который настолько эфемерен, что не заслуживает абсолютного и полного уважения к общим нормам нормализации, просто потому, что будет очень короткоживущей полезностью)
Итак, я согласен в двух моментах:
(A). Да, во многих случаях лучший дизайн может избежать этого; НО
(B.) В случаях миграции, репликации баз данных или решения чрезвычайных ситуаций это БОЛЬШОЙ ИНСТРУМЕНТ, который, к счастью, был там, когда я пошел искать, если он существует.