为什么主键应该是聚簇索引?

时间:2017-08-01 13:27:10

标签: sql sql-server tsql database-design relational-database

据我所知,表中的唯一一个聚簇索引定义了行的物理排序方式,例如:在表格中

==================================
            Contacts
==================================
 ID (P.K.) | FirstName | LastName
==================================
    1      | 'Donald'  | 'Trump'
----------------------------------
    2      | 'Crooked' | 'Hillary'
----------------------------------
    3      | 'Crazy'   | 'Bernie'

意味着3条记录按上面显示的顺序物理存储。但我不明白为什么这有用。也许在自动递增的主键没有间隙的情况下,如上例所示,这有助于查询,如

SELECT FirstName+LastName FROM Contacts WHERE ID=2

因为物理排序允许在ID=2时间内O(1)进行查找(就像通过索引获取数组的元素一样)。但如果表格像

那样
==================================
            Contacts
==================================
 ID (P.K.) | FirstName | LastName
==================================
    1      | 'Donald'  | 'Trump'
----------------------------------
    89     | 'Crooked' | 'Hillary'
----------------------------------
    12309  | 'Crazy'   | 'Bernie'

然后物理排序 不允许 O(1)查找;我们能做的最好的事情是O(log(n))

那么为什么我们要主键来定义行的物理排序?

1 个答案:

答案 0 :(得分:2)

SQL Server中聚簇索引的重要性不是“物理排序”,而是行数据在B树的叶页中可用,从而避免了额外的查找。子树成本与非聚集B树索引相同:O(log n)。

物理排序实际上是聚集索引中实际发生的事情的抽象。 extents中的页面存储在分配顺序中,不一定按聚集索引键排序。索引键排序保持在索引分配映射和指针链中,由此每个页面指向下一个(不一定是相邻的)页面。在页面内,行也按分配顺序编写和存储,而不是按键顺序,除非页面拆分,否则顺序不会改变。重建索引时,页面本身会被占用,但重建之间不会自动维护顺序。

主键不一定是聚簇索引的最佳选择。这两个概念彼此正交。