【问题标题】:Database Design for Multi-use Table多用途表的数据库设计
【发布时间】:2011-05-08 21:12:55
【问题描述】:

假设您有多个“事物”,每个“事物”都可以附加一个或多个 cmets。例如,产品和订单。表的结构应该如何......

  1. 产品、订单、评论、ProductComment { ProductID、CommentID }、OrderComment { OrderID、CommentID }
  2. 产品、订单、ProductComment { ProductID、Text }、OrderComment { OrderID、Text }
  3. 产品、订单、评论 { ProductID, OrderID, Text }

顺便说一下,使用 SQL Server 2008。

想法、意见?

【问题讨论】:

标签: database database-design data-modeling


【解决方案1】:

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

【讨论】:

  • 感谢您的建议,但我发现这是一种非常肮脏的、非面向对象的数据库构建方式。您正在丢失用于验证实体是否实际存在的数据库逻辑。当然,您可以在代码中执行此操作,但从数据库的角度来看,这不是一个非常干净的解决方案。
  • @Josh M - 您将不得不考虑空间权衡。并非一切都可以完美。这是一种非常 OO 的做事方式 - Entity 是多态的,因为它在一个表中表示许多不同的类型。
【解决方案2】:

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

如果您对所有 ID 都使用 GUIDS,并且不介意在数据库中没有定义外键,那么还有其他选择,但我不认为您拥有的数据库架构样式。

这是让我觉得关系模型令人头疼的用例之一!

【讨论】:

    【解决方案3】:

    如果你不喜欢entityID,entityType方法,因为你不能使用外键约束,你可以采取混合策略,比如

    COMMENT(commentID, comment, productID, orderID, ....)
    

    将 ... 作为每个可注释表格的附加列。

    【讨论】:

    • 这也许可行,但 asstander 的回答是它通常是如何完成的。
    • 这是我的选项#3。不确定我是否喜欢它....我倾向于选项 1。
    • @TokenMacGuy 我认为 asstander 的回答比我列出的 3 个选项差。
    • @TokenMacGuy 你能提供一些例子来说明它是如何“正常”完成的吗?像 Doctrine 这样的 ORM 在其内置的多对多关系中甚至不支持 方法。并且有一些明显的缺点。不用说,我很怀疑。
    • 好吧,Django 和 Rails 中的 ORM 都按照 asstander 建议的方式工作
    【解决方案4】:

    绝对只使用一个评论表,因此您不必复制评论信息(例如时间戳、flagged_for_moderation 等)。在评论中有两个字段很好,因为它清楚地表明它是一个一对多的链接。我可能会倾向于通过多个链接表来实现这一点,尽管我很欣赏当有链接时链接表中只有行,而不是一半的值是NULL。也许在一个非常大的数据库中有更多可以评论的东西,你可能会选择链接表。

    【讨论】:

    • 同意复制方面。我喜欢链接表,但我不喜欢进入评论表的额外步骤。
    • 是的,链接表确实使您的查询更加复杂。使用多列也意味着如果你得到所有的评论,你可以知道它们是什么类型的评论,而不需要做任何 JOIN,如果你在 URL(或其他引用)中使用 ID,你可以直接链接到被评论的项目。
    • 我喜欢链接表的另一个原因是您可以根据需要添加其他字段。也许 ProductComment 表也有一些与 Product\Comment 组合严格相关的字段。
    • 如果您需要额外的字段或者您希望很快会用到,我会说使用链接表。对未来的模式进行验证真的很困难。另外,顺便说一句,我经常使用约定 Product_Comment 来链接表,以区分它们和正常的驼峰式表名。
    • 我认为链接表选项是最灵活和面向未来的。这些表可以被视为传递表,因为它们实际上是一对一的。因此可以生成代码以直接在 Product 表上公开 Comment 表,完全跳过链接表。
    【解决方案5】:

    我认为Order/Product 表应该保持原样。

    Comments 表可以是

    CommentID
    EntityID
    EntityType
    Comment
    

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

    【讨论】:

    • 谢谢。我没有列出这个选项的原因是因为这会破坏外键。我真的不想检查 EntityType 来确定要查看哪个表来获取实体。
    • 这确实有一个限制,即您不能在支持它们的数据库(例如 InnoDB)中使用显式外键,这意味着您不能真正利用像 CASCADE 这样的功能。我很欣赏它减少了必要的表格数量,在许多情况下这很好,但它并不普遍值得。
    • 我可能会倾向于这个,因为它使您可以灵活地在将来添加另一种类型,而无需创建更多的 ORM 类型的代码来支持它(或添加另一个表或字段)。当然你不能再做级联了,但在这些特殊情况下你必须做出一些妥协。
    猜你喜欢
    • 2016-01-20
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 2017-01-04
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多