多用途表的数据库设计

5
假设您有多个“事物”,每个事物都可以附加一个或多个评论。例如,产品和订单。表应该如何结构化呢?
  1. Product,Order,Comment,ProductComment { ProductID,CommentID },OrderComment { OrderID,CommentID }
  2. Product,Order,ProductComment { ProductID,Text },OrderComment { OrderID,Text }
  3. Product,Order,Comment { ProductID,OrderID,Text }
顺便说一下,使用 SQL Server 2008。
你有什么想法或意见吗?

请看一个类似的问题/答案。链接 - Damir Sudarevic
5个回答

2
我认为订单/产品表应该保持不变。 评论表可以
CommentID
EntityID
EntityType
Comment

EntityType会告诉你EntityID属于哪个表格(ProductID/OrderID)。


谢谢。我没有列出这个选项的原因是因为这会破坏外键。我不想检查实体类型以确定要查找实体的表。 - Josh M.
这确实有一个限制,即您无法在支持显式外键的数据库(例如InnoDB)中使用它们,这意味着您无法真正利用CASCADE等功能。我欣赏它减少了必要的表格数量,在许多情况下这是好的,但并不普遍值得。 - theazureshadow
1
我可能会倾向于这个方案,因为它为您提供了灵活性,以后可以添加另一种类型,而无需创建任何其他ORM类型的代码来支持它(或添加另一个表或字段)。当然,您不能再使用级联操作,但在这些特殊情况下,您必须做出一些妥协。 - Chad Braun-Duin

1

绝对只使用一个注释表,这样您就不必复制注释信息(例如时间戳、待审核标记等)。在注释中有两个字段很好,因为它清楚地表明这是一对多的链接。虽然我欣赏您只有在有链接时才在链接表中拥有行,而不是让一半的值为NULL,但我可能更倾向于使用多个链接表。也许在一个非常大的数据库中,有更多可以评论的事情,您可能会选择使用链接表。


同意关于重复方面的问题。我喜欢连接表,但我不喜欢额外的步骤来到达评论表。 - Josh M.
是的,连接表确实会使您的查询更加复杂。而使用多个列则意味着如果您获取所有评论,您可以在不进行任何JOIN的情况下知道它们是什么类型的评论,如果您在URL(或其他引用)中使用ID,则可以直接链接到被评论的项目。 - theazureshadow
我喜欢链接表的另一个原因是,您可以根据需要添加其他字段。也许ProductComment表还有一些字段与Product\Comment的组合严格相关。 - Josh M.
1
如果你需要额外的字段或者预计很快会需要,我建议使用链接表。很难将一个架构未来可用化。另外,顺便说一下,我经常使用“Product_Comment”这种约定来区分链接表和普通的驼峰式表名。 - theazureshadow
我认为链接表选项是最灵活和未来可靠的。这些表可以被视为传递表,因为它们实际上是一对一的。因此,可以生成代码直接在产品表上公开评论表,完全跳过链接表。 - Josh M.

0
如果您不喜欢使用entityIDentityType方法,因为无法使用外键约束,那么您可以采用混合策略,例如:
COMMENT(commentID, comment, productID, orderID, ....)

在每个可评论的表格中增加...'s作为另外一列.


这个程序可能可以工作,但 astander 的答案是通常的做法。 - SingleNegationElimination
这是我的第三个选项。虽然我不确定是否喜欢它...但我更倾向于选择1。 - Josh M.
@TokenMacGuy,我认为astander的答案比我列出的三个选项更糟糕。 - Josh M.
好的,Django和Rails中的ORM都按照astander建议的方式工作。 - SingleNegationElimination
Django非常出色地支持它,其中包括django.contrib.contenttypes应用程序,该应用程序在原始发行版中。 - SingleNegationElimination
显示剩余2条评论

0

我喜欢在添加实体ID和实体类型列时增加灵活性,而无需进行额外的连接。


谢谢您的建议,但我认为这是一种相当不规范、非面向对象的数据库结构方式。您失去了验证实体是否存在的数据库逻辑。当然,您可以在代码中完成此操作,但从数据库的角度来看,这并不是一个非常干净的解决方案。 - Josh M.
@Josh M - 你必须考虑空间的权衡。并不是所有东西都能完美无缺。这是一种非常面向对象的做法——实体是多态的,因为它在一个表中代表了许多不同的类型。 - skaz

0

如果您使用链接表,并且有超过2或3个可以链接到评论的“类型”,那么开始考虑生成代码以创建所需的所有SQL。很快,您将拥有101个链接表和大量的表定义SQL需要维护。

如果您对所有ID使用GUIDS并且不介意在数据库中没有定义外键,则有其他选项,但我认为这不是您拥有的数据库模式风格。

这是其中一个用例,让我觉得关系模型非常麻烦!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接