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

Как работают внешние ключи Postgres "on update" и "on delete"?

Может ли кто-нибудь дать ясное объяснение/пример того, что делают эти функции, и когда оно подходит для их использования?

4b9b3361

Ответ 1

Прямо от руководство...

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

Запретить удаление ссылочного продукта

Удалите также и заказы

Что-то еще?

CREATE TABLE order_items (
 product_no integer REFERENCES products ON DELETE RESTRICT,
 order_id integer REFERENCES orders ON DELETE CASCADE,
 quantity integer,
 PRIMARY KEY (product_no, order_id)
);

Ограничительные и каскадные удаления являются двумя наиболее распространенными параметрами. RESTRICT предотвращает удаление ссылочной строки. NO ACTION означает, что если какие-либо ссылочные строки все еще существуют, когда проверяются ограничения, возникает ошибка; это поведение по умолчанию, если вы ничего не указали. (Существенное различие между этими двумя вариантами заключается в том, что NO ACTION позволяет отложить проверку до поздней транзакции, тогда как RESTRICT не делает этого.) CASCADE указывает, что при удалении ссылочной строки строки, ссылающиеся на нее, должны быть автоматически удалены также. Есть еще два варианта: SET NULL и SET DEFAULT. Это приводит к тому, что ссылочные столбцы будут установлены на нули или значения по умолчанию, соответственно, когда удаленная строка будет удалена. Обратите внимание, что это не оправдывает вас соблюдением каких-либо ограничений. Например, если действие указывает SET DEFAULT, но значение по умолчанию не будет удовлетворять внешнему ключу, операция завершится с ошибкой.

Аналогично ON DELETE также появляется сообщение ON UPDATE, которое вызывается, когда столбец с исправлением изменен (обновлен). Возможные действия одинаковы.

изменить: Возможно, вы захотите взглянуть на этот связанный с ним вопрос: Когда/Зачем использовать Cascading в SQL Server?. Концепции, стоящие за вопросом/ответами, одинаковы.

Ответ 2

У меня есть база данных PostGreSQL, и я использую On Delete, когда у меня есть пользователь, который я удаляю из базы данных, и мне нужно удалить его из другой таблицы. Этим способам я должен сделать только 1 удаление и FK, который имеет значение "Удалить", удалит информацию из другой таблицы.

Вы можете сделать то же самое с ON Update. Если вы обновите таблицу, а в поле появится FK с On Update, если вы сделаете изменение в FK, вы увидите в таблице FK.

Ответ 3

Что говорит Даок, это правда... это может быть довольно удобно. С другой стороны, все, что происходит автоматически в базе данных, может быть реальной проблемой, особенно когда дело доходит до устранения данных. Возможно, что в будущем кто-то будет рассчитывать на то, что FK обычно предотвращают удаление родителей, когда есть дети, и не понимают, что ваше использование On Delete Cascade не только не препятствует удалению, но и делает огромные объемы данных в десятках другие таблицы исчезают благодаря водопаду каскадных удалений.

Комментарий @Arthur.

Чем чаще "скрытые" вещи происходят в базе данных, тем меньше вероятность того, что кто-нибудь когда-нибудь будет хорошо разбираться в происходящем. Триггеры (и это по существу триггер) могут привести к моему простому действию удаления строки, чтобы иметь широкие последствия в моей базе данных. Я выдаю инструкцию "Удалить", а 17 таблиц затронуты каскадами триггеров и ограничений, и ни одно из них не сразу становится очевидным для эмитента команды. OTOH. Если я поместил исключение родителя и всех его дочерних элементов в процедуру, то очень просто и ясно, чтобы кто-нибудь мог увидеть ТОЧНО, что произойдет, когда я выведу команду.

Это абсолютно не имеет никакого отношения к тому, насколько хорошо я проектирую базу данных. Он имеет все, что связано с операционными проблемами, возникающими при срабатывании триггеров.

Ответ 4

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