请帮助我理解我认为两个事实之间存在不一致的地方:
通常,对于中间节点中的给定键,B树具有以下属性:左子树中的所有键都小于它,而右子树中的所有键都大于此,这样:
在上面的示例(image credit)中,显然将一个ID = 7的行插入到表中。但是,如果该ID的行数据(非键列)不在示例的根节点中且叶节点中没有7,那么它在哪里?
显然,除了“索引是B树”之外,还有更多内容,我希望能有所了解。
答案 0 :(得分:3)
我认为这篇文章的概述很好:
https://www.simple-talk.com/sql/database-administration/sql-server-storage-internals-101/
参见部分索引。示出了作为7或16的节点也具有它们的叶子 另外,我强烈推荐书:
Kalen Delaney的SQL Server 2012 Internals
https://www.amazon.com/Microsoft-Server-Internals-Developer-Reference/dp/0735658560
答案 1 :(得分:2)
构建B-Tree索引时,它从叶级开始 - 数据被排序并写入数据页并创建双链表。
从每个页面获取最小的键值(来自第一页的NULL)并用于构建下一级索引的索引页面,因此索引页面中的每一行都包含下面页面的ID和来自它的最小键值。它再次执行相同的操作,从每个索引页面获取最小的键值,以创建下一个级别。
这一直持续到一切都适合单个页面 - 这是根。
所有中间级别的页面和根目录遵循相同的模式,页面ID和该页面中的最小键值。
在上图中,假设它只是三个叶级页面和根,则根应包含select
,(pageID:1 Key:NULL)
和(pageID:2 Key:9)
。
答案 2 :(得分:2)
该图表用于B树,但从技术上讲,SQL Server使用B +树结构。向下滚动Wiki article,你会发现
在B +树中,密钥的副本存储在内部节点中;密钥和记录存储在树叶中;此外,叶节点可以包括指向下一个叶节点的指针,以加快顺序访问(Comer 1979,p.129)。
因此,内部节点只有密钥的副本,并且将在叶子中复制(在聚集索引的情况下,实际数据也被保留)。
您可以找到更多细节here。你会在评论部分注意到其他几个人注意到SQL Server使用的是B +树。
答案 3 :(得分:1)
(请原谅我的Word绘图技巧)
尽管您的图像确实代表了B-Tree,但实际的SQL Server实现略有不同,特别是B + Tree。我也尝试使用视觉效果进行解释,以下图为例:
如图所示,密钥不仅存在于一个节点(在本例中为根),而是复制并分发到子节点直到叶节点。 (在这种情况下,树只有2个级别,根级别和叶级别。)
因此,当运行密钥(Adams, Joe)
的查询时,将根据您在问题中提到的规则在B树中查找密钥(左侧较小的键,右侧较大的键) )。
这将持续到达 LEAF 节点。
此时有两个区别,特别是对于SQL Server:
非聚集索引(如上图所示):
聚集索引: