7

假设我们有一个 Product 表、一个 Order 表和一个(联结表)ProductOrder。

ProductOrder 将有一个 ProductID 和一个 OrderID。
在我们的大多数系统中,这些表还有一个称为 ID 的自动编号列。

放置主键(以及聚集键)的最佳做法是什么?

  • 我是否应该保留 ID 字段的主键并为外键对(ProductID 和 OrderID)创建非聚集索引

  • 或者我应该把外键对(ProductID和OrderID)的主键放在ID列上(如果有必要的话)

  • 或者......(你们中的一个人的聪明评论:))

4

4 回答 4

6

我知道这些话可能会让你畏缩,但“这取决于。”

您很可能希望订单基于 ProductID 和/或 OrderId 而不是自动编号(代理)列,因为自动编号在您的数据库中没有自然意义。您可能希望按与父表相同的字段对连接表进行排序。

  1. 首先了解为什么以及如何首先使用代理键 ID;这通常会决定你如何索引它。我假设您正在使用代理键,因为您正在使用一些适用于单列键的框架。如果没有特定的设计原因,那么对于连接表,我会简化问题并删除自动编号 ID,如果它没有带来其他好处。主键变为 (ProductID, OrderID)。如果不是,您至少需要确保 (ProductID, OrderID) 元组上的索引是唯一的,以保持数据完整性。

  2. 当查询需要与索引的排序顺序相同的结果时,聚集索引适用于顺序扫描/连接。因此,请查看您的访问模式,确定您将使用哪些键进行顺序、多行选择/扫描,以及您将使用哪些键进行随机、单独的行访问,并在其上创建聚集索引您将扫描最多的密钥,以及您将用于随机访问的密钥上的非聚集密钥索引。您必须选择一个或另一个,因为您不能同时对两者进行聚类。

注意:如果您有相互冲突的要求,有一种技术(“技巧”)可能会有所帮助。如果查询中的所有列都在索引中找到,则该索引是数据库引擎用来满足查询要求的候选表。您可以使用这一事实以多个顺序存储数据,即使它们相互冲突。请注意向索引添加更多字段的利弊,并在了解将要处理的查询的性质和频率后做出有意识的决定。

于 2010-03-09T16:42:12.770 回答
3

正确且唯一的答案是:

  • 主键是('orderid' , 'productid')
  • 另一个索引('productid' , 'orderid')
  • 两者都可以集群,但默认是PK

因为:

  • 您不需要单独orderidproductid单独的索引:优化器将使用其中一个索引
  • 您很可能会以“两种”方式使用表格
  • 您不需要代理键,因为您已经在链接表上拥有它们。所以第三列浪费空间。
于 2010-03-09T21:53:51.887 回答
1

这似乎适用于将添加许多订单的动态系统。因此,聚集索引应该在您的自动编号列上。

您可以将索引作为主键并在这对列上放置另一个唯一索引。或者,您可以将这对列设为主键(但非聚集键)。

使用主键或唯一索引键的选择取决于您。但我会确保集群的那个是你的自动编号列。

于 2010-03-09T16:38:40.573 回答
1

我的偏好一直是为主键创建一个自动编号。然后我在两个外键上创建一个唯一索引,这样它们就不会重复。

我这样做的原因是因为我越规范化我的数据,我必须在连接中使用的键越多。我最终设计了六到七层深的设计,如果我使用从一层流到另一层的键,我可能最终会在连接中使用n^2 个键。

尝试说服我的 SQL 开发人员将所有这些用于单个查询,他们会非常喜欢我

我保持简单。

于 2010-03-09T16:58:43.427 回答