前言

B+树是目前最常用的一种索引数据结构,通常用于数据库和操作系统的文件系统中,本文就网上的知识点与个人理解结合分享,如有错误,欢迎探讨及指正.

定义

B+树是B树的一种变形形式,B+树上的叶子结点存储关键字以及相应记录的地址,叶子结点以上各层作为索引使用。一棵m阶的B+树定义如下(注意: B+树的阶数m表示一个节点最多能有m个子节点,也就是每个节点上最多的键值个数.):
1.每个结点至多有m个子女;
2.除根结点外,每个结点至少有[m/2]个子女,根结点至少有两个子女;
3.有k个子女的结点必有k个关键字。

B+树的查找与B树不同,当索引部分某个结点的关键字与所查的关键字相等时,并不停止查找,应继续沿着这个关键字左边的指针向下,一直查到该关键字所在的叶子结点为止。

图文理解

下面我们通过图文详解来深入理解B+树

不同阶数的B+树对比

我们将数组[1,2,3,4…20]分别插入3阶、4阶、5阶、6阶B+数,最终存储的数据结构如下图:

  • 3阶B+树 :

  • 4阶B+数:

  • 5阶B+数:

  • 6阶B+数:

通过上面对比,我们不难发现以下特征:

  • 所有节点均有序排列;
  • 树节点总是树高平衡;
  • m阶的B+树除了根节点之外的每个节点都包含最少 m/2个元素,但最多包含 m-1 个元素(文末提供在线测试地址,可以自行删减元素,观察叶子结点的变化);
  • 对于任意的节点有最多 m 个子指针;
  • 对于所有内部节点,子指针的数目总是比元素的数目多一个;
  • 阶数越大,数的高度越小.
  • 所有数据存储在叶子结点上,非叶子节点不存储行数据,是为了能存储更多索引键,从而降低B+树的高度,进而减少IO次数.

B+树insert/delete操作后数据结构的变化

本次我们演示4阶B+树操作的变化过程

  • 第一步:我们先插入数字1、2、3

  • 第二步:插入数字4,由于每个节点最多只能有m-1个元素,即超过3个后需要进行拆分页,而目前只有一个根节点,所以旋转后树的深度+1.

  • 第三步:分别插入数字5、6,根据结构的特性拆分页,如下图


  • 第四步:分别插入数字7、8、9



  • 插入10的时候,触发每个节点最多只能有m-1个元素的特性,同时触发了[任意的节点有最多 m 个子指针]的特性,所以继续旋转后树的深度+1.

  • 第五步:前面四步演示了树的旋转以及拆分页,接下来我们看下删除元素会是什么样的效果,先删除元素10看下:

在第四步最后我们增加一个元素10,触发了B+树的特性调整了树的高度,现在我们删除元素10,从上图可以看出树的高度没有变化,这点跟平衡树不一样,我们继续删元素.


删除元素7之后,层级没有变化,但是第二级的右子节点元素值发生了旋转,由7变成了6,继续删除元素6:

我们发现删除元素6后,树的层级发生了变化,这是因为触发了[对于所有内部节点,子指针的数目总是比元素的数目多一个]这一特性,然后根据最优算法降低了树的高度,同时我们发现,此时的5个元素排列并没有恢复到我们之前从元素[1-5]插入后的结构,这点非常妙,不管接下来是新增、删除、查找你会发现效率都是最优的.

B+树的查找

我们还是以4阶树10个元素为例,查找元素6


从上可以看出查找路线与二叉树的查找规则一致,继续查找元素5



结合这两次查找,可以看出都消耗了3次IO找到数据,这个次数刚好等于数的高度,数据量少时看不出这个效率,假设是100阶的树,存储了400w+数据,实际也是3次IO就可以找到想要的数据,这个时候B+树的优势就体现出来了.

至此,相信你对B+树又有了更直观的认识,接下来我们再聊聊mysql应用的B+树索引.

mysql的B+树索引

mysql的B+树索引有多少阶?

对于这个问题,我们需要先了解下磁盘相关知识.

  • 磁盘的最小存储单位是扇区(512字节)
  • 磁盘的读取是以块为基本单位,一块大小为8个扇区,即4kb
  • B+树的每一个节点占用的空间就是一个块大小

由于B+树节点中只存储元素和指针.如果有n个元素,那么就有n+1个指针,假设现在索引存储int类型的值,一个int(32位)占用4个字节,一个指针占用8个字节,那么一个块最多能存4096/(4n+8(n+1))即340个元素,那么索引即为341阶(m阶数最多包含m-1个元素).

mysql的B+树索引能存多少数据?

以innodb引擎的索引数据结构为例,它的存储单元为一页,每页大小默认为16kb,该值可以通过参数调整,如下图.

  • 假设每个节点中索引元素占8个字节,指针占用6个字节,那么每页可存(16*1024)/(8+6)=1170个索引元素
  • 假设B+树的高度为3,一条数据大小为1k,那么:
    第一层可以存1170个元素;
    第二层可以存11701170=1368900个元素;
    第三层属于叶子结点,可以存的数据条数为页大小16k/每条数据大小1k,即16条,那么总共可以存储的数据条数即为16
    1368900=21902400

