1

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

我理解抽象/语义的区别。

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

但困扰我的是数据库引擎本身的实际差异

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

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

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

4

2 回答 2

5

真的没有什么不同。您指定PRIMARY KEY传达您的意图,而不是让引擎做任何不同的事情。在构建查询计划时,优化器仍将对其所有属性使用唯一性,并且仍将对其所有属性使用聚集索引,无论您是否在技术上将其创建为PRIMARY KEY. 创建 时FOREIGN KEY,您仍然可以引用指定为唯一的列(集群或非集群)。区别仅在于元sys.indexes.is_primary_key数据PRIMARY KEY

事实上,在很多情况下,您希望将聚集索引与PRIMARY KEY. 例如,如果您有一个 PK 是 GUID 的表,并且您通常针对该表运行日期范围查询,那么您最好让 PK 是非聚集的并且在自然增加的列上具有聚集索引( datetime 列) - 既可以最大程度地减少大量插入活动的页面拆分,也可以最好地协助日期范围查询。非聚集索引非常适合查找单个 GUID。(我想提一下,因为很多人认为主键必须是集群的。不是真的。)

还需要注意的是,如果您创建一个PRIMARY KEY约束,然后使用创建一个具有相同名称的唯一聚集索引,则DROP_EXISTINGis_primary_key列仍将是1,并且对象资源管理器仍将在 下显示索引名称Keys

于 2013-03-31T15:59:34.940 回答
1

这是一种场景 - 数据映射框架的大量代码查看数据库元数据(主键、外键等是什么)以确定代码的执行方式。例如Hibernate 需要一个主键

一个典型的场景可能是where为更新生成一个子句。

于 2013-03-31T16:03:09.447 回答