下面是我的数据库结构的简化版本(在 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 成员(member)商店。我想实现用户能够“收藏”和评价特定项目(和尺寸),所以我最初的冲动是实现几个基本的映射表:
[FavouriteSizes]
UserID (PK) (FK)
SizeID (PK) (FK)
[ItemRatings]
UserID (PK) (FK)
ItemID (PK) (FK)
Rating
但是,如果我强制执行参照完整性,当店主想要删除商品、商品大小甚至关闭他/她的整个商店时,我当然会遇到问题。
我确定的选项是:
WHERE IsActive
表连接使每个查询变得繁琐。另外我相信(如果我错了,请纠正我)这会增加 EF4 中的一些复杂性,例如 Items.Includes("ItemSizes")
. [FavouriteSizes].SizeID
FK 和 [ItemRatings].ItemID
FK 上) : 我以前从来没有这样做过。这似乎是“最简单”的答案,但我不确定它以后是否会回来咬我。 鉴于不强制执行这 2 个外键约束似乎是最简单的选择,我的实现将是:
ItemName
至 [FavouriteSizes]
,并用 ItemSize.Item.ItemName
填充它当用户喜欢尺寸时 FavouritedSize.Items Is Nothing
),则添加一个助手以显示通知,以便用户可以从他们的收藏夹列表中删除该项目。 这种实现会在 future 引起问题吗?是否有足够的理由让我不惜执行软删除而不是不强制执行参照完整性(除了保留历史数据以进行报告)?我是否错过了更适合的选项?
最佳答案
不执行参照完整性是一件有风险的事情,除非您绝对且完全确定除了您的应用程序之外没有任何人会在此表中填充数据(并且您的应用程序当然经过测试以确保其保持完整性)
在实际场景中,我发现这种方法有风险,因为一旦系统投入生产,总会有其他应用程序出现的可能性,尤其是在某些紧急情况下的数据迁移工具/补丁/一些直接数据操作- 最终会操纵数据,并且在没有约束的情况下,他们将无法识别这种关系,并且可能最终会输入不正确的数据。
此外,我不知道您是否需要此输入,但是查看您的架构,我可能会考虑稍作更改
[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 - 但总的来说,我会说通过确保检查特定点来确保检查始终存在于所有查询中很容易完成 - 作为一部分审查过程。通常,它成为团队中的第 2 种性质,并且确保检查可以忽略不计的额外努力。
关于sql-server - 软/逻辑删除 vs 无参照完整性 vs ...?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4383533/