MySQL为何不选择平衡二叉树

既然平衡二叉树解决了普通二叉树的问题,那么mysql为何不选择平衡二叉树作为索引呢?

索引需要存储什么

让我们想一想,如果我们要把索引存起来,那么应该存哪些信息呢,它应该存储三块信息:

  • 索引的值:就是表里面索引列对应的值。

  • 数据的磁盘地址(通过磁盘地址找到当前数据)或者直接存储整条数据。

  • 子节点的引用:我们需要从根节点往下走,所以需要知道左右子节点的地址。 根据这三点,可以有如下大致的一个简单的结构图:

上图中数字表示的是索引的值,0x开头的表示磁盘地址,根节点中存了左右节点的引用。

AVL树用来存储索引存在什么问题

我们知道,页(Page)是 Innodb 存储引擎用于管理数据的最小磁盘单位,页的默认大小为16KB。页也就是上图中的节点,每查询一次节点就需要进行一次IO操作,IO操作是一种非常耗时的操作,很多业务系统的瓶颈都是卡在IO操作上,所以如果我们需要提高查询效率的办法之一就是减少IO次数,那么问题就来了,AVL树一个节点上只存了一个关键字(索引值)+一个磁盘地址+左右节点的引用,这是远远达不到16KB的,会浪费了大量的空间。

上图中如果我们要找到6这条数据,需要进行3次IO(获取一个节点就是一个IO操作),如果这棵树很高的话,就会进行大量的IO操作,所以说AVL树存在的最大问题就是空间利用不足,浪费了大量空间,数据量大的时候就会成为一颗瘦高的树,那么我们可以怎么改进呢?答案很明显了,那就是每个磁盘块多存一点东西,也就是说每个磁盘多存几个关键字,因为关键字越多,路数越多;路数越多,树也就越矮越胖,相应的操作IO次数就会越少。

多路平衡树(Balanced Tree)

多路平衡树简称B树,又称B-树,和AVL树一样,B树在枝节点和叶子节点存储键值、磁盘地址、左右节点引用。请看下图的一个多路平衡树的示例:

B树的特点

相比较AVL树,B树一个磁盘上可以存多个关键字(值),而且有一个特点就是:

  • 分叉数(路数)永远比关键字数多1。 我们可以画出如下简图(下图中只画了3路,即两个关键字,实际取决于一页能存储多少个关键字):

从上图可以很明显的看出,同样高度的树,B树能存的数据远远大于平衡二叉树。

B树是如何查找数据的

以上图为例,假如我们要找key=32这个数字,首先获取到根节点,发现18小于key,所以往右边走,获取到右边的数据,54和76,这时候遵循以下原则:

  • key<54,命中最左边分叉;

  • key=54,直接命中,返回数据;

  • 54<key<76,走中间的一个分叉;

  • key=76,直接命中,返回数据;

  • key>76,命中右边分支; 这里因为key=32,所以走得是第1条,命中左边分支,这时候再去获取左边分支,获取到32和50,比较发现key=32,命中,返回数据。

从上面我们可以看出B树效率相对于AVL树,在数据量大的情况效率已经提高了很多,那么为什么MySQL还是不选择B树作为索引呢? 那么接下来让我们先看看改良版的B+树,然后再下结论吧!

B+树

B+树由B树改良而来,属于改良版的多路平衡查找树。 首先让我们来看看B+树到底长什么样呢:

对比B+树,我们可以发现一个很明显的区别就是叶子节点有一个箭头指引而且从左到右是有序的。

InnoDB中使用的B+树相比较于传统B+树,改进之后的B+树具有以下特点

InnoDB中B+树的特点

  • 它的关键字的数量是跟路数相等的。

  • B+树的根节点和枝节点中都不会存储数据,只有叶子节点才存储数据。而搜索到关键字不会直接返回,会到最后一层的叶子节点。

  • B+树的每个叶子节点增加了一个指向相邻叶子节点的指针,它的最后一个数据会指向下一个叶子节点的第一个数据,形成了一个有序链表的结构。

  • 它是根据左闭右开的区间来检索数据的 按照B+树的特点,我们可以画出一个存储数据的简图,如下:

最后

给大家送上一份福利,领取方式:戳这里免费下载

Java架构进阶面试及知识点文档笔记

这份文档共498页,其中包括Java集合,并发编程,JVM,Dubbo,Redis,Spring全家桶,MySQL,Kafka等面试解析及知识点整理

Java分布式高级面试问题解析文档

其中都是包括分布式的面试问题解析,内容有分布式消息队列,Redis缓存,分库分表,微服务架构,分布式高可用,读写分离等等!

互联网Java程序员面试必备问题解析及文档学习笔记

Java架构进阶视频解析合集

)]

互联网Java程序员面试必备问题解析及文档学习笔记

[外链图片转存中…(img-kDFntc1E-1625205424045)]

Java架构进阶视频解析合集

