什么是索引,非聚集索引可以是非唯一的吗?

Posted

技术标签:

【中文标题】什么是索引,非聚集索引可以是非唯一的吗?【英文标题】:what is index and can non-clustered index be non-unique? 【发布时间】:2011-04-17 14:04:50 【问题描述】:

我的问题 [1] 的子问题:

(我能找到的)(MS SQL Server)索引的所有定义都是模棱两可的,所有基于它的解释都使用未定义或定义不明确的术语来叙述某些事情。 index的解释是什么?

例如,wiki 中最常见的索引定义(http://en.wikipedia.org/wiki/Index_(database)):

1) “数据库索引是一种数据结构,它以降低写入速度和增加存储空间为代价提高对数据库表的数据检索操作的速度。可以使用数据库表的一个或多个列创建索引。 ..” 2) "SQL server 默认在主键上创建聚集索引[1]。数据以随机顺序出现,但逻辑顺序由索引指定。数据行可能随机分布在整个表中. 非聚集索引树包含排序顺序的索引键,索引的叶级包含指向页的指针和数据页中的行号"

嗯,这是模棱两可的。在索引下可以理解:

1) 一个有序的数据结构,一棵树,包含中间节点和叶子节点; 2) 叶节点数据包含索引列中的值+“指向页面的指针和数据页面中的行号”

考虑到 2),非聚集索引可以是非唯一的吗?或者,甚至是 1) ? 在我看来不是这样...

但是 TSQL 是否意味着存在非唯一非聚集索引?

如果是,那么“CREATE INDEX (Transact-SQL)”[2] 中的非聚集索引可以理解什么,以及 UNIQUE 参数适用于什么?

是吗:

3) 包含索引列值的叶节点数据?即像2)但没有指针+行号)?

如果是 3),那么问题 1) 又出现了 - 为什么要对“索引”中的真实数据的副本应用约束,而不是在原位的真实数据?


更新: 对真实数据行的书签(指针+行号)不是唯一的(唯一标识行)吗? 这个书签不是构成索引的一部分,从而使索引唯一吗? 你能给我索引的定义,而不是解释如何使用它 UNDEFINED 吗?后半部分我已经知道(或者可以自己阅读)。


[1] “创建 INDEX 的唯一参数 - 有什么用?”UNIQUE argument for INDEX creation - what's for?

[2] [创建索引 (Transact-SQL)]http://msdn.microsoft.com/en-us/library/ms188783.aspx

【问题讨论】:

不清楚您想知道什么...您是对 INDEX 的一般定义感兴趣,还是对使用它们感兴趣? 是的,只是定义。关于索引非唯一性的问题是修辞。它的应用和实现是众所周知的 【参考方案1】:

索引是一种旨在优化查询大型数据集的数据结构。因此,目前没有任何关于是否有任何东西是独一无二的声明。

你绝对可以有非唯一的非聚集索引 - 你怎么能索引姓氏,名字?这永远不会是独一无二的(例如在 Facebook 上.....)

您可以将索引定义为唯一的 - 这只是对其添加了额外的检查,即不允许重复值。如果您要将 (lastname, firstname) 索引设为 UNIQUE,那么第二个在您的网站上注册的 Brad Pitt 就无法这样做,因为该唯一索引会拒绝他的数据。

一个例外是任何给定表上的主键。主键是用于唯一且准确地标识数据库中每一行的逻辑标识符。因此,它必须在所有行中都是唯一的,并且不能包含任何 NULL 值。

SQL Server 中的聚集索引 的特殊之处在于它们确实在其叶节点中包含实际数据。到目前为止没有任何限制 - 但是:聚集索引也用于唯一定位(物理定位)数据库中的数据,因此,聚集索引必须是唯一的 - 它必须是能够区分布拉德皮特 #1 和布拉德皮特 #2。如果您不注意并为聚集索引提供一组唯一的列,SQL Server 将为那些不唯一的行添加一个“uniquefier”(一个 4 字节的 INT),例如你会得到 BradPitt001 和 BradPitt002(或类似的东西)。

聚集索引用作指向 SQL Server 表中实际数据行的“指针”,因此它也包含在每个非聚集索引中。因此,您在 (lastname, firstname) 上的非聚集、非唯一索引不仅包含这两个字段,而且实际上,它还包含该表上的 clustered key - 这就是为什么重要SQL Server 表上的聚簇键小、稳定且唯一 - 通常是 INT。

因此,您在 (lastname, firstname) 上的非聚集索引将真正具有 (lastname, firstname, personID) 并且将具有 (Pitt, Brad, 10176)(Pitt, Brad, 17665) 等条目。当您在非聚集索引中搜索“Brad Pitt”时,SQL Server 现在将找到这两个条目,并且对于这两个条目,它都有一个“物理指针”,指向哪里可以找到这两个家伙的其余数据,所以如果您要求的不仅仅是名字和姓氏,SQL Server 现在可以为两个 Brad Pitt 条目中的每一个获取整行,并为您提供查询所需的数据。

【讨论】:

“你绝对可以有非唯一的非聚集索引 - 你怎么能索引姓氏,名字??这永远不会是唯一的”——通过将表的键附加到末尾列列表,例如CREATE UNIQUE CLUSTERED INDEX uq__Persons ON Persons (lastname, firstname, personID); ...但你不是自己说的吗?我很困惑。 @onedaywhen:从您的角度来看,该索引是非唯一的 - 您绝对可以有多个具有相同名字和姓氏的条目。 在内部,对于 SQL Server,它会将集群键添加到索引条目以允许数据查找。所以 YOU 看到了一个非唯一索引 - 而 SQL Server 会向您的索引条目添加一些唯一数据(但您并不关心,您没有看到,您没有注意到那个.....) 谢谢但忽略:尽管引用了你,但我没有正确阅读你最初所说的内容;现在我有了,这很有意义。道歉。 如果我是布拉德皮特,我会创建具有唯一名/姓限制的 facebook,这样就不会有另一个布拉德皮特。 我认为 Facebook 在 lastname 上创建索引已经有点过了 :)【参考方案2】:

索引的定义是***定义的第一部分“数据库索引是一种以降低写入速度和增加存储空间为代价提高对数据库表的数据检索操作速度的数据结构。”

然后你有唯一索引,作为一种特殊的索引,它确保索引值是唯一的。

如何实现...取决于 DBMS。 但它不会改变索引或唯一索引的定义。

作为一个实现细节,MS SQL 允许非集群(通常的类型,它是一棵树,其指针指向单独空间中的实际行内容,您编号为 2。)和集群(其中行存储在索引,根据您编号为 1.) 的索引值。

因此,非唯一非聚集索引只是(概念上)一棵值树,每个值都有一组指向包含该值的表行的指针。

【讨论】:

以上是关于什么是索引,非聚集索引可以是非唯一的吗?的主要内容,如果未能解决你的问题,请参考以下文章

sqlserver的索引

SQL SERVER数据库 唯一索引 非唯一索引 聚集索引 非聚集索引 之间区别

聚集索引和唯一索引的区别是啥?

数据库优化

数据库怎样创建一个唯一聚集索引

聚集索引非聚集索引