前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >innodb为什么选择B+ Tree而不是跳表,Redis为什么选择跳表而不是B+ Tree

innodb为什么选择B+ Tree而不是跳表,Redis为什么选择跳表而不是B+ Tree

作者头像
大忽悠爱学习
发布于 2023-03-23 06:43:09
发布于 2023-03-23 06:43:09
2.4K0
举报
文章被收录于专栏:c++与qt学习c++与qt学习

innodb为什么选择B+ Tree而不是跳表,Redis为什么选择跳表而不是B+ Tree


跳表

链表和数组相比,数组可以通过下标快速定位,或者通过二分查找,查询复杂度为O(logn),而链表只能按照顺序挨个查找,复杂度为O(n)。

为了让链表也能支持二分查找,我们可以在链表的基础上加上一层目录,即一层索引链表:

当我们访问某个节点时,先访问索引链表,通过索引链表进行二分过滤,在索引链表找到结点后,顺着索引链表的结点向下,找到原始链表的结点:

当数据量很大的情况下,一层索引查询复杂度无法满足O(logn)时,可以基于原始链表的第1层索引,抽出第二层/第三层更为稀疏的索引,结点数量是上一层的一半:

跳表: 通过对链表抽出索引层,以实现二分查找,从而可以快速定位节点位置,提示查找效率:

  • 当原始链表有n个结点,则索引的层数为log(n)-1,在每一层的访问次数是常量,因此查找结点的平均时间复杂度为O(logn)。
  • 增加了索引层,空间开销变大,相当于是以空间换时间

B+ Tree

一般来说B+树是由多个页组成的多级层级结构,每个页16Kb,对于主键索引来说,叶子节点存放用户完整行数据,非叶子节点存放索引信息(索引列和页号)。每个数据页内部,通过页目录实现二分查找

B+ tree也是利用了空间换时间的方式,同时利用索引层可以存放大量索引这一特点,使得B+ tree整体看上去更矮更胖,即定位记录需要的IO次数更少,每一层存放的数据量更多。


跳表和B+ tree相同之处

相同:

  • B+树和跳表都是在最底层包含所有用户数据,并且都是按顺序排列,时候范围查询
  • B+树和跳表利用索引层实现二叉查看,从而提高性能

不同之处也就是二者使用场景的区别了。


跳表和B+ tree在数据插入方面的性能

B+ tree插入性能分析

B+ Tree本质是一种多路平衡树,关键在于"平衡"二字,它的含义是子树们的高度层级尽量一致(最多差一个层级),这样在搜索的时候,不管是到哪个子树分支,搜索次数都差不太多。

当我们向数据库表不断插入记录时,为了维持B+树的平衡,B+树会不断分裂调整数据页。

插入主要分为以下三种情况:

  • 叶子结点和索引结点都没满的情况,直接将数据插入叶子结点即可
  • 叶子结点满了,索引结点没满的情况,拆分叶子结点,索引结点中需要增加新的索引项
  • 叶子结点满了,且索引结点也满了。叶子和索引结点都要拆分,同时往上还要再加一层索引。

跳表插入性能分析

当我们需要往跳表中插入数据时,是通过随机函数产生当前节点的层数,然后更新每一层索引,往其中加入一个节点,如果当前层数不足,就新添加一个索引层。

理论上为了达到二分效果,每一层的节点数需要是下一层节点数的二分之一。


为什么Innodb选择B+ tree而不是跳表

  • B+ tree是多叉树结构,每个结点都是一个16k的数据页,能存放较多的索引信息,所以扇出很高。三层左右就可以存储2kw左右的数据。也就是说查询一次数据,如果这些数据页都在磁盘里,那么最多需要查询三次磁盘IO。
  • 跳表是链表结构,一个结点存放一条数据,如果底层需要存储2kw数据,且每次查询都能达到二分效果,2kw大概需要2的24次方左右,也就是说跳表高度大概在24层左右。最坏情况下,这24层数据会分散在不同的数据页里,也就是说查询一次数据需要24次磁盘IO。

因此,存放同样量级的数据,B+ tree的高度会比跳表的要少,对于数据库系统而言,意味着一次查询需要的磁盘IO次数更少,因此查询效率更高。

