连接表的主键/聚簇键

时间:2010-03-09 16:32:33

标签: sql clustered-index junction-table

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

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

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

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

  • 或者我应该放置外键对的主键(ProductID和OrderID)并在ID列上放置非聚集索引(如果需要的话)

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

4 个答案:

答案 0 :(得分:5)

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

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

  1. 首先了解您使用代理键ID的原因和方式 首先;这往往会决定你如何索引它。一世 假设您正在使用代理键,因为您正在使用某些代码键 适用于单列键的框架。如果没有 具体设计原因,然后对于一个连接表,我简化了 问题,只是删除自动编号ID,如果它没有带来其他 效益。主键变为(ProductID,OrderID)。如果不, 你需要至少确保你的索引(ProductID, OrderID)元组是唯一保持数据完整性的。

  2. 群集索引适用于顺序扫描/连接时 查询需要的结果与索引的排序顺序相同。 所以,看看你的访问模式,找出你的密钥 将进行顺序,多行选择/扫描,以及通过它 关键,你将做随机,单独的行访问,并创建 您将扫描最多的密钥上的聚簇索引,以及非聚集的密钥 您将用于随机访问的密钥的密钥索引。你必须 选择其中一个,因为你不能将它们都聚集在一起。

  3. 注意:如果您的要求存在冲突,则可以采用一种技巧(“技巧”)。如果在索引中找到查询中的所有列,则该索引是数据库引擎用于满足查询要求的候选表。您可以使用此事实以多个订单存储数据,即使它们彼此冲突也是如此。请注意为索引添加更多字段的优缺点,并在了解将要处理的查询的性质和频率后做出有意识的决定。

答案 1 :(得分:3)

正确且唯一的答案是:

  • 主键为('orderid' , 'productid')
  • ('productid' , 'orderid')
  • 上的另一个索引
  • 可以群集,但默认情况下是PK

由于:

  • 您不需要仅orderidproductid上的索引:优化工具将使用其中一个索引
  • 您最有可能以“两种”方式使用表格
  • 您不需要代理键,因为您已在链接表上拥有它们。所以第三列浪费了空间。

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:0)

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

我这样做的原因是因为我对数据进行规范化的次数越多,我在连接中使用的密钥就越多。我最终设计的深度为6到7级,如果我使用从一个级别流到另一个级别的密钥,我可能最终会在连接中使用 n ^ 2 键。

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

我保持简单。