数据结构与算法之美
王争
前 Google 工程师
283752 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 81 讲
基础篇 (38讲)
数据结构与算法之美
15
15
1.0x
00:00/00:00
登录|注册

48 | B+树:MySQL数据库索引是如何实现的?

频繁的删除操作会影响索引效率
写入和删除数据的效率下降
节省内存空间
提高查询效率
B树的叶子节点不需要链表串联
B树中的节点存储数据,B+树中只存储索引
分裂节点和合并节点
叶子节点存储值,链表串联
节点不存储数据,只作为索引
根节点存储在内存中,其他节点存储在磁盘中
通过链表将叶子节点串联在一起,方便按区间查找
m叉树只存储索引,并不真正存储数据
根节点的子节点个数可以不超过m/2
每个节点中子节点的个数不能超过m,也不能小于m/2
跳表也可以作为数据库索引的实现
B+树是通过改造二叉查找树得到的
缺点
优点
B树和B+树的区别
改造二叉查找树
特点
跳表与B+树的关系
索引的优缺点
B+树
数据库索引实现

该思维导图由 AI 生成,仅供参考

作为一个软件开发工程师,你对数据库肯定再熟悉不过了。作为主流的数据存储系统,它在我们的业务开发中,有着举足轻重的地位。在工作中,为了加速数据库中数据的查找速度,我们常用的处理思路是,对表中数据创建索引。那你是否思考过,数据库索引是如何实现的呢?底层使用的是什么数据结构和算法呢?

算法解析

思考的过程比结论更重要。跟着我学习了这么多节课,很多同学已经意识到这一点,比如 Jerry 银银同学。我感到很开心。所以,今天的讲解,我会尽量还原这个解决方案的思考过程,让你知其然,并且知其所以然。

1. 解决问题的前提是定义清楚问题

如何定义清楚问题呢?除了对问题进行详细的调研,还有一个办法,那就是,通过对一些模糊的需求进行假设,来限定解决的问题的范围
如果你对数据库的操作非常了解,针对我们现在这个问题,你就能把索引的需求定义得非常清楚。但是,对于大部分软件工程师来说,我们可能只了解一小部分常用的 SQL 语句,所以,这里我们假设要解决的问题,只包含这样两个常用的需求:
根据某个值查找数据,比如 select * from user where id=1234;
根据区间值来查找某些数据,比如 select * from user where id > 1234 and id < 2345。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