总结:mysql 单表使用innodb引擎(表数据文件本身就是一个B+树组织的索结构文件),默认至少可以存2000w数据(实际每个节点不只存储了元素及指针),并且查找数据,最多3次io即可.

资料参考

  • 非常经典的数据结构可视化工具
    https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html

  • 百度百科
    https://baike.baidu.com/item/B+%E6%A0%91/7845683#reference-[3]-1168762-wrap

欢迎关注个人订阅号:Java技术宝典 ,及时获取最新分享.

B+树,有图有真相!相关推荐

  1. 英语发音差异化,英语学习心得和方法、总结,程序猿也爱学英语(上),有图有真相...

    程序猿也爱学英语(上),有图有真相 一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 前言(Introduction) 发音(Pronunciation) 基本常用单词积 ...

  2. 数据结构 —— 数组,列表和树的家族

    作为一个程序员,在现在的工作中,写业务代码已经不是什么困难的事情了,但是这里有两个来自灵魂的拷问: 你知道你写的代码是如何执行的嘛?你知道你代码中的数据是怎么存储的嘛? 我不知道...... 那你还不 ...

  3. 程序猿也爱学英语(上),有图有真相

    程序猿也爱学英语(上),有图有真相 原文链接:http://www.cnblogs.com/KnightsWarrior/p/CoderLoveEnglish.html 一.本文所涉及的内容(Cont ...

  4. 判断两个树是否相等和判断tree1是否包含tree2 python实现

    判断两个树是否相等 def equal(node_a, node_b):"""判断两个树是否相等:param node_a: :param node_b: :return ...

  5. 论文溯源树AMiner

    来自 DBLP.ArXiv.STM 等多家学术出版机构和平台的数据表明,在过去 20 年间,计算机科学.物理学.统计学等研究领域的出版物总量都有大幅增加.像 CVPR.AAAI 等有关人工智能等新兴领 ...

  6. Python---哈夫曼树---Huffman Tree

    今天要讲的是天才哈夫曼的哈夫曼编码,这是树形数据结构的一个典型应用. !!!敲黑板!!!哈夫曼树的构建以及编码方式将是我们的学习重点. 老方式,代码+解释,手把手教你Python完成哈夫曼编码的全过程 ...

  7. 深度树匹配模型(TDM)

    深度树匹配模型(TDM) 算法介绍 Tree-based Deep Match(TDM)是由阿里妈妈精准定向广告算法团队自主研发,基于深度学习上的大规模(千万级+)推荐系统算法框架.在大规模推荐系统的 ...

  8. 洛谷 P5057 [CQOI2006]简单题(树状数组)

    嗯... 题目链接:https://www.luogu.org/problem/P5057 首先发现这道题中只有0和1,所以肯定与二进制有关.然后发现这道题需要支持区间更改和单点查询操作,所以首先想到 ...

  9. 二逼平衡树——树套树(线段树套Splay平衡树)

    题面 Bzoj3196 解析 线段树和Splay两棵树套在一起,常数直逼inf,但最终侥幸过了 思路还是比较简单, 在原数组维护一个下标线段树,再在每一个线段树节点,维护一个对应区间的权值Splay. ...

最新文章

  1. 美国物理超级计算机,美国科学家在物理学的一个分支领域朝着开发超级计算机迈进了一步。这一分支领域研究的是人眼看不见的粒子。...
  2. Python中numpy库unique函数解析
  3. 启明云端分享| 手把手教你基于DEMO源码快速进行86盒应用开发
  4. 为什么java在自己这是正确的但过不了oj_技术干货:关于Java异常的9大问题
  5. 【073】Android 数据存储(SQLite)
  6. 缓存击穿、缓存穿透、缓存雪崩简单总结
  7. 403保护网站服务器,HTML5服务器禁止访问403错误动画
  8. wordpress如何获得当前用户的头像
  9. Java 排序算法:折半插入排序
  10. xml-配置bean之depends-on
  11. Sobel 边缘检测
  12. mysql 1114错误_mysql出现错误编码1114的解决方法
  13. 六级未过,排名10%开外,如何保研浙大计算机?
  14. JavaScript实现变化的满天星星
  15. 达梦数据库使用小记录【关于 无效的列】
  16. 正在配置计算机好久了,准备配置windows请勿关闭计算机要多久_准备配置请勿关机很久...
  17. PS(2018)更换启动界面
  18. 为什么光盘能安装 gpt_您需要了解有关gpt 3的哪些信息以及为什么如此重要
  19. 《智能手机心率和呼吸率测量算法的前瞻性验证》阅读笔记
  20. 51单片机的应用——正脉冲宽度的的测量

热门文章

  1. 绝路之后,人人网还有三条去路
  2. [二分图最大独立集] bzoj4808 马
  3. 大数据技术原理与应用—第10讲 Spark(林子雨老师)课后习题
  4. linux解除硬盘加密,封印解除—在linux下访问群联闪存盘加密分区
  5. 十六进制(二进制)编辑器
  6. 《GIT教程-廖雪峰》笔记
  7. 简易手写输入法软件的编写
  8. js实现数据分页算法
  9. Python攻防-模拟猜测附近局域网WIFI密码
  10. POJ-2001-Shortest Prefixes