Java高级工程师每日面试题精选,面试经历分享相关推荐

  1. ​浅谈 Java 后端开发工程师腾讯面试经历分享总结

    最近一段时间考虑到换工作,打算整理一下网络上曾经面试者分享的的面试经历并结合自己以往的面试经历和经验,帮助大家获取到互联网大厂的入职通知书,也就是入职 offer. 本文整理网络面试者和本人的面试经历 ...

  2. 这操作真香!Android高级工程师每日面试题精选,面试必备

    开头 眼看着金九银十就快来了,各大厂也开始了新一轮的招聘计划,尤其是腾讯前一段时间爆出了一个大消息: 将正式启动2021届秋季招聘,加大对数字经济和产业互联网人才的挖掘培养. 在本次招聘中,特别面向2 ...

  3. Android高级工程师每日面试题精选,面试必备

    开头 眼看着金九银十就快来了,各大厂也开始了新一轮的招聘计划,尤其是腾讯前一段时间爆出了一个大消息: 将正式启动2021届秋季招聘,加大对数字经济和产业互联网人才的挖掘培养. 在本次招聘中,特别面向2 ...

  4. Android高级工程师每日面试题精选,offer拿到手软

    一.背景介绍 从实用角度梳理一篇能够帮大家快速扫盲的CMake基础教程,也是对我目前负责项目的一次学习总结.既然选择从项目实用性考虑,下面的讲解内容可能并不一定完整,更多的是符合项目目前使用到的一些特 ...

  5. java高级工程师开放面试题集二

    临近年关,不少人蠢蠢欲动,有童鞋问我java后端面试会面试什么? 作为一个java后端老鸟,跌打滚爬多次被面试和面试别人,总结了一些经验,希望对大家有所帮助. 特别说明,仅仅针对工作两年以上的java ...

  6. 南方航空java面试_面试经验 南航面试经历分享

    南方航空面试经历分享 前言 每个人的成功经验都是来之不易的,今天小V的面经写得有点长,为了给大家写的详细一些,参考多一些,也是拼了! 小V的基本情况:小V是一名大三的在校学生,学的还是搬砖的理工科专业 ...

  7. 【网络安全面经】2023届网络安全岗秋招面试题及面试经验分享

    随着国家政策的扶持,网络安全行业也越来越为大众所熟知,相应的想要进入到网络安全行业的人也越来越多,为了更好地进行工作,除了学好网络安全知识外,还要应对企业的面试. 所以在这里我归总了一些网络安全方面的 ...

  8. 2023级网络安全岗面试题及面试经验分享

    在当今社会网络安全行业越来越发达,也有越来越多的人去学习,为了更好地进行工作,除了学好知识外还要应对企业的面试. 所以在这里我归总了一些网络安全方面的常见面试题,希望对大家有所帮助. 一个2023届毕 ...

  9. 天顺智慧能源,思科,平安科技面试经历分享吧

    面试经历分享吧 需要面试题,请私我 1.天顺智慧能源有限公司(上海) 面试java岗位 1.首先,人事会给你一份笔试试题,见我博客,然后java工程师,让你自我介绍,问一下高并发知识,你所从事的项目等 ...

最新文章

  1. python自动退出程序_python异常退出
  2. 初步学习JS中的闭包
  3. 【SSH】——Hibernate三种状态之间的转化
  4. mac安装telnet 超简单 复制telnet文件即可
  5. 什么叫做在oracle目录下,ORACLE directory 目录
  6. DataFrame.to_dict(orient='dict')英文文档翻译
  7. django 学习 (一)
  8. linux服务器登录次数,Linux 服务器和Windows服务器 用户登录失败次数限制【互联网金融系统漏洞排查】...
  9. DeepRacer 根据路线计算Action Space RaceLine_Speed_ActionSpace
  10. 畅管进销存管理系统 v6.0
  11. Nginx + Lua搭建文件上传下载服务
  12. 流程管理对企业有何价值?如何做好企业流程管理?
  13. 为中国的孩子制造安全的校车
  14. 基于拉丁超立方抽样的风,光,负荷场景生成方法 风电功率场景生成 ,光伏功率场景生成,负荷场景生成
  15. IOS app 上线流程
  16. Linux下 rsync远程同步带密码
  17. Linux下安装GPU显卡驱动
  18. zcmu1074: 求1+1/2+1/3+...+1/n
  19. MySQL中MAX函数如何使用?
  20. mysql undo文件_mysql undo管理

热门文章

  1. Method Swizzle黑魔法,修改 ios 系统类库方法(转载)
  2. 优化算法的意义,之二。
  3. java项目中外接扫描仪无法使用_java – 扫描仪行不可用错误
  4. socket read time out解决方法_time_after方法对jiffies回绕问题的解决
  5. mysql .pdb是什么文件_计算广告算法到底要做什么?
  6. mysql的英文字母_MySQL中查询的有关英文字母大小写问题的分析
  7. windows命令行无法启动redis_windows系统安装redis
  8. MongoDB 数据类型查询——$type使用
  9. c++ vector学习
  10. 看雪 2016CrackMe 攻防大赛 - 1-Crack_Me-凉飕飕