B+树在数据库索引中的重要性和应用价值是本文的核心内容。文章首先介绍了数据库索引的功能性和非功能性需求,然后回顾了散列表、平衡二叉查找树和跳表等数据结构,并指出它们在满足部分需求时存在局限性。接着详细介绍了B+树的特点和应用,强调了B+树与跳表的相似性,并通过代码示例展示了B+树的实现过程。文章还掏出了B+树在减少内存消耗和提高数据查询效率方面的优势,以及在数据写入和删除过程中可能带来的性能下降。最后,指出B+树的结构和操作与跳表非常类似,甚至可以替代B+树作为数据库的索引实现。整体而言,本文深入浅出地介绍了B+树在数据库索引中的重要性和应用价值,为读者提供了全面的技术视角。 B+树通过存储在磁盘的多叉树结构,实现了时间、空间的平衡,既保证了执行效率,又节省了内存。B+树的特点包括每个节点中子节点的个数不能超过m,根节点的子节点个数可以不超过m/2,m叉树只存储索引,并通过链表将叶子节点串联在一起,以方便按区间查找。此外,文章还简要提及了B树和B-树,强调了它们与B+树的区别和联系。总的来说,本文通过清晰的介绍和比较,使读者能够快速了解B+树在数据库索引中的重要性和应用价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《数据结构与算法之美》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(136)

  • 最新
  • 精选
  • Jerry银银
    个人觉得B+tree理解起来真不难,抓住几个要点就可以了: 1. 理解二叉查找树 2. 理解二叉查找树会出现不平衡的问题(红黑树理解了,对于平衡性这个关键点就理解了) 3. 磁盘IO访问太耗时 4. 当然,链表知识跑不了 —— 别小瞧这个简单的数据结构,它是链式结构之母 5. 最后,要知道典型的应用场景:数据库的索引结构的设计 还记得,在学生时代,不好好学数据结构的我,当看到这个高大尚的名词“B+tree”时,我心里无比惊慌:这东西貌似不简单。^_^ 那时,也有着王争老师说的这种情况:B-tree,这是B减树;肯定还有个正常的B树;B+tree,这是B加树;然后在我的脑海里面,想当然地认为,它们之间有着这样的大小关系:B-tree < B tree < B+tree ---------- 对于思考题,@老杨 大哥的回答我觉得很到位了。 我只做一下补充: 第一题: 对于B+tree叶子节点,是用双向链表还是用单链表,得从具体的场景思考。我想,大部分同学在开发中遇到的数据库查询,都遇到过升序或降序问题,即类似这样的sql: select name,age, ... from where uid > startValue and uid < endValue order by uid asc(或者desc),此时,数据底层实现有两种做法: 1)保证查出来的数据就是用户想要的顺序 2)不保证查出来的数据的有序性,查出来之后再排序 以上两种方案,不加思考,肯定选第一种,因为第二种做法浪费了时间(如果选用内存排序,还是考虑数据的量级)。那如何能保证查询出来的数据就是有序的呢?单链表肯定做不到,只能从头往后遍历,再想想,只能选择双向链表了。此时,可能有的同学又问了:双向链表,多出来了一倍的指针,不是会多占用空间嘛? 答案是肯定的。可是,我们再细想下,数据库索引本身都已经在磁盘中了,对于磁盘来说,这点空间已经微不足道了,用这点空间换来时间肯定划算呀。顺便提一下:在实际工程应用中,双向链表应用的场景非常广泛,毕竟能大量减少链表的遍历时间 第二题: 答案是「肯定的」。如同@老杨 大哥说的,JDK中的LinkedHashMap为了能做到保持节点的顺序(插入顺序或者访问顺序),就是用双向链表将节点串起来的。 其实,王争老师在《散列表(下)》那一堂课中就已经深入讲解了LinkedHashMap,如果理解了那篇,这个问题应该不难。 ------- 最后,我发现王争老师布置的这些课后思考题,都涉及到了之前学到的内容,不知道是有意还是无意的,嘻嘻! 这节的思考题花了蛮多时间进行思考,才能给出以上答案,希望王争老师帮看看是否有不对的地方,谢谢!

    作者回复: 👍

    2019-01-19
    23
    254
  • feifei
    老师,看了你的讲解,对于B+树的原理,我基本理解了,我又找了b+树的代码实现,也搞懂怎么回事了,当我看懂了,这个B+树的实现了之后,我就有个问题,这个B+树该如何保存到磁盘中呢?我搜索了好多,也没有找到相关的一个代码,你有这相关的资料吗?这种数据一般是如何保存的?谢谢

    作者回复: 我懂你的意思。具体我没研究过。我觉得可以直接存到文件里。节点在文件里的位置表示指针。我瞎猜的:)等我研究研究再说:)

    2019-01-24
    11
    40
  • hnbc
    老师,我想问一下100叉树为什么是3次io操作,不应该是4次吗,100的4次方是1亿

    作者回复: 这...第一层索引节点可以放到内存里的,这样就3次了:)

    2019-03-13
    5
    26
  • Harry陈祥
    您好。有次面试,面试官直接问我,什么数据结构可以做到O(logn)的范围查询? 当时没有想到填表,想到了B+树,而且数据库索引确实也是用的B+树。 那么问题来了,跳表和B+树在实现难度和性能上有什么区别,在数据量很大的情况下,表现性能如何,为什么redis选跳表? 谢谢老师

    作者回复: b+树主要是用在外部存储上,为了减少磁盘IO次数。 跳表比较适合内存存储。 实际上,两者本质的设计思想是雷同的,性能差距还是要具体看应用场景,无法从时间复杂度这么宽泛的度量标准来度量了。

    2019-02-21
    4
    22
  • Monday
    请问: 第一段代码,第9行: PAGE_SIZE = (m-1)*4[keywordss 大小]+m*8[children 大小] 1,这个8指的是引用(指针)占的内存大小吗? 2,引用大小是怎么计算的?和机器是多少位的有什么关系吗? 望争哥回复,谢谢!

    作者回复: 1. 是的 2. 有关系的,就是用多少位表示一个存储地址

    2019-01-20
    3
    10
  • mrlay
    维持b+树的特性的策略有了,但是如何实现这个策略 以及一些其他问题解决的策略的实现 我有些发怵的感觉,大家一般都是怎么过来的呢?

    作者回复: 兄弟对自己要求太高了,你要是学操作系统,还得把操作系统实现一个啊;)

    2019-07-02
    4
    6
  • 唯她命
    老师,现在觉得 你画的图 都是B树 而不是B+树

    作者回复: 好像不是吧

    2019-01-30
    2
    5
  • 唯她命
    老师 网上查到的资料 说有k个子树的中间节点包含有k个元素(B树中是k-1个元素) 和你讲的不同

    作者回复: 咱不要太教科书化啊。理解思想最重要啊。我觉得我讲的没问题啊。

    2019-01-30
    5
  • H.L.
    叶子节点的数据是如何存储的?比如mysql的b+树,key放在一堆,data放在一堆?

    作者回复: 叶子节点存对象 对象包含key和data

    2019-04-15
    3
    3
  • 西南偏北
    对于这样的查询语句"select * from table where user_id < 1000", 是如何在叶子节点上进行遍历的?是找到1000之后往前遍历,还是从开始遍历到1000?

    作者回复: 你可以看下极客时间多mysql专栏

    2019-11-02
    2
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部