数据结构——5、树——2、B-树/B树

1.1.1 *B-树/B树*

1.1.1.1 *索引为什么使用树结构*

要弄明白B+树,先要弄明白B-树,B-树就是B树,中间的横线不是减号

1、数据库索引为什么要使用树结构进行存储?

树的查询效率高,并且可以保持有序

2、为什么没有使用二叉查找树树来实现?

二叉查找树查询的时间复杂度是O(logN),从算法逻辑上来讲,二叉查找树的查找速度和比较次数都是最小的,但需要考虑一个现实问题:磁盘IO

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

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

img img

如果利用二叉查找树作为索引结构,假设树的高度是4,查找的值是10,则流程如下:

img

imgimg

imgimg

可以看到:

磁盘IO的次数由索引树的高度决定,即最坏查找情况下,磁盘IO的次数等于索引树的高度

为了减少磁盘IO的次数,就需要将将原本“瘦高”的树结构变得“矮胖”,这就是B树的特征之一

1.1.1.2 *B树的特征*

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

一个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树为例:

img

重点看(2,6)节点:

该节点中有两个元素2,6,有三个孩子1,(3,5),8

其中1小于元素2,(3,5)在元素2,6之间,8大于(3,5)(规则5)

均符合B树的几条特征

1.1.1.3 *B树的查询过程*

B树的查询过程如下:如果B树中查询数值5

img img

img img

img img

整个流程中,我们可以看出:

B树中的查询次数并不比二叉查找树少,尤其当单一节点中的元素数量很多时,可以相比磁盘IO的速度,内存中的比较耗时,可以忽略不计,

即次数查找是在磁盘IO中查找的,元素比较是在内存中进行的

磁盘读取时,不是按需读取的,而是读取当前数据,并向后读取一段数据,将这段数据加载到内存中,默认这段数据为一页,或页的整数倍,

B树添加节点的时候,默认申请一个磁盘页的空间,用来存储一个节点的数据,这样每个节点只需要一次IO,就可以完全载入

一个节点的数据需要通过一次磁盘IO进行读取,读取到内存中,节点中的数据比较,则是在内存中进行

只要树的高度足够低,IO的次数足够少,就可以提升查找性能。节点内部元素多一些,没有关系,仅仅是多了几次内存交互而已,只要不超过磁盘页的大小即可,这也是B树的优势之一

1.1.1.4 *B树的插入过程*

B树的插入删除过程比较复杂,可以看一个典型的例子:

示例:加入插入的值4:

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

imgimg

动画演示:https://www.cnblogs.com/vincently/p/4526560.html

可以看到:

为了插入一个元素,整个B树中,很多节点都发生了连锁改变,但这也是B树的一大特点,始终能够维持多路平衡,即自平衡

1.1.1.5 *B树的删除过程*

示例:删除元素11

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

img img

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

1.1.1.6 *B树的实际应用*

B树主要应用于文件系统,以及部分数据索引,如非关系型数据库MongoDB,大部分关系型数据库,如MySql,使用B+树作为索引

posted on 2021-09-28 10:24  夜萤火虫和你  阅读(196)  评论(0编辑  收藏  举报

导航