数据结构和算法之八:B+树

数据结构树论之B+树

上一文中,我们详细了解了二叉树,以及一些特殊的二叉树(搜索树、平衡树、红黑树)的原理,本文重点来说明在MYSQL中用于索引的B+树。

如果仅仅是在内存中进行操作,那么红黑树是完全能够满足我们的要求的,但是如果数据量到达非常庞大的量级,比如几千万上亿时,我们是很难将数据全部load到内存中,构建出红黑树来直接查询,那么必定会将大量数据存放到磁盘上,在查询时通过磁盘I/O来完成。

我们假设现在有1000万数据,如果用红黑树来处理的话,那么树高估计在23-24层,如果1000万数据都在内存中,我们可以看到,一次查询只需要执行20多次搜索比较就可以完成查找,效率是极高的;但是1000万数据全部放到内存中也不现实,因此实际的做法是,只把根节点加载到内存,其他数据放到磁盘上;在执行查找时,如果比根节点小,则再从磁盘加载左孩子节点,再比较,再加载,一直这样执行到叶子节点。那么你会发现,一次查找,要经过20多次的磁盘I/O,我们知道磁盘I/O相对内存操作是非常低效的,20多次磁盘I/O是不能接受的。

为了解决大数据量下,数据存到磁盘时,查询导致磁盘I/O次数过多带来的性能问题,诞生了B+树这种数据结构, 它是MYSQL数据库的索引的结构。

首先我们来认识一下B+树的结构

在这里插入图片描述

可以看到,它和二叉树的不同点是,首先,每个节点不止存一个值了,而是存多个值,一个值可以将数据分成小于它的和大于它的两半,那么N值就可以将数据分为N+1个区间段了;另外一个就是二叉只会分为两个孩子,而B+树可以最多可以有M个分叉;最后你会发现叶子节点之间通过双向链表连接起来,这是主要是为了实现如SQL中的区间查找功能。

综合一下B+树的特点,它有如下的一些性质

M阶的B+Tree:

(1)每个节点最多有m个子节点(m叉树)(为什么不是M+1个子节点,理论上不是分为M+1个段吗?我认为这是一个工程实践问题,B+树的上一层值会来自于下一层节点的最大或者最小值,因此它会存在一个左右开闭问题,因此要么是左边,要么是右边会少一个值区间)

(2)除根节点外,每个节点至少有m/2个子节点。

(3)根节点要么是空,要么是独根,否则至少有2个子节点

(4)有k个子节点的节点必有k个关键码:就是 有m个数据就有m个叉叉;

(5)叶节点的高度一致:这样所有分支的查询复杂度是一样的。

基本认识了B+树的结构之后,回到之前的问题,B+树时怎么解决大数据量下的查找,导致磁盘I/O次数过多引起的性能问题?

先来点计算机的底层知识,计算机从磁盘读取数据到内存中时,并不是一个数据一个数据的读取,它有个一个最小的读取尺寸单位,叫页,比如4KB,每次读取都是4kB。

因此我们可以利用这个原理,将一个节点的大小就设置为一次磁盘I/O读取的4kb大小,对于整形的数据类型,通常占用的空间在4个字节,那么一个节点可容纳的数据量就是 4096 / (4+2) 差不多为700,这个2指的是指针占用的空间。在B+树中,所有数据都存在叶子节点中,我们可以初略估算一下,只有两层的B+树,数据量级为700 * 700 = 49W,如果是3层的B+树,量级为700 ^ 3 = 3.5亿。换句话说,从3.5亿的数据量中查找只需要做3次磁盘I/O,从根到叶子节点,你说高效不高效。(PS:1. 以上的计算只是说明思路,实际的数值是有出入的;2. 实际工程实践中,根节点通常是常驻内存,因此I/O还会少一次根的加载)

B+树的查找操作,和二叉树差不多,元素先和根比较(因为每个节点的元素是排好序的,因此可以使用二分查找),找到对应的区间,再往下一级区间去查找,直到叶子节点为止。

插入操作比二叉树时,多了节点分裂的操作,因为B+树有个阶的限制,当某个节点的数量大于阶的限制时,会分裂成多个节点。反过来,如果删除节点时,存在何必的动作。

道理虽懂,但是暂时还没有动手自己写一颗B+树出来,所以也就暂时不贴代码出来,有空的大神可以写出来分享一下。

前面说了这么多B+树, 那么B树呢?

B树在实际中使用较少(貌似还没见过那儿直接使用的B树),你可以把它看做是B+树的过渡,因此对它有个了解即可。

它和B+树有哪些区别呢?

  1. 它的所有节点都会存储数据,而B+树的所有数据都在叶子节点上,非叶子节点(也可以认为索引层)数据是冗余的,下层节点的一些值。
  2. 它的叶子节点之间没有双向链表连接,因此范围查找时麻烦的事情。

最后,如果想知道B+树在MYSQL索引中的具体应用,本人后续推出MYSQL索引文章来详解,敬请关注。

B+树可视化神器体验:https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html

B树可视化神器体验:https://www.cs.usfca.edu/~galles/visualization/BTree.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值