假设我们有一个Product表,Order表和一个(联结表)ProductOrder。
ProductOrder将具有ProductID和OrderID 在我们的大多数系统中,这些表还有一个名为ID的自动编号列。
放置主键(以及群集密钥)的最佳做法是什么?
我应该保留ID字段的主键并为外键对(ProductID和OrderID)创建非聚集索引
或者我应该放置外键对的主键(ProductID和OrderID)并在ID列上放置非聚集索引(如果需要的话)
或者......(你们其中一个人的聪明评论:))
答案 0 :(得分:5)
我知道这些话可能让你感到畏缩,但“这取决于。”
您很可能希望订单基于ProductID和/或OrderId而不是autonumber(代理)列,因为自动编号在您的数据库中没有自然含义。您可能希望通过与父表相同的字段来对连接表进行排序。
首先了解您使用代理键ID的原因和方式 首先;这往往会决定你如何索引它。一世 假设您正在使用代理键,因为您正在使用某些代码键 适用于单列键的框架。如果没有 具体设计原因,然后对于一个连接表,我简化了 问题,只是删除自动编号ID,如果它没有带来其他 效益。主键变为(ProductID,OrderID)。如果不, 你需要至少确保你的索引(ProductID, OrderID)元组是唯一保持数据完整性的。
群集索引适用于顺序扫描/连接时 查询需要的结果与索引的排序顺序相同。 所以,看看你的访问模式,找出你的密钥 将进行顺序,多行选择/扫描,以及通过它 关键,你将做随机,单独的行访问,并创建 您将扫描最多的密钥上的聚簇索引,以及非聚集的密钥 您将用于随机访问的密钥的密钥索引。你必须 选择其中一个,因为你不能将它们都聚集在一起。
注意:如果您的要求存在冲突,则可以采用一种技巧(“技巧”)。如果在索引中找到查询中的所有列,则该索引是数据库引擎用于满足查询要求的候选表。您可以使用此事实以多个订单存储数据,即使它们彼此冲突也是如此。请注意为索引添加更多字段的优缺点,并在了解将要处理的查询的性质和频率后做出有意识的决定。
答案 1 :(得分:3)
正确且唯一的答案是:
('orderid' , 'productid')
('productid' , 'orderid')
由于:
orderid
或productid
上的索引:优化工具将使用其中一个索引答案 2 :(得分:1)
这似乎适用于将添加许多订单的动态系统。因此聚集索引应该在您的自动编号列上。
您可以将索引设为主键,并在列对上添加另一个唯一索引。或者,您可以将这对列作为主键(但非聚集键)。
使用主键或唯一索引键的选择取决于您。但我会确保群集的那个是您的自动编号列。
答案 3 :(得分:0)
我的偏好始终是为主键创建自动编号。然后我在两个外键上创建一个唯一索引,这样它们就不会重复了。
我这样做的原因是因为我对数据进行规范化的次数越多,我在连接中使用的密钥就越多。我最终设计的深度为6到7级,如果我使用从一个级别流到另一个级别的密钥,我可能最终会在连接中使用 n ^ 2 键。
尝试说服我的SQL开发人员将所有这些用于单个查询,他们非常喜欢我。
我保持简单。