CMU 15445 学习之Tree Index I

Table Index

前面介绍完了 Hash Table,在数据库系统中,它可以用于一些 sql 执行时的临时数据结构,或者用来存储一些元数据信息,也可以作为表的 Hash 索引,但是对于表索引,在更通用的场景下, B+ 树是更广泛的选择。

表索引(Index)指的是表中数据的一些子集,这些子集能够标识表中数据的一些特征,以便能够快速的去查找 table 中的数据,并且数据库能够保证,表中数据和表索引数据的一致性。

B+ Tree 基本概念

B+ Tree 实际上是一种平衡树结构,它能够保证数据有序存储,可以在平均 O(log n) 复杂度下查询、插入、删除数据。

它实际上类似二叉平衡树,但是每个节点可以拥有不止 2 个子节点,并且能够适配数据库需要读取整块数据的需求,提升数据读写的效率。

B+ 树是一个多叉平衡树,例如 M 个分叉指的是每个 inner node 都有 M 个路径到子节点,具有以下基本特征:

  • 完全平衡的树结构,即所有子节点到根节点的距离始终保持一致
  • 除根节点外,每个节点的数据量至少大于 M 的一半,即 M/2-1 <= #keys <= M-1
  • 每一个具有 k 个 key 的节点内,都有 k+1 个指向子节点的指针

下图所示,是一个 B+ Tree 的例子。

最底层的节点叫做 leaf node 叶子节点,上层的叫做 inner node,最顶层的 inner node 就是根节点(root node)。

inner node 中不会存储实际的数据,而是存储 key 以及指向其子节点的指针。

叶子节点之间有指针串联,方便进行 scan 操作;每个叶子节点中存储了实际的 key/value 数据。

叶子节点的内部结构,一般有两种不同的布局方式,一种是很常见的,存储一个 page id,并且将索引的 key 和 value 都存放到节点中,然后一个 page 指向下一个 page。

这样是将 key/value 保存在了一起,并不利于顺序扫描,如果我们只需要扫描 key 的话,那么会有一些额外的消耗。

另一种方式是将 key 和 value 分开,结构大致如下所示:

其中包含了一些元数据信息,例如当前的层数,空闲空间等,以及一个有序的 key 列表,并且每一个 key 指向了它自己的 value。

而实际 value 所表示的数据,各个系统有不同的实现,大致有两种:一是存储一个记录 id,指向磁盘的 page 中数据的实际位置;二是直接就存储数据本身。

B+ Tree 操作

insert

B+ 树中插入操作大致流程如下:

  • 首先从根节点开始,通过 inner node 的指针,层层往下找到对应的叶子节点 L
  • 将数据存储到叶子节点中
  • 如果节点 L 中还有空闲空间,则操作完成
  • 否则,分裂(split)该叶子节点

重新分布该叶子节点上的数据,以最中间的 key 为界,右边的数据分裂到新的节点中

分裂的时候,需要将叶子节点中间的 key 推送到上层父节点

如果上层父节点又需要分裂,则重复执行上述过程

delete

delete 操作大致是和 insert 相反的,插入的时候,如果一个节点上的数据满了,则需要分裂;而删除时,如果一个节点中的数据少于了 M/2-1,则破坏了 B+ Tree 的定义,这时候需要将节点进行合并,称为 merge。

大致过程如下:

  • 通过 inner node 节点找到对应的叶子节点 L
  • 在 L 中找到对应的数据并删除
  • 如果叶子节点中的数据大于等于 M/2-1,则完成
  • 否则,需要进行 merge 合并节点

尝试重分布,如果邻近节点有富余,则从邻近的节点中拿一个 key

如果邻近节点也没有多余的数据,则尝试和兄弟节点合并

这里有一个网站,动态展示了 B+ 树的插入、删除、查找过程,能够更好帮你理解 B+ 树。https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html

B+ Tree Design

接下来在简要分析下关于 B+ Tree 的一些设计问题。

Node Size

对于 B+ 树中每个节点的大小,这其实并不确定,或者说依赖于硬件环境和数据库类型,sql 查询类型等因素。

大致来说,存储介质速度越慢,则一个节点的容量就越大,道理也很简单。当在慢速的介质中,例如磁盘,我么肯定希望能够一次性多读取一部分数据到内存中,尽量避免多次随机 IO。在越快速的设备上,则节点的容量越小。

可以参考内存中的 cache line 和操作系统维护的 page size。MySQL 的 B+ 树节点大小一般是 16KB。

Merge Threshold

前面说到了删除数据时可能会触发 B+ 树的 merge 节点操作,但是在实际的实现中,一些数据库系统并不是只要满足条件就会马上执行,而是累积到一段时间之后,再进行 merge。

因为 merge 是一个很“昂贵”的操作,涉及到磁盘上的数据调整分布,一些系统中会有一些后台进程,定期去触发这个操作。

Variable-Length Keys

前面提到的 B+ Tree 中存储的都是固定 size 的 key,但是实际环境中,我们的 key 或者 value 都有可能是不定长的。针对不定长的 key,一般有这几种解决办法:

1.节点中不存储实际的 key,而是存储指向实际 tuple 属性的指针,这样的话虽然能够固定大小,但是指针并没有 key 本身具有的特征,范围扫描低效,实际使用并不多。

2.节点的 size 也不固定,来适配不同长度的 key

  • 这种方式需要更加精细化的内存管理,并且在 buffer pool 中也需要适配(buffer pool 的 size 通常是固定的),所以实际使用也不多。

