什么是 B-树❓

不知大家心里有没有点 B-树概念 O(∩_∩)O哈哈~

MySQL 数据库大家都用过吧?里面的索引是基于什么数据结构?

当然大家也都知道索引主要是基于 Hash 表或者 B+ 树。

知识点:对于InnoDB表,数据文件ibd本身就是按B+树组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。

 

那大家知道 B+ 树的实现细节是什么样?B-树和 B+ 树有什么区别?MySQL 里面的索引为什么主要基于 B+树?

B-树和 B+ 树都是很基础的概念,大家有必要掌握一下。

 

要弄明白 B+ 树,咋们先要了解 B-树。需要注意的是,B-树就是 B 树,中间的横线并不是减号。

谁要是把 B-树读成 B 减树,那可就丢人了。

 

那大家来说说,数据库索引为什么要使用树结构存储呢?

也许你会认为这还不简单,树的查询效率高,而且保持有序。

既然这样,为什么索引没有使用二叉树来实现呢?(二叉树查询的时间复杂度是 0(logN),性能已经足够高了啊,难道 B 树可以比它更快?)

其实从算法逻辑上来讲,二叉树的查找速度和比较次数都是最小的。但是我们不得不考虑一个现实问题:磁盘 IO

数据库索引是存储在磁盘上的,当数据量比较大的时候,索引的大小可能有几个 G 甚至更多。

当我们利用索引查询的时候,能把整个索引全部加载到内存吗?显然不可能。能做的只有逐一加载每一个磁盘页这里的磁盘页对应着索引树的节点

 

如果我们利用二叉查找树作为索引结构,情形是什么样呢?假设树的高度是 4,查找的值是 10,那么流程如下:

第 1 次磁盘 IO:

第 2 次磁盘 IO:

第 3 次磁盘 IO:

第 4 次磁盘 IO:

大家有没有从中看出,磁盘 IO 的次数是由什么决定的?

磁盘 IO 的次数是 4 次,索引树的高度也是 4.索引最坏的情况下,磁盘 IO 次数等于索引树的高度。

既然如此,为了减少磁盘 IO 次数我们就需要把原本“瘦高”的树结构变得“矮胖”这就是 B-树的特征之一

B 树是一种多路平衡查找树,它的每一个节点最多包含 k 个孩子,k 被称为 B- 树的阶。k 的大小取决于磁盘页的大小

 

下面来具体介绍一下 B-树(Balance Tree),一个 m 阶的 B 树具有如下特征:

1. 根节点至少有两个子女。

2. 每个中间节点都包含 k-1 个元素和 k 个孩子,其中 m/2 <= k <=m

3. 每一个叶子节点都包含 k-1 个元素,其中  m/2 <= k <=m

4. 所有叶子节点都位于同一层

5. 每个节点中的元素从小到大排列,节点当中 k-1 个元素正好是 k 个孩子包含的元素的值域分划。

 

是不是觉得这条条框框的,看着好复杂。

别急,我们以一个 3 阶 B-树为例,来看看 B-树的具体结构。树中的具体元素和刚才的二叉查找树是一样的。

这棵树中,咋们重点来看(2,6)节点。该节点有两个元素 2 和 6,又有三个孩子 1,(3,5),8.其中 1 小于元素 2,(3,5)在元素 2,6 之间,8 大于(2,6),正好符合刚才所列的几条特征。

也许你会觉得这棵树长得可真奇怪,它真的能实现高效的查询吗?

那就让我来演示一下 B- 树查询的过程吧。假设我们要查询的数值是 5。

第 1 次磁盘 IO:

在内存中定位(和 9 比较):

第 2 次磁盘 IO:

在内存中定位(和 2,6 比较):

第 3 次磁盘 IO:

在内存中定位(和 3,5 比较):

通过整个流程我们可以看出,B-树在查询中比较次数其实不比二叉查找树少尤其当单一节点中元素数量很多时

可是相比磁盘 IO 的速度内存中的比较耗时几乎可以忽略所以只要树的高度足够低IO 次数足够少就可以提升查找性能

相比之下节点内部元素多一些也没有关系仅仅多了几次内存交互只要不超过磁盘页的大小即可这就是 B-树的优势之一

 

就是这样,查询的过程明白了吧,那么 B-树是如何插入和删除的呢?

B-树插入新节点的过程比较复杂,而且分成多种情况。由于时间的关系,我们只举一个最典型的例子,假如我们要插入的值是 4。

自顶向下查找 4 的节点位置,发现 4 应当插入到节点元素 3,5 之间。

节点 3,5 已经是两元素节点,无法再增加。父亲节点 2,6 也是两元素节点,也无法再增加。根节点 9 是单元素节点,可以升级为两元素节点。于是拆分节点 3,5 与节点 2,6,让根节点升级为两元素节点 4,9,节点 6 独立为根节点的第二个孩子。

是不是发现,就为了插入一个元素,让整个 B-树的那么多节点都发生了连锁反应。

确实有些麻烦,但也正因为如此,让 B- 树能够始终维持多路平衡。这也是 B- 树的一大优势:自平衡

 

下面我们再来说一说 B-树删除的过程。同样只举一个典型例子,删除元素 11。

自顶向下查找元素 11 的节点位置:

删除 11 后,节点 12 只有一个孩子,不符合 B- 树规范。因此找出 12,13,15 三节点的中位数 13,取代节点 12,而节点 12 自身下移成为第一个孩子。(这个过程称为左旋)。

 

以上就是 B-树的插入和删除,也是学习 B-树最绕的部分。没太看明白的小伙伴也不必心急,最关键的还是理解 B-树的核心思想。

 

那么,B-树都有哪些实际应用呢?

B- 树主要应用于文件系统以及部分数据库索引,比如著名的非关系型数据库 MongoDB。

而大部分关系型数据库,比如 MySQL,则使用 B+ 树作为索引。有关 B+ 树的知识,我们在 什么是 B+ 树❓做具体介绍。

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值