2008-10-22 1 views

ответ

22

Прямо из the manual ...

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

Disallow УДАЛЕНИЕ ссылается продукт

Удаление заказов, а также

Что-то еще?

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 есть также ОБНОВЛЕНИЕ, которое вызывается, когда ссылочный столбец изменяется (обновляется). Возможные действия одинаковы.

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

0

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

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

0

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

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

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

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

+1

Я не думаю, что это проблема, если схема спроектирована правильно. обычно дети (FK) данных не очень полезны без его родителя. – 2008-10-22 15:30:40

0

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

Смежные вопросы