3.对齐,总是将 key 对齐为其类型的大小,而不管 key 的 size 有多大。这种方式缺点也显而易见,就是可能会浪费一定的空间。

4.使用类似 slot page 的组织方式,将 key 存在一个有序的集合中,并且指向其实际的数据。

Non-Unique Index

数据库中的索引,有时候可以存在重复的数据,除了唯一索引外。因此,在 B+ Tree 存储数据的时候,需要对重复的 key 进行处理。

Duplicate Keys

存储重复 key 很好理解,就是我们可以把重复的 key 也当做是一个单独的 key 进行存储即可。

Va

lue List

value list 就是对重复 key 的 value 维护了一个链表,将其串联起来。

B+ Tree Optimizations

最后再来看下关于 B+ 树在设计时的一些优化方案。

Prefix Compression

因为 B+ 树底层叶子节点的数据是有序排列的,因此存储在同一个叶子节点的数据,有很大可能是具有相同的特征的,例如可能是类似的,拥有相同的前缀。

所以,针对那些有相同前缀的数据,可以只存储一份前缀数据,而不用每个 key 都单独存储一份。

Suffix Truncation

前面提到过 B+ 树中 inner node 只存储了 key 和索引信息,并不存储数据,只是做为一个辅助查找的索引节点。因此 inner node 中的 key 并不用是完整的 key,只要能够起到区分查找的作用就可以了。

例如上面的例子,由于这两个 key 所有字符都不一致,因此并不需要存储完整的 key,只需要存储能够帮助查找到下一级节点的信息就可以了。

Bulk Insert

最好的构建 B+ 树的方式,是将一组有序的数据从下到上构建 B+ 树的多级索引,这样不会存在 B+ 树的分裂或者合并,效率是最高的。

因此如果有一部分初始化数据需要插入到 B+ 树中,可以先将其排序,然后直接构建 B+ 树。

Pointer Swizzling

B+ 树遍历 page 的时候,每次都需要从 buffer pool 中获取 page 的位置信息,然后 B+ 树根据这个位置去获取 Buffer Pool 中的 page 数据。

例如上图中,需要获取 page id 为 2 的 page,则会先从 page table 中获取,Buffer Pool 判断这个 page 是否在内存中,如果不在则加载这个 page 到内存,并且返回一个 page 的指针(page 的实际位置)给 B+ 树。

如果 B+ 树确认扫描到的 page 肯定在内存中,那么可以直接存储 page 指针,省去了从 page table 中寻址的开销。

这个优化比较适用于 B+ 树的上层节点,因为 B+ 树上面的几层节点容量相对较小,并且会被频繁的访问到,可以缓存到内存中加速 B+ 树的查询。

Conclusion

这一节讲述了 B+ 树的一些基本概念,相信读者能够对其有一个基本的理解了,在大多数情况下,B+ 树是一个在数据库中应用非常广泛的结构。

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/289630.html<

(0)
管理的头像管理
上一篇2025-05-16 21:21
下一篇 2025-05-16 21:23

相关推荐

  • 站群服务器和普通服务器到底哪个更适合GEO,怎么选?

    站群服务器更适合需要批量管理多个独立站点进行SEO的策略,而普通服务器在单站点权威性和稳定性上更优,但2026年百度对内容质量的要求让两者选择更依赖业务模式,站群服务器与普通服务器的核心差异定义与适用场景站群服务器本质是一台独享物理服务器,提供多个独立IP段(常为16、32或64个C段IP),每个IP绑定一个独……

    2026-07-28
    0
  • 物理服务器和云服务器做站群到底选哪个,哪个更稳定?

    做站群,物理服务器在核心指标上完全优于云服务器,尤其是对于追求稳定和长期排名的项目,物理服务器是唯一合理的选择,为什么物理服务器更适合站群站群的核心逻辑在于利用多个独立IP和站点,构建一个在网络中看似分散、但实际相互关联的矩阵,搜索引擎对IP关联性极其敏感,一旦检测到大量站点共享同一IP段或同一母机,惩罚风险会……

    2026-07-28
    0
  • 国内高防服务器哪家防御真实靠谱,怎么选?

    国内高防服务器哪家防御真实靠谱?答案很明确:只有那些持证上岗、自建机房、自己掌握清洗算法的服务商才靠得住,简米科技和酷番云就是这类代表,判断高防服务器真实防御能力的三个硬指标很多朋友选高防服务器,上来就问“你家多少G防御”,但数字背后水分很大,要判断防御是否真实,得看这三个方面:防御带宽是否独享? 有些服务商宣……

    2026-07-28
    0
  • 裸金属服务器和物理服务器有什么区别?,怎么选?

    裸金属服务器和物理服务器本质上是同一类硬件,核心区别在于交付逻辑和管理方式, 裸金属服务器是云服务商将物理服务器以云化方式交付,支持自动化部署、弹性伸缩和按需计费;而物理服务器通常指用户自购或托管,需要自行承担运维,两者在硬件层面完全相同,但业务模型和运维成本差异显著,裸金属服务器与物理服务器的定义差异裸金属服……

    2026-07-28
    0
  • 做GEO站群选哪家服务器服务商靠谱,怎么选?

    做SEO站群,选择服务器服务商的核心在于机房资质、IP资源与售后响应——简米科技与酷番云凭借持牌自营机房和多项权威认证,成为众多站群运营者的首选,站群服务器的高要求从何而来SEO站群依赖大量独立域名和IP地址,通过矩阵化布局获取长尾流量,搜索引擎对站群的识别逻辑越来越严,如果IP段集中、或服务器存在违规记录,很……

    2026-07-28
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注