【问题标题】:Clustered Indexes without Primary key没有主键的聚集索引
【发布时间】:2012-06-03 16:36:54
【问题描述】:

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

问题 - 如果主键不存在并且我将Name 列设置为聚集索引。这样的话,上面的说法会不会矛盾?

【问题讨论】:

  • 我相信非唯一的集群键也将获得最多 4 个字节的唯一数据。因此,您的姓名列不必是唯一的。
  • 考虑在DBA.SE 上提出这样的问题。我们有非常有针对性的受众,他们很乐意回答此类问题。

标签: sql-server sql-server-2008 sql-server-2005 clustered-index


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    不 - 为什么?

    聚集索引仍然在其叶级存储实际数据页,(最初)按name 列物理排序。

    叶级上方的索引导航结构将包含所有行的name 列值。

    总的来说:没有任何变化。

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

    聚类索引是一种物理构造,它将(最初)按聚类键对数据进行物理排序,并相应地排列 SQL Server 页面。

    虽然在 SQL Server 中,默认情况下使用主键作为集群键,但两者不必同时存在 - 也不必与另一个同时存在。您可以拥有一个具有非聚集主键的表,也可以拥有一个没有主键的聚集表。两者都是可能的。这样做是否明智是另一个讨论 - 但在技术上是可行的。

    更新:如果您的主键是集群键,则保证唯一性(因为主键必须是唯一的)。如果您选择某个不是主键的列作为集群键,并且该列不保证唯一性,SQL Server 将在幕后向这些重复值添加一个 4 字节 (INT) 唯一性列以生成他们独一无二。因此,您的 Smith's 的聚集索引导航结构中可能有 SmithSmith1Smith2 等等。

    见:

    【讨论】:

    • 那么在这种情况下如何定义指向实际数据行的行定位器?我的意思是名字可以重复。对吗?
    • 您能分享说明这一事实的链接吗?谢谢。这是我的最后一条评论。
    • 可以分享一些知识here 吗?
    • 嘿!批量插入呢?插入只有聚集索引的表或插入主键的表有什么区别吗?
    【解决方案3】:

    主键和唯一索引(或约束)之间的区别在于主键列中不允许 Null 值。表上不需要主键,但它使外部应用程序更容易编辑表中的行,即使这样,对于大多数外部应用程序来说,它也不是必需的。

    就性能而言,这没有任何改变。重要的是索引的存在与否(唯一与否、是否聚集以及是否具有空值),而主键本质上只是一个没有空值的唯一索引。

    对于聚集索引,列不需要是唯一的和/或没有空值。具有重复值和空值的列适用于创建聚集索引。

    对于外键,它必须引用具有唯一索引的列,但不一定是主键或没有空值。引用不是主键的列是完全合法的,只要它有唯一索引就允许空值。请注意,因为它必须有一个唯一索引,所以该列不能有多个空值。

    外键列本身(外表上的列)没有限制,但在性能方面,在其上设置索引通常是一件好事。

    【讨论】:

    • 如果用于聚集索引的列不是唯一的,SQL Server 将使它唯一 - 通过添加一个 4 字节的唯一符。这是您需要注意的额外开销。您可以使用非唯一列 - 我认为一般来说这样做不是一个好主意。
    猜你喜欢
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多