Каскадные удаления, вызывающие несколько каскадных путей

Я использую SQlServer 2008, и ниже приведены некоторые таблицы данных:

пользователей

Идентификатор (ПК)

UserItems

UserId (PK) ItemId (PK) - (составной ключ из 2 столбцов)...

UserItemVotes

UserId (PK) ItemId (PK) VoterId (PK) - (составной ключ из 3 столбцов)

У меня определены следующие отношения:

  • User.Id -> UserItems.UserId
  • (UserItems.UserId, UserItems.ItemId) -> (UserItemVotes.UserId, UserItemVotes.ItemId)
  • UserId.Id -> UserItemVotes.VoterId

Теперь у меня проблема при включении каскадного удаления. При добавлении 3-го отношения я получаю сообщение об ошибке "... может вызвать циклы или несколько каскадных путей. Укажите ON DELETE NO ACTION или ON UPDATE NO ACTION или измените другие ограничения FOREIGN KEY". Я не очень хочу этого делать, в идеале, если пользователь будет удален, я бы хотел удалить его элемент пользователя и / или его голоса.

Это плохой дизайн? Или есть способ получить поведение, которое я хочу от SQL Server?

3 ответа

Решение

Я бы привел к плохому дизайну. Хотя большинство СУБД могут управлять каскадным удалением, использование этой встроенной функциональности рискованно. Ваш сценарий - прекрасный пример того, почему этими типами вещей часто управляют в коде приложения. Там вы можете точно определить, что нужно удалить и в каком порядке.

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

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

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

"UserItems.ItemId -> UserItemVotes.UserId"

Этот кажется крайне подозрительным.

Другие вопросы по тегам