【发布时间】:2017-08-01 13:27:10
【问题描述】:
我了解表上的唯一一个聚集索引定义了行的物理排序方式,例如在表中
==================================
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))。
那么为什么我们需要主键来定义行的物理顺序呢?
【问题讨论】:
-
您并不总是希望聚集索引成为主键。这不是必需的,只有默认值几乎总是最符合逻辑的,主键也是聚集索引。
-
在您的第一个示例中或一般情况下,我不确定聚集索引查找本身是否为
O(1)。聚集索引只是意味着一旦在索引中找到项目,实际项目就在那里。在非聚集索引中,即使找到了项目,我们仍然需要在聚集索引中进行查找以找到实际记录(如果我的术语有些偏差,请原谅)。 -
不知道为什么这被否决或标记为不清楚。这是一个有效的问题,我很清楚 OP 在问什么。答案肯定很长,因为它需要大量关于索引的信息,但这个问题本身对我来说似乎很合理。也许以前有人问过,但不值得一票恕我直言。
-
您正在描述哈希索引,这些索引仅在 SQL Server 中允许用于内存优化表。正常的,基于磁盘的索引只能是 B 树或列存储(堆根本不是索引)。 B-tree 有
O(log(n)),列存储可能更糟。但据我所知,即使是哈希索引也不能保证O(1),尽管有时它可能会提供。 -
@SeanLange 这太宽泛了。答案将是有关该主题的教程。 user7127000 应该读一些。这个例子甚至没有什么特别之处。另外不幸的是,这个问题与一些基础知识相矛盾(参见 cmets),包括它的前提是错误的。
标签: sql sql-server tsql database-design relational-database