无主键的聚集索引

8

一个聚集索引将实际数据行存储在索引的叶级别。回到上面的例子,这意味着与主键值123关联的整个数据行将存储在该叶节点中。

enter image description here

问题 - 如果主键不存在,我将Name列设置为聚集索引。在这种情况下,上述语句是否会变得矛盾?


1
我相信非唯一聚集键也会获得高达4个字节的唯一数据。因此,您的姓名列不必是唯一的。 - ta.speot.is
1
考虑在DBA.SE上提出这样的问题。我们有一个非常有针对性的受众群体,他们很乐意回答这样的问题。 - Nick Chammas
3个回答

23

不需要,为什么?

聚簇索引仍将在其叶节点上存储实际数据页面,并按name列进行物理排序。索引导航结构在叶子级别以上将包含所有行的name列值。

所以总体而言:没有改变。

主键是一个逻辑结构,旨在唯一标识表中的每一行。这就是为什么它必须是唯一且非空的原因。

聚簇索引是一个物理结构,最初会根据聚簇键对数据进行物理排序并相应地排列SQL Server页面。

虽然在SQL Server中,默认情况下使用主键作为聚簇键,但两者不必合并 - 也不必同时存在。您可以拥有具有非聚集主键的表,或者没有主键的聚集表。两者都是可能的。是否明智拥有它是另一个讨论问题 - 但从技术上讲是可能的。

更新: 如果您的主键是聚簇键,则保证唯一(因为主键必须是唯一的)。如果您选择的某个列不是主键而作为聚簇键,并且该列不能保证唯一性,则SQL Server将在幕后添加一个4字节(INT)唯一标识符列以使那些重复值唯一。因此,对于您的Smith,您可能会在聚集索引导航结构中有SmithSmith1Smith2等。

参见:


那么在这种情况下,指向实际数据行的行定位符是如何定义的呢?我的意思是,名称可能会重复,对吧? - Nilish
你能分享一下证明这个事实的链接吗?谢谢。这是我的最后一条评论。 - Nilish
你能在这里分享一些知识吗?链接 - Nilish
嘿!批量插入怎么样?在仅有聚集索引的表中插入和在具有主键的表中插入是否有区别? - Dmitriy Dokshin

3
如果聚集索引不是唯一的,SQL Server 会创建一个4字节的唯一标识符并将其添加到聚集索引值中。唯一标识符仅在聚集索引值重复时添加,而不是针对所有聚集索引值添加。 所有非聚集索引都将在其叶级别包含此值,非唯一的非聚集索引也将在其非叶级别条目中包含此唯一标识符值作为书签的一部分。

2
主键和唯一索引(或约束)之间的区别在于主键列不允许空值。表格上没有必要设置主键,但对于外部应用程序编辑表格中的行会更加方便,即使对于大多数外部应用程序来说这并非必需。
在性能方面,这并没有改变什么。重要的是存在或不存在索引(无论是唯一的还是不唯一的,聚集的还是非聚集的,以及是否带有null值),而主键本质上只是另一个没有null值的唯一索引。
对于聚集索引,该列不需要是唯一的和/或没有null值。具有重复值和null值的列可用于创建聚集索引。
对于外键,它必须引用一个具有唯一索引的列,但不一定是主键或没有null值的列。只要有唯一索引,引用非主键且允许null值的列是完全合法的。请注意,因为必须在其上有唯一索引,所以该列不能具有多个null值。
外键列本身(外部表格上的列)没有限制,但从性能角度考虑,在其上设置索引通常是一件好事。

1
如果用于聚集索引的列不是唯一的,则SQL Server将通过添加4字节的唯一标识符使其唯一。这是您需要注意的额外开销。您可以使用非唯一列 - 我认为通常不是一个很好的主意。 - marc_s

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接