Дилемма: каскадное удаление или присоединение к удалению - PullRequest
8 голосов
/ 19 октября 2011

Это не конкретный вопрос, более общий вопрос.

Когда вам нужно удалить несколько таблиц в отношении 1: M, лучше сделать ограничение FK каскадным удалением или объединить таблицы в операторе удаления.

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

Существует также возможность сделать хранимую процедуру или транзакцию.

ИтакЯ ищу мнение или совет ...?

Ответы [ 4 ]

7 голосов
/ 19 октября 2011

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

Если вы используете каскадное удаление, никто ничего не должен помнить, и дочерние строки всегда будут удаляться по мере необходимости.

4 голосов
/ 31 октября 2011

Если для вашей базы данных определен правильный RI, то не должно быть случаев нарушения целостности данных. Все ваши связанные таблицы должны иметь декларативный RI, что означает, что вы не можете удалить родителя, пока у него еще есть дети.

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

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

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

ИМО, я предпочитаю, чтобы мои разработчики знали о приложении, а не помогали им оставаться в неведении о нем.

4 голосов
/ 19 октября 2011

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

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

0 голосов
/ 01 ноября 2011

Используйте оба!

«Объединенные» ручные удаления обычно лучше предотвращают взаимные блокировки и другие конфликтные проблемы, поскольку вы можете разбить удаления на более мелкие единицы работы.Если у вас есть разногласия, определенно легче найти причину конфликта.

Как указано, "Удалить каскад" будет абсолютно гарантировать ссылочную целостность.

Так что используйте оба - делайте явное удаление "потомков" в соединенных sqls, чтобы избежать тупиков и проблем с производительностью.Но оставьте «CASCADE DELETE» включенным, чтобы ловить все, что вы пропустили.Поскольку при удалении родителя не должно быть детей, это ничего не будет вам стоить, если только вы не допустили ошибку при удалении, и в этом случае стоит сохранить вашу ссылочную целостность.

...