背景
对于我们支持并编写 SQL 报告的主要供应商提供的产品,我无法理解数据库中的主键选择。一些不相关的细节已更改。
每个主表都有一个唯一的自动编号“内部 ID”字段,但这个字段并不总是用作主键。
我的问题
特别是,我对订单和订单行表的主键选择感到困惑:
- 组织 PK(
organization_internal_id
) - 订单表 PK
(organization_internal_id, order_internal_id)
- 订单行 PK
(order_internal_id, organization_internal_id)
每个订单和订单行表都有一个 internal_id
也唯一标识它们的行。每个表都使用聚集索引的主键。仅内部 ID 就有非聚集索引。
为什么不将内部 ID 设为主键,而是为每个 ID 设置一个单独的唯一聚集索引(就像现在这样)?
一种可能
我能想到的一件事是设计者不知道主键和聚簇索引之间的区别,所以使用一个奇怪的 PK 来获得他们想要的聚簇索引。公平地说,订单行通常引用订单进行访问,并且没有低于行级别的详细信息来引用 order_line_internal_id
。
查询效率
订单的聚集索引的一个问题是它鼓励 QO 在将许多订单和订单行连接在一起时使用扫描和散列连接(不幸的是,这种情况太常见了,即使我只使用了 5%最后的数据)。选择的行太多,无法在订单行表中循环查找(尽管强制这样做有时会有所帮助),并且使组织成为订单键的第一部分可以防止合并连接在没有排序的情况下工作。
更多详情
- 这些内部 ID 仅用于连接其他表;对于系统外部的引用或向用户显示的引用,有单独的外部 ID。设计师喜欢这些自动编号人工键。
- 数据库在 MS SQL Server 2000 上
- 我认为供应商过去支持 Oracle 作为数据库
- 订单表有 1M 行 ~5MB
- 订单行表有 30M 行 ~1GB
- 整个数据库约为 100GB
最佳答案
另外,考虑到内部 ID 可能是该公司产品中使用的 ORM 所必需的,该数据库随附于此数据库。
关于sql-server - 了解奇怪的数据库 key 设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1272245/