clustered index将实际数据行存储在索引的叶级别。回到上面的例子,这意味着与主键值123相关联的整行数据将存储在该叶节点中。
问题 - 如果主键不存在,我将Name
列设置为聚簇索引。在这种情况下,上述陈述会变得矛盾吗?
答案 0 :(得分:18)
不 - 为什么?
聚簇索引将仍然将实际数据页存储在其叶级别(最初)按name
列进行物理排序。
叶级上方的索引导航结构将包含所有行的name
列值。
主键是逻辑结构,旨在唯一标识表中的每一行。这就是它必须是唯一且非空的原因。
群集索引是物理构造,它将(最初)通过群集密钥对您的数据进行物理排序,并相应地排列SQL Server页面。
在SQL Server中,主要使用默认作为群集密钥,两者不必一起 - 也不必与另一个存在。您可以拥有包含非群集主键的表或没有主键的群集表。两者都是可能的。是否明智是另一种讨论 - 但这在技术上是可行的。
更新:如果您的主键是您的群集密钥,则保证唯一性(因为主键必须是唯一的)。如果您选择的某些列不是主键作为您的群集键,并且该列不保证唯一性,则SQL Server将在幕后为这些重复值添加一个4字节(INT)唯一程序列他们独特。因此,您的Smith的聚集索引导航结构中可能包含Smith
,Smith1
,Smith2
等。
请参阅:
答案 1 :(得分:3)
如果聚簇索引不是唯一的,则SQL Server会创建一个4字节的唯一符,并将其添加到聚簇索引值。仅当聚簇索引值重复时才添加唯一符,而不是所有聚簇索引值。 所有非聚簇索引都将在其叶级别中包含此值,并且非唯一非聚簇索引也将在其非叶级别条目中具有此唯一值,作为书签的一部分。
答案 2 :(得分:1)
主键和唯一索引(或约束)之间的区别在于主键列中不允许Null值。没有必要在表上使用主键,但它使外部应用程序更容易编辑表中的行,即便如此,对于大多数外部应用程序来说,它并不是必需的。
在表现方面,这没什么变化。重要的是索引的存在与否(无论是否唯一,是否为聚簇,是否为空值),主键本质上只是一个没有空值的唯一索引。
对于聚簇索引,该列不需要是唯一的和/或不需要null。具有重复项和空值的列可用于创建聚簇索引。
对于外键,它必须引用具有唯一索引的列,但不一定是主键或没有空值。引用不是主键的列并且允许空值很长,因为它上面有唯一索引是完全合法的。请注意,因为它上面必须有唯一索引,所以此列不能包含多个空值。
外键列本身(外表上的列)没有限制,但性能方面,设置索引通常是件好事。