Мягкое / логическое удаление против ссылочной целостности против ...? - PullRequest
4 голосов
/ 08 декабря 2010

Ниже приведена упрощенная версия структуры моей базы данных (создание концептуального сайта в MVC 2 с Entity Framework 4 в качестве моего ORM):

[Stores]
StoreID (PK)
StoreName

[Items]  
ItemID (PK)  
ItemName
Description
StoreID (FK)

[ItemSizes]
SizeID (PK)  
SizeName
Price
ItemID (FK)

[Users]
UserID (PK)
UserName

Магазины продать предметы , которые бывают разных размеров .[Users] представляет стандартное хранилище членства asp.net.

Я бы хотел, чтобы пользователи имели возможность "выбирать" и оценивать отдельные элементы (и размеры), поэтому я сначала хотел реализовать несколько основныхТаблицы сопоставления:

[FavouriteSizes]
UserID (PK) (FK)
SizeID (PK) (FK)

[ItemRatings]
UserID (PK) (FK)
ItemID (PK) (FK)
Rating

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

Опции, которые я определила:

  • Каскадное удаление : основным недостатком является следующий раз, когда пользователь входит в систему, его избранные элементы полностью отсутствуют
  • Soft / Logical Deletes : в этом случае я уклоняюсь от них, потому что когда я использовал их в прошлом, добавление WHERE IsActive к каждому запросу становится затруднительнымстол присоединяется.Кроме того, я верю (поправьте меня, если я не прав), это добавляет сложности в EF4, скажем, Items.Includes("ItemSizes").
  • Неисполнение ссылочной целостности (на [FavouriteSizes].SizeID FK и [ItemRatings].ItemIDТолько для ФК) : Я никогда раньше так не делал.Это кажется «самым простым» ответом, но я не уверен, что он вернется, чтобы укусить меня позже.

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

  1. Добавьте ItemName к [FavouriteSizes] и заполните егос ItemSize.Item.ItemName, когда пользователь выбирает размер
  2. Добавьте помощника для отображения уведомления, если избранный элемент больше не доступен (FavouritedSize.Items Is Nothing), чтобы пользователи могли удалить этот элемент из списка избранных.
  3. Убедитесь, что любые отчеты типа «Самые рейтинговые элементы» извлекают только те элементы, которые еще существуют.

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

1 Ответ

2 голосов
/ 08 декабря 2010

Отказ от применения ссылочной целостности - рискованная вещь, если вы не абсолютно и не уверены, что НИКТО, а ВАШЕ приложение не будет когда-либо заполнять данные в этой таблице (и что ваше приложение, конечно, протестировано, чтобы убедиться, что оно сохраняетцелостность)

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

Кроме того, я не знаю, нужен ли вам этот ввод, но, глядя на вашу схему, я, вероятно, рассмотрю небольшое изменение

[Stores]
StoreID (PK)
StoreName

[Items]  
ItemID (PK)  
ItemName
Description
StoreID (FK)

[Sizes]
SizeID (PK)  
SizeName

[ItemSizes]
ItemID (PK)
SizeID (PK)  
Price

[Users]
UserID (PK)
UserName

Примечание: я разделил вашу таблицу [ItemSizes] на [Sizes] и [ItemSizes].

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

[FavouriteSizes]
UserID (PK) (FK)
SizeID (PK) (FK)
IsActive

[FavouriteItemSizes]
UserID (PK) (FK)
ItemID (PK) (FK)
SizeID (PK) (FK)
IsActive

[ItemRatings]
UserID (PK) (FK)
ItemID (PK) (FK)
Rating
IsActive

Подводя итог, добавьте поля IsActive, даже в избранное и рейтингтаблицы - в дополнение к вашим основным таблицам - с помощью WHERE IsActive проверять и делать избранное / оценки мягкими - удаляются при удалении элемента / размера / размера элемента, а затем иметь дополнительную логику для отображения ваших избранных / оценок, чтобы указать не- наличие ранее добавленных оценок / избранного для пользователя кажется мне лучшим вариантом.

Я не совсем уверен в том, как проверка IsActive работает с EF - не использовал EF - но в целом, я бы сказал,убедиться, что проверка всегда присутствует во всех запросах, легко, если убедиться, что конкретный пункт проверен - как часть процесса проверки.Обычно это становится второй натурой в команде, и дополнительные усилия по обеспечению того, чтобы проверка была незначительной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...