我正在部署一个连接Items
到的映射表ItemGroups
尽管 anItem
只会出现在单个中,但ItemGroup
请先接受先验Items
,但在我的用例中,将列附加到表中是不合适的。
因此,将创建一个包含两列的表:
ItemId INT NOT NULL
ItemGroupId INT NOT NULL
为这张表制作 CI 和 PK 很诱人ItemId
……但这合适吗?我认为它作为主键是有意义的,但由于它既不是顺序的也不是永久增加的,因此作为 CI 似乎是不正确的。我永远不会执行范围查询ItemId
...但是,仅用于顺序 CI 的代理键似乎也不合适。
我同样有可能执行:
SELECT [ItemGroupId] FROM [Table] WHERE [ItemId] = @id
SELECT [ItemId] FROM [Table] WHERE [ItemGroupId] = @id
据我所知,我有几个选择:
ItemId
既是CI又是PKItemId
不是CI,而是PKItemId
既不是 CI 也不是 PK 但有UNIQUE
约束ItemId, ItemGroupId
组合成为 PK 并ItemId
具有UNIQUE
约束
选项 5:
(ItemGroupId, ItemId)
(注意顺序)作为主键(集群)ItemId
虽然搜索依据
ItemId
不利于范围扫描(还?),但搜索依据ItemGroupId
是 1,这使其成为聚簇索引键的前导列的一个很好的候选者。我对这种类型的表的正常设计是索引这两种组合,即,
(Column1, Column2)
所以(Column2, Column1)
我(和其他人)永远不必考虑它是否正确索引;它只是。在您的情况下,一个组合是退化的,因此只有一列进入键,但非键列仍被索引覆盖,因为它是聚簇索引键的一部分。当然,如果涉及非键列,情况会变得更加复杂,但这超出了您在此处询问的范围。在这种情况下,虽然您可以使用唯一约束翻转主键,但我特意选择了 2 列主键,因为它在表的生命周期内会更加稳定。这对您作为 DBA(一个词:复制)和开发人员(如果主键定义更改可能需要大量代码更新)都有利。
1这里的术语可能有问题。按单个搜索
ItemId
将返回 0 或 1 行;通过单个ItemGroupId
(不完整的键)搜索返回 >= 0 行,搜索 + 扫描也是如此(它将在执行计划中显示为索引搜索)。显然这不是对 multipleItemGroupId
s 的“范围扫描”。ItemId
这个想法是将每个 s物理组合在一起(并在本例中排序)ItemGroupId
。我希望这很清楚。