对于写操作而言,B+树需要拆分合并数据页,跳表则是独立插入,并且根据随机函数确定层数,没有旋转和维持平衡带来的开销,因此跳表的写入性能会比B+ tree树要好。


为什么Redis有序集合底层选择跳表而非B+ tree

redis是基于内存的数据库,因此不需要考虑磁盘IO,所以索引层数在redis看了就不再是跳表的劣势了

  • B+树在数据写入时,存在拆分和合并数据页的开销,目的是为了保持树的平衡。
  • 跳表在数据写入时,只需要通过随机函数生成当前节点的层数即可,然后更新每一层索引,往其中加入一个节点,相比于B+ tree而言,少了旋转平衡带来的开销。

因此,redis最终选择的是跳表,而不是B+ tree。

由于跳表的查询复杂度在O(logn),因此redis中zset数据类型底层结合使用skiplist和hash,用空间换时间,利用跳表支持范围查询和有序查询,利用hash支持精确查询。

小结

  • B+ 树是多路平衡搜索树,扇出高,三层高度即可容纳2kw左右的数据,相同情况下,跳表则需要大约24层,假设层高对应磁盘IO,那么B+树的读性能会比跳表要好,因此Innodb选择了B+树做索引
  • redis读写全在内存中,不涉及磁盘IO,无需考虑索引层高度,同时由于跳表实现起来更加简单,相比B+ tree而言,少了选择树结构的开销,因此redis使用跳表来实现zset,而不是B+ tree。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-03-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Mysql的索引为什么使用B+树而不使用跳表?
