【问题标题】:Advantages and disadvantages of having composite primary key具有复合主键的优点和缺点
【发布时间】:2012-07-20 21:11:23
【问题描述】:

不使用复合主键(此表维护代表两个实体[两个表]的两个表之间的关系),建议设计以identity列作为主键并强制执行唯一数据约束超过两列,代表实体主键中的数据。

对我来说,每个关系表都有标识列违反了规范化规则。

  • 行业标准是什么?
  • 在对此做出设计决策之前需要考虑哪些因素?
  • 哪种方法合适?

【问题讨论】:

  • 复合键专业人士的简单文章:weblogs.sqlteam.com/jeffs/archive/2007/08/23/…
  • 不需要标识列,主键基本上是一组列(1 个或多个),用于唯一定义您的数据。通过添加一个标识列,您正在添加一个额外的索引,并使您可能会使用最多的索引(具有 2 个重要列的索引)作为非聚集索引,加上更新/插入会稍微慢一点,等等。 . 基本上不用了。
  • @RThomas - 在那个博客中,他们使用了一个客户->产品关系,它不应该有一个复合键,因为它表示交易数据。 可以在不同时间创建多个关系,该表需要唯一标识 PKey。例如,订购同一 SKU 下的葡萄酒瓶 - 由单个 ProductID 引用 - (不理想,但可能)。但是,如果每个瓶子都有自己的 ID,那么“订单限制”就没有实际意义,因为您必须为每件商品创建单独的交易记录。要么你构建的结构错误,要么你不正确地跟踪数据。

标签: tsql


【解决方案1】:

有很多表,您可能希望将标识列作为主键。但是,对于您描述的 M:M 关系表,最佳做法是不要为主键使用新的标识列。

RThomas 在他的评论中的链接提供了最佳实践是不添加标识列的绝佳理由。这里是that link

在几乎所有情况下,利弊都会超过利弊,但既然你问利弊,我也列出了几个不太可能的利弊。

缺点

  • 增加复杂性

  • 可能导致重复关系,除非您对关系强制执行唯一性(默认情况下主键会这样做)。

  • 可能较慢:db 必须维护两个索引而不是一个。

优点

所有的专业人士都很粗略

  • 如果您遇到需要使用关系表的主键作为单独表(例如审计表?)的连接的情况,连接可能会更快。 (尽管如前所述 - 添加和删除记录可能会更慢。此外,如果您的关系表是本身使用唯一 ID 的表之间的关系,则在连接中使用一个标识列与两个标识列的速度增加将是最小的。)

  • 为简单起见,应用程序可以假设它使用的每个表都有一个唯一的 ID 作为其主键。 (这是应用程序中糟糕的设计,但您可能无法控制它。)您可以想象这样一种情况,在数据库中引入一些额外的复杂性比在这样的应用程序中引入额外的复杂性更好。

【讨论】:

  • 答案是两者都使用——在每张表上总是有一个唯一的标识[这不仅仅是基于性能的好处/坏处——程序员必须使用这些结构,重要的是要有一个与数据交互的一致方法],但在有意义的地方使用复合键!最重要的是,在您的数据库架构中保持一致。
【解决方案2】:

您必须在每个表中创建所有列作为外键使用。这是最大的缺点。

【讨论】:

    【解决方案3】:

    缺点:

    • 必须在所有引用表中导入复合主键。 这意味着更大的索引,以及要编写的更多代码(例如连接、 更新)。如果您系统地使用复合初级 键,它会变得非常麻烦。
    • 您不能更新主键的一部分。例如。如果你使用 university_id,student_id 作为大学表中的主键 学生,并且一名学生改变了大学,您必须删除 并重新创建记录。

    优点:

    • 复合主键允许强制执行一种常见的约束 以一种强大而无缝的方式。假设你有一张 UNIVERSITY 表, 一个表 STUDENT、一个表 COURSE 和一个表 STUDENT_COURSE(其中 学生学习哪门课程)。如果这是一个约束,你总是 必须是 A 大学的学生才能修读以下课程 大学 A,那么该约束将被自动验证,如果 university_id 是 STUDENT 和 课程。

    【讨论】:

    • Re “必须在所有引用表中导入复合主键。” 好点 - 有助于澄清何时值得添加标识键。例如,考虑具有 N:N 对的复合主键以及少量附加列的表。并且没有其他表“引用”这些复合键。如果后来设计演变为添加另一个表,其中包含与某些 N:N 对关联的附加信息,那么此时值得考虑在 N:N 表中添加一个标识列,以便新表只需要引用它。跨度>
    猜你喜欢
    • 2015-12-01
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多