48 | B+树:MySQL数据库索引是如何实现的?
该思维导图由 AI 生成,仅供参考
算法解析
1. 解决问题的前提是定义清楚问题
- 深入了解
- 翻译
- 解释
- 总结
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-1923254 - feifei老师,看了你的讲解,对于B+树的原理,我基本理解了,我又找了b+树的代码实现,也搞懂怎么回事了,当我看懂了,这个B+树的实现了之后,我就有个问题,这个B+树该如何保存到磁盘中呢?我搜索了好多,也没有找到相关的一个代码,你有这相关的资料吗?这种数据一般是如何保存的?谢谢
作者回复: 我懂你的意思。具体我没研究过。我觉得可以直接存到文件里。节点在文件里的位置表示指针。我瞎猜的:)等我研究研究再说:)
2019-01-241140 - hnbc老师,我想问一下100叉树为什么是3次io操作,不应该是4次吗,100的4次方是1亿
作者回复: 这...第一层索引节点可以放到内存里的,这样就3次了:)
2019-03-13526 - Harry陈祥您好。有次面试,面试官直接问我,什么数据结构可以做到O(logn)的范围查询? 当时没有想到填表,想到了B+树,而且数据库索引确实也是用的B+树。 那么问题来了,跳表和B+树在实现难度和性能上有什么区别,在数据量很大的情况下,表现性能如何,为什么redis选跳表? 谢谢老师
作者回复: b+树主要是用在外部存储上,为了减少磁盘IO次数。 跳表比较适合内存存储。 实际上,两者本质的设计思想是雷同的,性能差距还是要具体看应用场景,无法从时间复杂度这么宽泛的度量标准来度量了。
2019-02-21422 - Monday请问: 第一段代码,第9行: PAGE_SIZE = (m-1)*4[keywordss 大小]+m*8[children 大小] 1,这个8指的是引用(指针)占的内存大小吗? 2,引用大小是怎么计算的?和机器是多少位的有什么关系吗? 望争哥回复,谢谢!
作者回复: 1. 是的 2. 有关系的,就是用多少位表示一个存储地址
2019-01-20310 - mrlay维持b+树的特性的策略有了,但是如何实现这个策略 以及一些其他问题解决的策略的实现 我有些发怵的感觉,大家一般都是怎么过来的呢?
作者回复: 兄弟对自己要求太高了,你要是学操作系统,还得把操作系统实现一个啊;)
2019-07-0246 - 唯她命老师,现在觉得 你画的图 都是B树 而不是B+树
作者回复: 好像不是吧
2019-01-3025 - 唯她命老师 网上查到的资料 说有k个子树的中间节点包含有k个元素(B树中是k-1个元素) 和你讲的不同
作者回复: 咱不要太教科书化啊。理解思想最重要啊。我觉得我讲的没问题啊。
2019-01-305 - H.L.叶子节点的数据是如何存储的?比如mysql的b+树,key放在一堆,data放在一堆?
作者回复: 叶子节点存对象 对象包含key和data
2019-04-1533 - 西南偏北对于这样的查询语句"select * from table where user_id < 1000", 是如何在叶子节点上进行遍历的?是找到1000之后往前遍历,还是从开始遍历到1000?
作者回复: 你可以看下极客时间多mysql专栏
2019-11-022