Я не проектирую схемы каждый день, но когда я это делаю, я пытаюсь правильно настроить / удалить каскадные обновления, чтобы упростить администрирование. Я понимаю, как работают каскады, но я никогда не могу вспомнить, какой стол какой.
Например, если у меня есть две таблицы - Parent
и Child
- с внешним ключом для Child
этих ссылок Parent
и имеет ON DELETE CASCADE
, какие записи вызывают каскад и какие записи удаляются каскадом? Моим первым предположением будет Child
удаление Parent
записей при удалении записей, поскольку Child
записи зависят от Parent
записей, но ON DELETE
это неоднозначно; это может означать удаление Parent
записи при Child
удалении записи, или это может означать удаление Child
записи при Parent
удалении. Так что это?
Я хочу синтаксис был ON PARENT DELETE, CASCADE
, ON FOREIGN DELETE, CASCADE
или что - то подобное для устранения неясности. У кого-нибудь есть мнемоника для запоминания этого?
источник
Order(custID, itemID, orderID)
гдеcustID
ссылается на первичный ключ вCustomers
таблице иitemID
ссылается на первичный ключ вItems
таблице. НеOrder
будет двух родителей?ON DELETE CASCADE - это необязательное условие в объявлении внешнего ключа. Так же и с декларацией внешнего ключа. (Имеется в виду в таблице «ребенок».)
Один из способов интерпретации объявления внешнего ключа: «Все допустимые значения для этого столбца взяты из« that_column »в« that_table »». Когда вы удаляете строку в «дочерней» таблице, это никого не волнует. Это не влияет на целостность данных.
Когда вы удаляете строку из «родительской» таблицы - из «that_table» - вы удаляете допустимое значение из возможных значений для «дочерней» таблицы. Чтобы сохранить целостность данных, вы должны что- то сделать с «дочерней» таблицей. Каскадное удаление - это одна вещь, которую вы можете сделать.
источник
SQL: 2011 Spec
Есть пять вариантов
ON DELETE
, иON UPDATE
это может применяться кFOREIGN KEY
. Они вызываются<referential actions>
непосредственно из спецификации SQL: 2011Внешний ключ устанавливает зависимые отношения.
<referential action>
Определяет , что происходит , когда растворяются отношения.Пример / Метафора / Объяснение
В этом примере мы примем общую модель общества и экономики: где каждый
business
- это компания, которая поддерживает отношения сbourgeoisie
помощью afatcat_owner
.Если все
business
они непосредственно затронуты ихbourgeoisie
путем,fatcat_owner
то что вы делаете после рабочей революции, когда вы очищаете ееfatcat_owner
и имеете бесклассовое общество?У вас есть несколько вариантов здесь,
RESTRICT
. Некоторые люди считают, что это меньшее зло, но обычно они ошибаются.Позвольте этому продолжаться. Если так, когда произойдет революция, SQL дает вам четыре варианта,
SET NULL
- оставь это поле пустым. Кто знает, может быть, капитализм восстановитсяbourgeoisie
, и олигархи заполнят списокfatcat_owners
. Важное примечание, столбец должен бытьNULLABLE
(нетNOT NULL
), иначе этого не может быть.SET DEFAULT
- Может быть, выDEFAULT
справились с этим? АDEFAULT
может вызвать функцию. Возможно, ваша схема уже готова к революции.CASCADE
- нет контроля ущерба. Еслиbourgeoisie
идет, то иbusiness
. Если бизнес должен иметьfatcat_pig
, то иногда имеет смысл потерять данные, а не иметь некоммерческий бизнес вbusiness
таблице.NO ACTION
- по сути, это метод задержки проверки, в MySQL он ничем не отличается отRESTRICT
, но в PostgreSQL вы сможете сделать этоВ такой системе ограничение проверяется только перед фиксацией транзакции. Это может привести к остановке революции, но вы можете восстановить транзакцию - для некоторой степени «восстановления».
источник
referenced
таблица означает родительскую таблицу иreferencing
таблица означает ребенок таблицу?Простая мнемоника будет
УДАЛИТЬ родительский CASCADE [удаляя] здесь
Это говорит вам, какие операции удаления (удаления родительского элемента) каскадируются, куда идет оператор ON DELETE CASCADE (для дочернего элемента ) и что удаляется (дочерний элемент).
источник
ну, возможно, мы можем рационализировать синтаксис. Давайте возьмем пример Python:
то, что в этой строке написано on_delete для Parent (что случайно упоминается в выражении), пожалуйста, каскадно удалите дочерний объект. Вот почему оператор CASCADE определяется на дочернем уровне, он отмечает тех дочерних элементов, которые необходимо удалить.
Например, если у вас был другой класс
эта структура четко показала бы, кого из детей нужно удалить (Child), а каких оставить (GrownUpChild), хотя и осиротеть
[Редактировать: учитывая контекст обсуждения, особенно в случаях on_delete = models.CASCADE и т. Д.], На самом деле часто бывает желательным оставлять детей удаленного родителя из-за причин аудита и отчетности, а также из-за случайного восстановления удаления. [конечно, программное обеспечение уровня предприятия будет построено на основе такого поведения и будет помечать удаленные записи как удаленные = 1 вместо фактического их удаления, а также не будет включать их в какие-либо запросы для внешнего интерфейса, за исключением некоторых специально разработанных отчетов. Кроме того, он будет иметь функцию очистки удаленных == 1 записей из базы данных, которая обычно выполняется администратором пользовательского интерфейса, часто избегая какого-либо участия со стороны администратора базы данных.]
источник