为什么redis用跳表不用b+树,而mysql用b+树而不是跳表?

news/2024/12/3 5:16:07/

写在前面

上一篇文章中,我们深度解析了redis中的跳表结构,而b+树的结构我们很久之前就讲过了,那么我们知道了redis的有序集合用的是跳表,而mysql的innodb引擎用的是b+树存储,但这是为什么呢?为什么redis用跳表不用b+树,而mysql用b+树而不是跳表?这篇文章我们就来讲一下。

1. B+树和跳表结构对比

我们分别对这两个结构进行读、写操作两个场景来做分析。

1.1 B+树结构

在这里插入图片描述

  • 读操作:我们知道 B+树 的结构中每个结点都是一个16k的数据页,能存放较多的索引信息,三层左右就可以存储3kw左右的数据。查询一次数据,最多三次磁盘IO。
  • 写操作:随着数据的增加,B+树为了保持自身平衡而需要调整自身的树高,这背后有相对复杂逻辑来做平衡调整。

所以B+树这类数据结构适合大量数据(相比于redis),而大量的数据肯定不能全放内存里,必定是需要存放在磁盘,而磁盘的读写又很慢,B+数的灵魂在于索引,索引作用是为了加速磁盘io

但是redis又是一个内存数据库,索引在内存中的作用不大了,相反B+数复杂的平衡逻辑会使得插入变慢,redis这类追求高速的单进程数据库是不建议有这类慢操作的。

1.2 跳表结构

在这里插入图片描述

  • 读操作:一个结点存放一条数据,如果像上面的mysql一样存储3kw左右的数据,即使每次都能达到最优的二分,也要找2的25次方左右。 当然redis也不会有哪个key会存储3kw的数据,这就算大key了,是不允许的。而且与磁盘io不同,内存是很快的。
  • 写操作:与拆分合并数据页不同,一个节点直接插入一条数据。逻辑相对来说比较简单,也很快速,没有平衡的复杂过程。

2. 总结

Redis 使用跳表的原因:

  • 内存数据库,查询、插入、删除的效率高,且实现简单,适合高并发、低延迟的内存操作。
  • 内存管理灵活,不需要像 B+树那样复杂的节点分裂和合并操作,这些操作也比较耗时。并且B+的最大的索引优势在内存中作用不大。

MySQL 使用 B+树的原因:

  • 适合磁盘存储和大规模数据,能够高效进行范围查询和排序,支持复杂的事务管理。
  • 适合持久化存储,在数据量很大的情况下,通过索引结构能够优化磁盘 I/O,B+树能够保持查询性能。

参考

[1] https://15721.courses.cs.cmu.edu/spring2018/papers/08-oltpindexes1/pugh-skiplists-cacm1990.pdf
[2] https://opensource.googleblog.com/2013/01/c-containers-that-save-memory-and-time.html


http://www.ppmy.cn/news/1551915.html

相关文章

【新人系列】Python 入门(十四):文件操作

✍ 个人博客:https://blog.csdn.net/Newin2020?typeblog 📝 专栏地址:https://blog.csdn.net/newin2020/category_12801353.html 📣 专栏定位:为 0 基础刚入门 Python 的小伙伴提供详细的讲解,也欢迎大佬们…

HCIE IGP双栈综合实验

实验拓扑 实验需求及解法 本实验模拟ISP网络结构,R1/2组成国家骨干网,R3/4组成省级网络,R5/6/7组成数据中 心网络。 配置所有ipv4地址,请自行测试直连。 R1 sysname R1 interface GigabitEthernet0/0/0ip address 12.1.1.1 255.…

Flink 离线计算

文章目录 一、样例一&#xff1a;读 csv 文件生成 csv 文件二、样例二&#xff1a;读 starrocks 写 starrocks三、样例三&#xff1a;DataSet、Table Sql 处理后写入 StarRocks四、遇到的坑 <dependency><groupId>org.apache.flink</groupId><artifactId&…

C++11新增特性2

一.lambda 1.本质&#xff1a;lambda对象是⼀个匿名函数对象&#xff0c;它可以定义在函数内部。 注&#xff1a;lambda表达式语法使⽤层⽽⾔没有类型&#xff0c;所以我们⼀般是⽤auto或者模板参数定义的对象去接收lambda对象。 2.表达式&#xff1a;[capture-list] (param…

跨平台应用开发框架(3)-----Qt(样式篇)

目录 1.QSS 1.基本语法 2.QSS设置方式 1.指定控件样式设置 2.全局样式设置 1.样式的层叠特性 2.样式的优先级 3.从文件加载样式表 4.使用Qt Designer编辑样式 3.选择器 1.类型选择器 2.id选择器 3.并集选择器 4.子控件选择器 5.伪类选择器 4.样式属性 1.盒模型 …

分布式锁的实现原理

作者&#xff1a;来自 vivo 互联网服务器团队- Xu Yaoming 介绍分布式锁的实现原理。 一、分布式锁概述 分布式锁&#xff0c;顾名思义&#xff0c;就是在分布式环境下使用的锁。众所周知&#xff0c;在并发编程中&#xff0c;我们经常需要借助并发控制工具&#xff0c;如 mu…

opengl 三角形

最后效果&#xff1a; OpenGL version: 4.1 Metal 不知道为啥必须使用VAO 才行。 #include <glad/glad.h> #include <GLFW/glfw3.h>#include <iostream> #include <vector>void framebuffer_size_callback(GLFWwindow *window, int width, int heigh…

Unity类银河战士恶魔城学习总结(P150 End Screen结束重启按钮)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址&#xff1a;https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了死亡后重新启动游戏&#xff0c;并且加入了游戏管理器 加入了重新开始游戏的按钮 GameManager.cs using System.Collection…