Каскадные операции

Каким может быть поведение ON DELETE для внешних ключей, давайте разберем на примере.

CASCADE - распространяет операции изменения/удаления родительского ключа на зависящие от него дочерние ключи.

CREATE TABLE parent (
    id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    name varchar
);

CREATE TABLE child (
    id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    parent_id int,
    CONSTRAINT fk_parent_id
        FOREIGN KEY (parent_id)
            REFERENCES waiter.parent(id)
            ON DELETE CASCADE
            ON UPDATE CASCADE

);

  • при изменении значения в parent.id изменяется значение в child.parent_id
  • при удалении строки в parent удаляются все строки в child, у которых child.parent_id = parent.id
  • внимание - значение child.parent_id может быть NULL (как видно выше, мы не накладывали на него условия NOT NULL)

RESTRICT - запрещает изменять/удалять родительский ключ, когда существует один или несколько ссылающихся на него дочерних ключей

SET NULL - оставит при удалении все зависимые записи, но сбросит им child.parent_id в NULL, т.е. ссылаться на удаленную запись они перестанут.

SET DEFAULT - значение каждого столбца дочернего ключа устанавливается в значение по умолчанию для данного столбца. О том, как столбцам назначаются значения по умолчанию, можно узнать в подробной документации по CREATE TABLE.

NO ACTION - никаких специальных действий не производится при изменении/удалении родительского ключа.

Итак, если вы боритесь за консистентность и сохранение истории в своих данных, то Ваш путь:

  • ON UPDATE CASCADE
  • ON DELETE RESTRICT

*заметка: Doctrine поддерживает CASCADE, SET NULL и RESTRICT.


28.12.2010 10:17