前言

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条,那么总共可以存储的数据条数即为161368900=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技术宝典 ,及时获取最新分享.

java磁盘读写b 树_原来你是这样的B+树相关推荐

  1. java代码读写者问题_一整套Java线上故障排查技巧,爱了!

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:腾讯推出高性能 RPC 开发框架 个人原创100W+访问量博客:点击前往,查看更多 来源:fredal.xin/ ...

  2. hdfs java api 读写文件操作_第十讲:通过JavaAPI对HDFS读写

    上一讲我们通过java api 接口对虚拟机里面的hdfs进行了新建文件夹.下面我们要进行其他的操作: 注,以下的所有内容都是在第九讲的代码的基础上的. 1.删除hdfs上面的文件夹 2.删除dhfs ...

  3. java线程读写互相影响_求助。多线程读取文件相互影响

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 for(.......) { new Thread(new Runnable(){ @Override public void run() { //读取文 ...

  4. java sax读写xml文件_使用SAXReader读取xml文件

    搜索热词 原XML文件: 99999 5275 0 001 9999 20151221 018888 0100010 5275 6600 99898989 000 c1aaaax QD00112210 ...

  5. js数组对象递归转换树_使用手刹批量转换视频目录树以递归流式传输到Xbox360

    js数组对象递归转换树 I've got many many gigs of 640x480 video of the kids and family taken on my Flip Ultra a ...

  6. c++解析csv 存入数组_使用Apache Commons CSV在Java中读写CSV

    介绍 这是专门针对Java读写CSV的库的简短系列文章的第二篇,也是上一篇文章" Core Java读写CSV"的直接续篇. Apache Commons CSV 在Apache的 ...

  7. java怎样读txt文件_【后端开辟】java怎样读写txt文件?

    java怎样读取txt文件? 1.运用FileInputStream完成读取txt文件内容 2.运用FileOutputStream完成写入txt文件内容 package cn.xiaobing.ut ...

  8. java 程序怎么设置中文_怎么让这个简单JAVA程序读写中文字符

    怎么让这个简单JAVA程序读写并正确显示中文字符,现在它只能读写显示英文字符.//这是个简单的读写文本的程序import .*;import t.*;import javax.swing.*;impo ...

  9. java 区间树_线段树(区间树)之区间染色和4n推导过程

    前言 线段树(区间树)是什么呢?有了二叉树.二分搜索树,线段树又是干什么的呢?最经典的线段树问题:区间染色:正如它的名字而言,主要解决区间的问题 一.线段树说明 1.什么是线段树? 线段树首先是二叉树 ...

最新文章

  1. Git011--分支管理策略
  2. c语言switch()语句
  3. c语言实现快速排序对文件中字符,C语言中快速排序和插入排序优化的实现
  4. 地壳中元素含量排名记忆口诀_Nature:利用熔融包裹体的元素和同位素示踪俯冲带流体来源...
  5. c++工作笔记002---C++ 类成员访问运算符 - 的重载
  6. Python爬虫实战之爬取链家广州房价_02把小爬虫变大
  7. quartz定时任务框架
  8. JAVA泛型_泛型类、接口、通配符、方法、上下边界
  9. Error(13) 解决LoggerFactory is not a Logback LoggerContext but Logback is on the classpath
  10. 2019-11-10训练总结
  11. ArrayList vs LinkedList
  12. 用ps羽化图片边缘(两种羽化图片边缘的方法)
  13. 蚂蚁区块链大杀器首度亮相,速来围观!丨蚂蚁区块链创新大赛站
  14. 计算机英语pork,[语音]各种肉的英文
  15. 2012年第23周限时免费游戏应用点评
  16. (平衡)kd树的创建与搜索
  17. Leetcode_128_Longest Consecutive Sequence
  18. 哈尔滨商业大学c语言考试形式,知到题库管理会计(哈尔滨商业大学)答案教程...
  19. 怎样与领导谈加薪以及谈加薪的技巧
  20. 在线分享 Hosts 规则工具:Remote Hosts Server

热门文章

  1. 卷积核一定可以提升网络性能吗?-分类0,2
  2. 用矩阵内积的办法构造迭代次数受控的神经网络1:0.6:0.1=4:3:2
  3. access期刊可以重投几次_又被拒稿了?老司机带你一投即中
  4. 3.1 基础模型-深度学习第五课《序列模型》-Stanford吴恩达教授
  5. 玩转Mixly – 2、Arduino AVR编程 之 输入输出
  6. SPI配置8通道ADC128S022
  7. 利用切片操作,实现一个trim()函数,去除字符串首尾的空格,不调用str的strip()方法:
  8. 计算机等级考试初级网络工程师,计算机等级网络工程师考试内容
  9. SpringBoot系列: SpringBoot 启动慢的问题
  10. Linux系统中的防火墙的实现:iptables/netfilter