假设您有这些表:RestaurantChains
,Restaurants
,MenuItems
- 它们之间有明显的关系。现在,您有表Comments
和Ratings
,它们存储有关连锁店,餐馆和菜单项的客户评论/评级。链接这些表的最佳方法是什么?显而易见的解决方案可能是:
OwnerType
和OwnerID
中使用列Comments
和Ratings
,但现在我无法添加外键来将评论/评级与其对象相关联Comments
和Ratings
的单独表格,例如MenuItemRatings
,MenuItemComments
等。此解决方案的优点是所有正确的外键都存在,并且明显不利于拥有大量和大量具有基本相同结构的表。那么,哪种解决方案效果更好?或者是否有一个我不了解的更好的解决方案?
答案 0 :(得分:4)
由于关于菜单项的评论与关于餐馆的评论不同(即使它们碰巧共享相同的结构),我会将它们放在单独的表中并使用适当的FK来强制数据库中的某些数据完整性。
我不知道为什么在数据库中有更多表的厌恶。除非您从50个表到50,000个表,否则由于大型目录表而无法看到性能问题(在这种情况下,拥有更多,更小的表实际上应该可以提供更好的性能)。我还倾向于认为在处理名为“Menu_Item_Comments”和“Restaurant_Comments”的表时要比处理一个名为“评论”的表并且不知道其中究竟是什么的更清楚。它的名字。
答案 1 :(得分:1)
答案 2 :(得分:0)
对所有对象都有一个评论/评级表,不要使用自动生成的外键。评级表中的键,例如RatingID可以放在餐厅,连锁店,菜单项表中的字段中,它们都可以指向同一个表,它们仍然是外键。
如果你需要反过来知道评论涉及哪个对象,你需要有一个字段来指明评论的类型,但这应该是全部。
答案 3 :(得分:0)
使用单个表格进行评论,并使用GUID
作为您网站的主要密钥。
然后你可以在事先不知道它们属于的地方选择评论:
SELECT CommentText
FROM Comments c, Restaurants r
WHERE c.Source = r.Id
SELECT CommentText
FROM Comments c, Chains ch
WHERE c.Source = ch.Id
等
当然,你不能使用外键进行评论,但如果没有外键,评论就无法生效。
您可以清除触发器中的孤立注释,但如果剩下其中一些则没有任何不妥。
您还可以创建一个全局Entity
表格(包含一个GUID
列),制作您的Chains
,Restaurants
,MenuItems
和{{1使用Comments
引用该表,当FOREING KEY ON DELETE CASCADE
表示餐馆时,请将其从该表中删除。它将删除餐厅及其上的所有评论,您仍然拥有自己的诚信。
答案 4 :(得分:0)
如果要利用外键约束并在基表之间规范化注释(和评级)的属性,则可能需要在基表和注释(和评级)之间创建关系表。
e.g。餐馆和评论:
Restaurants
id (PK)
(attributes of restaurants...)
RestaurantComments
id (PK)
restaurantid (FK to Restaurants)
commentid (FK to Comments)
Comments
id (PK)
(attributes of comments...)