直接遍历这一行行数据,性能就是O(n),比较慢。为了加速查询,使用了B+树来做索引,将查询性能优化到了O(lg(n))。
小白debug
2022/06/20
9740
Mysql的索引为什么使用B+树而不使用跳表?
跳表:为什么Redis一定要用跳表来实现有序集合?
时间复杂度O(logn)的二分查找很高效,但是依赖数组随机访问的特性,如果是链表,如何做到O(logn)?
Yuyy
2022/11/16
8110
跳表:为什么Redis一定要用跳表来实现有序集合?
LSM-Tree - LevelDb Skiplist跳表
跳表(SkipList)是由William Pugh提出的。他在论文《Skip lists: a probabilistic alternative to balanced trees》中详细地介绍了有关跳表结构、插入删除操作的细节。
阿东
2022/05/19
6120
LSM-Tree - LevelDb Skiplist跳表
顺丰面试,第二个问题把我劝退了!
本文主人翁是我星球里一位同学,周一线上顺丰面试遇到的问题,反馈面经时,只记得部分的。
田维常
2023/02/16
5490
顺丰面试,第二个问题把我劝退了!
mysql索引
这里是为后续的mysql调优做准备,要像做到mysql调优,索引很关键,理解索引结构,页结构,对于调优来说是很重要的基础。
Joseph_青椒
2023/08/02
2760
mysql索引
MySQL数据库索引选择为什么使用B+树而不是跳表?
在进一步分析为什么MySQL数据库索引选择使用B+树之前,我相信很多小伙伴对数据结构中的树还是有些许模糊的,因此我们由浅入深一步步探讨树的演进过程,在一步步引出B树以及为什么MySQL数据库索引选择使用B+树!
小冷coding
2023/05/24
7360
MySQL数据库索引选择为什么使用B+树而不是跳表?
跳表
我们可以对链表加一层索引。具体来说,可以每两个结点提取一个结点到上一级,我们把抽出来的那一级叫作索引或索引层。索引节点中通过一个 down 指针,指向下一级结点。通过这样的改造,就可以支持类似二分查找的算法。我们把改造之后的数据结构叫作跳表(Skip list)。
硬件开源小站
2023/04/07
3520
Redis的ZSet底层数据结构,ZSet类型全面解析
详细介绍:Redis五种数据类型、String、List、Set、Hash、ZSet
寻求出路的程序媛
2024/11/03
2050
Redis的ZSet底层数据结构,ZSet类型全面解析
Mysql为什么最终用B+树做索引?
索引能极大的减少存储引擎需要扫描的数据量 索引可以把随机IO变成顺序IO(索引指向(左小右大)) 索引可以帮助我们在进行分组、排序等操作时,避免使用临时表
名字是乱打的
2021/12/22
1.2K0
Mysql为什么最终用B+树做索引?
面试官:为何Redis使用跳表而非红黑树实现SortedSet?
知道跳表(Skip List)是在看关于Redis的书的时候,Redis中的有序集合使用了跳表数据结构。接着就查了一些博客,来学习一下跳表。后面会使用Java代码来简单实现跳表。
JavaEdge
2021/12/07
5330
面试官:为何Redis使用跳表而非红黑树实现SortedSet?
mysql 中的innoDB 引擎的B+树索引
在优化慢接口的时候,遇到一个问题,在通过索引查询数据库表的时候根据时间区间去扫描表的时候,开始时间时表扫描的其实位置吗?或者说根据时间日期B+索引能一次性定位到具体的时间位置吗?是的不能。那为什么不能呢? 接下来我们来看看b+树索引的底层数据结构。
袁新栋-jeff.yuan
2020/08/26
9540
mysql 中的innoDB 引擎的B+树索引
数据结构与算法系列之跳表(GO)
前边的一篇文章中分享了二分查找算法,里边有说到二分查找算法依赖数组的随机访问特性,只能用数组来实现。如果数据存储在链表中就没法用二分查找算法了
书旅
2020/12/03
4890
女朋友问我:为什么 MySQL 喜欢 B+ 树?我笑着画了 20 张图
要解释这个问题,其实不单单要从数据结构的角度出发,还要考虑磁盘 I/O 操作次数,因为 MySQL 的数据是存储在磁盘中的嘛。
小林coding
2021/12/27
7120
女朋友问我:为什么 MySQL 喜欢 B+ 树?我笑着画了 20 张图
浅析skiplist(跳表)
跳表由William Pugh 1989年发明。他在论文《Skip lists: a probabilistic alternative to balanced trees》中详细介绍了跳表的数据结构和插入删除等操作。论文是这么介绍跳表的:
山行AI
2019/06/28
2.6K0
Mysql-为什么使用B+树
https://www.bilibili.com/video/BV1yT4y1w7FS?from=search&seid=1538805982597498566&spm_id_from=333.337.0.0
Get
2024/03/10
1560
Redis03-Redis的数据结构之跳表
上一篇文章我们介绍了字典这个数据结构,这一篇文章我们接着来学习下另外一个数据结构,跳表。那么什么是跳表呢?
码农飞哥
2021/08/18
4500
Mysql InnoDB 为啥选择B+树索引 转
Mysql数据库中的常见索引有多种方式,例如Hash索引,B-树索引,B+树索引,但是为啥mysql中默认是采用B+树索引索引呢?下面对这三种索引学习总结一下。B+树到底有啥优势? B-树
双面人
2019/04/10
6630
MySQL为什么要使用B+树索引
搞懂这个问题之前,我们首先来看一下MySQL表的存储结构,再分别对比二叉树、多叉树、B树和B+树的区别就都懂了。
BUG弄潮儿
2021/02/03
5650
MySQL为什么要使用B+树索引
数据结构-跳表
跳表这种数据结构对你来说,可能会比较陌生,因为一般的数据结构和算法书籍里都不怎么会讲。但是它确实是一种各方面性能都比较优秀的动态数据结构,可以支持快速地插入、删除、查找操作,写起来也不复杂,甚至可以替代红黑树(Red-black tree)。
acc8226
2022/05/17
3290
数据结构-跳表
mysql b+树优点_基础B
大家在面试的时候,肯定都会被问到MySql的知识,以下是面试场景: 面试官:对于MySQL,你对他索引原理了解吗? 我:了解 面试官:MySQL的索引是用什么数据机构的? 我:B+树 面试官:为什么要用B+树,而不是B树? 我:… 面试官:用B+树作为MySql的索引结构,用什么好处? 我:…
全栈程序员站长
2022/11/16
6300
mysql b+树优点_基础B
相关推荐
Mysql的索引为什么使用B+树而不使用跳表?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档