具有聚簇唯一索引的非可空列。为什么需要主键?

时间:2013-03-31 15:54:01

标签: sql-server sql-server-2008 indexing unique-constraint clustered-index

在SQL Server中,我有一个不可为空的列,上面有唯一聚簇索引。 如果我将此列设为主键,则会自动创建完全相同的索引 该列被识别为主键。

我理解抽象/语义差异。

(主键标识实体,而具有此索引的任何其他列可能不标识实体 例如,一个人可以拥有唯一的,不可为空的......但可以更改的电子邮件字段

但令我困扰的是,当涉及到数据库引擎本身时,实际差异

如果我只是创建一个Id列,使其不可为空,为它创建一个唯一的聚簇索引,使其成为身份增量,但没有主键约束,会发生什么?

主键约束在什么情况下发挥作用?

(在问这个问题之前,我已经看了很多相关的问题,但我看到的所有答案都以抽象/理论解释结束了。)

2 个答案:

答案 0 :(得分:5)

真的没有什么不同。您指定PRIMARY KEY来传达您的意图,而不是引擎以不同的方式执行任何操作。在构造查询计划时,优化器仍将使用其所有属性的唯一性,并且仍将对其所有属性使用聚集索引,无论您是否在技术上将其创建为PRIMARY KEY。创建FOREIGN KEY时,您仍然可以引用指定为唯一的列(已集群或未集群)。区别仅在于元数据(sys.indexes.is_primary_key)和SSMS'对您的表示(哦,您可以在NULLable列上创建唯一的聚簇索引,但您无法创建{{1}在那一栏上。)

实际上,在许多情况下,您希望将聚集索引与PRIMARY KEY完全分开。例如,如果您有一个表是PK是GUID的表,并且您通常对该表运行日期范围查询,那么最好不要将PK设置为非群集并且在自然增加的列上具有聚簇索引(日期时间列) - 两者都可以最大限度地减少重插入活动的页面拆分,也可以最大限度地协助日期范围查询。非聚集索引非常适合查找单个GUID。 (我想提一下,因为很多人认为主键必须聚集在一起。不正确。)

另外有趣的是,如果您创建PRIMARY KEY约束,然后使用PRIMARY KEY创建具有相同名称的唯一聚簇索引,DROP_EXISTING列仍将是{{1}并且对象资源管理器仍将在is_primary_key下显示索引名称。

答案 1 :(得分:1)

这是一个场景 - 数据映射框架的许多代码查看数据库元数据(主键,外键等)以确定代码的执行方式。例如Hibernate requires a primary key

典型情况可能是为更新生成where子句。