Когда использовать " 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
);

для "on DELETE CASCADE", если родитель с id удаляется, запись в ребенком с parent_id = parent.id будет автоматически удален. Это не должно быть проблемой.

  1. это означает, что" ON UPDATE CASCADE " будет делать то же самое, когда id of родитель обновляется?

  2. если (1) верно, это означает, что нет необходимости использовать "ON UPDATE CASCADE", если parent.id не обновляется (или никогда не будет обновляться), как когда это AUTO_INCREMENT или всегда быть TIMESTAMP. Это правда?

  3. если (2) не верно, в какой другой ситуации мы должны использовать "ON UPDATE CASCADE"?

  4. Что делать, если я (по какой-то причине) обновить child.parent_id чтобы быть чем-то несуществующим, будет ли это затем будет автоматически удален?

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

пожалуйста, пролей немного света.

6 351

6 ответов:

Это правда, что если ваш первичный ключ-это просто значение идентификатора, автоматически увеличенное, вы не будете иметь реального использования для ON UPDATE CASCADE.

однако, предположим, что ваш первичный ключ представляет собой 10-значный штрих-код UPC, и из-за расширения вам нужно изменить его на 13-значный штрих-код UPC. В этом случае при обновлении каскад позволит вам изменить значение первичного ключа, и все таблицы, которые имеют ссылки на внешний ключ, будут изменены соответствующим образом.

In ссылка на #4, Если вы измените дочерний идентификатор на то, что не существует в родительской таблице (и у вас есть ссылочная целостность), вы должны получить ошибку внешнего ключа.

  1. Да, это означает, что, например, если вы делаете UPDATE parent SET id = 20 WHERE id = 10 все дети parent_id из 10 также будут обновлены до 20

  2. Если вы не обновляете поле, на которое ссылается внешний ключ, этот параметр не нужен

  3. не могу придумать никакого другого использования.

  4. вы не можете этого сделать, так как ограничение внешнего ключа не будет выполнено.

Я думаю, что вы в значительной степени прибил точки!

Если вы следуете рекомендациям по дизайну базы данных, и ваш первичный ключ никогда не обновляется (что, я думаю, всегда должно быть так), то вам никогда не понадобится ON UPDATE CASCADE предложения.

Зед сделал хороший момент, что если вы используете естественные key (например, обычное поле из таблицы базы данных) в качестве первичного ключа, тогда могут возникнуть определенные ситуации, когда вам нужно обновить свой первичный ключ. Другим недавним примером может быть ISBN (International Standard Book Numbers), который не так давно изменился с 10 до 13 цифр+символов.

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

Итак, в конце концов: если ваш первичный ключ никогда не меняется, то вам никогда не понадобится ON UPDATE CASCADE пункт.

Марк

несколько дней назад у меня была проблема с триггерами, и я понял, что 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
);

в моем выпуске мне пришлось определить некоторые дополнительные операции (триггер) для обновления таблицы концерта. Эти операции должны были изменить club_name и band_name. Я не смог этого сделать из-за ссылки. Я не мог изменить концерт, а затем иметь дело с клубными и групповыми столами. Я не мог также сделать это по-другому. ON UPDATE CASCADE ключ к решить проблему.

мой комментарий в основном относится к пункту #3: при каких обстоятельствах применяется каскад обновлений, если мы предполагаем, что родительский ключ не обновляется? Вот один случай.

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

Это отличный вопрос, у меня вчера был тот же вопрос. Я думал об этой проблеме, специально искал, существует ли что-то вроде "ON UPDATE CASCADE", и, к счастью, дизайнеры SQL также думали об этом. Я согласен с Тедом.Штраус и я также прокомментировали дело Норана.

когда я его использовал? Как указал Тед, когда вы обрабатываете несколько баз данных одновременно, и модификация в одной из них, в одной таблице, имеет Любое воспроизведение в том, что Ted вызывает "спутниковую базу данных", не может храниться с очень оригинальным идентификатором, и по какой-либо причине вам нужно создать новый, в случае, если вы не можете обновить данные на старом (например, из-за разрешений, или в случае, если вы ищете быстроту в случае, который настолько эфемерен, что не заслуживает абсолютного и полного уважения к общим правилам нормализации, просто потому, что будет очень недолговечной утилитой)

Итак, я согласен в двух пунктах:

(А.) Да, во многих раз лучший дизайн может избежать этого; но

(B.) В случаях миграции, репликации баз данных или решения чрезвычайных ситуаций это отличный инструмент, который, к счастью, был там, когда я пошел искать, если он существовал.