我对DB的接触有限,只是作为应用程序程序员使用过DB。我想知道关于聚集和非聚集索引。 我在谷歌上搜索了一下,我发现:

A clustered index is a special type of index that reorders the way records in the table are physically stored. Therefore table can have only one clustered index. The leaf nodes of a clustered index contain the data pages. A nonclustered index is a special type of index in which the logical order of the index does not match the physical stored order of the rows on disk. The leaf node of a nonclustered index does not consist of the data pages. Instead, the leaf nodes contain index rows.

我在SO中发现的是聚集索引和非聚集索引之间的区别是什么?

有人能用通俗易懂的语言解释一下吗?


当前回答

使用聚集索引,行按与索引相同的顺序物理存储在磁盘上。因此,只能有一个聚集索引。

对于非聚集索引,有第二个列表,其中包含指向物理行的指针。您可以有许多非聚集索引,尽管每个新索引都会增加写入新记录的时间。

如果想要返回所有列,从聚集索引中读取通常更快。您不必先访问索引,再访问表。

如果需要重新排列数据,则写入具有聚集索引的表可能会较慢。

其他回答

使用聚集索引,行按与索引相同的顺序物理存储在磁盘上。因此,只能有一个聚集索引。

对于非聚集索引,有第二个列表,其中包含指向物理行的指针。您可以有许多非聚集索引,尽管每个新索引都会增加写入新记录的时间。

如果想要返回所有列,从聚集索引中读取通常更快。您不必先访问索引,再访问表。

如果需要重新排列数据,则写入具有聚集索引的表可能会较慢。

让我提供一个关于“聚类索引”的教科书定义,摘自Database Systems: The Complete Book中的15.6.1:

我们也可以称之为聚类索引,它是一个或多个属性上的索引,这样所有具有该索引的搜索键的固定值的元组都出现在能够容纳它们的大致尽可能少的块上。

为了理解定义,让我们看一下教科书提供的例子15.10:

A relation R(a,b) that is sorted on attribute a and stored in that order, packed into blocks, is surely clusterd. An index on a is a clustering index, since for a given a-value a1, all the tuples with that value for a are consecutive. They thus appear packed into blocks, execept possibly for the first and last blocks that contain a-value a1, as suggested in Fig.15.14. However, an index on b is unlikely to be clustering, since the tuples with a fixed b-value will be spread all over the file unless the values of a and b are very closely correlated.

注意,该定义并没有强制数据块在磁盘上必须是连续的;它只是说带搜索键的元组被打包到尽可能少的数据块中。

A related concept is clustered relation. A relation is "clustered" if its tuples are packed into roughly as few blocks as can possibly hold those tuples. In other words, from a disk block perspective, if it contains tuples from different relations, then those relations cannot be clustered (i.e., there is a more packed way to store such relation by swapping the tuples of that relation from other disk blocks with the tuples the doesn't belong to the relation in the current disk block). Clearly, R(a,b) in example above is clustered.

为了将两个概念连接在一起,聚类关系可以具有聚类索引和非聚类索引。但是,对于非聚类关系,除非索引构建在关系的主键之上,否则不可能实现聚类索引。

“集群”作为一个词在数据库存储端的所有抽象级别(三个抽象级别:元组、块、文件)上被大量发送。一个叫做“集群文件”的概念,它描述了一个文件(一组块(一个或多个磁盘块)的抽象)是否包含来自一个关系或不同关系的元组。它与集群索引概念无关,因为它是在文件级别上。

然而,一些教材喜欢根据聚类文件定义定义聚类索引。这两种类型的定义在集群关系级别上是相同的,无论它们是根据数据磁盘块还是文件来定义集群关系。从这段的链接中,

在以下情况下,文件属性A上的索引称为聚类索引:属性值A = A的所有元组按顺序(=连续)存储在数据文件中

连续存储元组就相当于说“元组被打包到尽可能少的块中,以容纳这些元组”(一个是文件,另一个是磁盘)。这是因为连续存储元组是实现“将这些元组打包到尽可能少的块中”的方法。

聚集索引

聚集索引根据表或视图中的键值对数据行进行排序和存储。这些是包含在索引定义中的列。每个表只能有一个聚集索引,因为数据行本身只能按一种顺序排序。

只有当表中包含聚集索引时,表中的数据行才会按排序顺序存储。当一个表具有聚集索引时,这个表称为聚集表。如果表没有聚集索引,则其数据行存储在称为堆的无序结构中。

非聚集

Nonclustered indexes have a structure separate from the data rows. A nonclustered index contains the nonclustered index key values and each key value entry has a pointer to the data row that contains the key value. The pointer from an index row in a nonclustered index to a data row is called a row locator. The structure of the row locator depends on whether the data pages are stored in a heap or a clustered table. For a heap, a row locator is a pointer to the row. For a clustered table, the row locator is the clustered index key.

可以将非键列添加到非聚集索引的叶级,以绕过现有的索引键限制,并执行完全覆盖的索引查询。有关更多信息,请参见创建包含列的索引。有关索引键限制的详细信息,请参见SQL Server最大容量规格。

参考:https://learn.microsoft.com/en-us/sql/relational-databases/indexes/clustered-and-nonclustered-indexes-described

一个非常简单的、非技术性的经验法则是,聚集索引通常用于主键(或者至少是唯一的列),而非聚集索引用于其他情况(可能是外键)。实际上,SQL Server默认会在你的主键列上创建一个聚集索引。正如您将了解到的,聚类索引与数据在磁盘上物理排序的方式有关,这意味着对于大多数情况,它是一个很好的全面选择。

我知道这是一个非常古老的问题,但我想我可以提供一个类比来帮助说明上面的答案。

聚集索引

If you walk into a public library, you will find that the books are all arranged in a particular order (most likely the Dewey Decimal System, or DDS). This corresponds to the "clustered index" of the books. If the DDS# for the book you want was 005.7565 F736s, you would start by locating the row of bookshelves that is labeled 001-099 or something like that. (This endcap sign at the end of the stack corresponds to an "intermediate node" in the index.) Eventually you would drill down to the specific shelf labelled 005.7450 - 005.7600, then you would scan until you found the book with the specified DDS#, and at that point you have found your book.

非聚簇索引

But if you didn't come into the library with the DDS# of your book memorized, then you would need a second index to assist you. In the olden days you would find at the front of the library a wonderful bureau of drawers known as the "Card Catalog". In it were thousands of 3x5 cards -- one for each book, sorted in alphabetical order (by title, perhaps). This corresponds to the "non-clustered index". These card catalogs were organized in a hierarchical structure, so that each drawer would be labeled with the range of cards it contained (Ka - Kl, for example; i.e., the "intermediate node"). Once again, you would drill in until you found your book, but in this case, once you have found it (i.e, the "leaf node"), you don't have the book itself, but just a card with an index number (the DDS#) with which you could find the actual book in the clustered index.

当然,没有什么能阻止图书管理员复印所有的卡片,并将它们按不同的顺序分类在一个单独的卡片目录中。(通常至少有两个这样的目录:一个按作者姓名排序,另一个按标题排序。)原则上,您可以拥有任意数量的这些“非聚集”索引。