Mysql InnoDB B+Tree是什么?
“mysql中常用的数据库搜索引擎InnoDB,其索引通过B+Tree的方式进行构建。”
实在想不起来B+Tree是怎么一回事了。以点带线,将涉及到的数据结构一起复习一下。
文章目录
- 数据结构定义
- 红黑树
- 定义
- 使命
- BTree
- 定义
- 使命
- B+Tree
- 定义
- InnoDB B+Tree
- 旋转与调整
- 二叉排序树
- 插入
- 删除
- 平衡二叉树
- 插入
- 删除
- 红黑树
- 插入
- 删除
- m阶BTree
- 插入
- 删除
- m 阶B+Tree
- 插入
- 删除
- 参考内容
数据结构定义
数据结构 | 定义 |
---|---|
二叉树 | 每个节点最多有两个子树 |
二叉排序树 | 又叫二叉搜索树。在二叉树的基础上,递归定义 任意子树根节点大于其左子树最大值小于右子树最小值. 左<根<右 |
平衡二叉树 | 在二叉排序树的基础上, 递归定义 任意节点 左右子树的高度差≤1. |
红黑树 | 在二叉排序树的基础上,递归定义 见下方 |
BTree | B-Tree 同一个东西。见下方 |
B+Tree | 见下方 |
如果插入的是有序序列, 二叉排序树的效率降低为O(n). 所以推出 平衡二叉树
红黑树
定义
- 左中右: 前提是一棵二叉搜索树(左<中<右)
- 根、叶黑: 根节点和叶子结点都是黑色
- 不红红: 不存在两个红色节点有直接父子关系
- 黑路同: 任意节点到所有叶子节点经过的黑色节点数相同
使命
红黑树并不是在平衡二叉树的基础上定义的。
由于平衡二叉树左右子树高度差≤1,要求过于严格。虽然查询效率较高,但插入、删除时,调整频繁, 因此引入红黑树。
由于不红红和黑路同的性质可以推断出:红黑树左右子树最长路径节点数不超过最短路径的2倍。
相对于平衡二叉树,插入、删除效率有所提升。
BTree
BTree 就是多路查找树(一个节点内可以有多个元素),每个元素都有左右子树。 2阶BTree, 退化成平衡二叉树
定义
-
有序 1. 结点元素内有序 2. 元素的左子树都小于它,右子树都大于它
-
平衡 所有的叶结点都在同一层
-
节点限制 m阶BTree
根节点至少有1个元素,2个分支
其他节点 至少有(m+1)/2个分支, (m-1)/2个元素(左右间隙肯定要比元素数多1)
所有节点元素数<m, 分支数≤m。 所有叶子节点在同一层上
使命
数据是存储在磁盘上,每次将节点读入内存,就需要一次IO操作,IO操作是比较耗时。树的高度,限制了数据的查找效率。
一次IO读取连续地址的多个字节和读取一个字节几乎没有什么差别。
通过增加节点元素数,降低树的高度 就成为了必然的选择。
一个节点可以有多个元素 每个元素左右间隙指向后续节点。将左右间隙视为左右子树。
B+Tree
定义
从BTree基础上发展而来,
- 非叶子结点直接存储索引,>左子树最大值,<=右子树最小值
- 叶结点包含全部关键字及指向相应记录的指针,非叶结点只作索引
- 所有节点元素数<m(也有地方说是<=m), 分支数≤m
- 每一个叶子节点都有指向后续叶子节点的指针
InnoDB B+Tree
对经典B+Tree进行改造,除了记录叶子节点的头部位置,后续叶子节点外, 记录了前驱节点。提升了中序遍历和范围查找效率。
旋转与调整
二叉树就是为了阐述的需要,没有实际应用的意义,不存在调整的问题。
二叉排序树
插入
与当前节点比较, 小于当前节点在左子树进行比较 大于当前节点在右子树进行比较。
最后插入到叶子节点上。
Insert 4 2 3 1
删除
通过比较查找定位到待删除的节点
叶子节点,直接删除
只有左子树或只有右子树 删除后,让子树占据其位置
左右子树都有 需要进行转化 让其中序遍历前驱节点或后继结点占据其位置,转化为删除中序遍历前驱节点或后继结点。转化为前两种情况。
演示一下删除节点50的过程
- 节点50左右子树都有,使用中序遍历定位后继节点。将节点65放到节点50的位置
- 待删除的节点只有右子树, 将右子树直接挂上
平衡二叉树
插入
通过递归进行节点比较,插入到叶子节点。 然后判定是否出现左右子树高度差>1的情况。
没有出现, 插入结束。否则根据下面四种情况进行调整
类型 | 调整方式 |
---|---|
LL | 爷爷节点顺时针旋转(右旋) |
RR | 爷爷节点逆时针旋转(左旋) |
LR | 父节点逆时针旋转,爷爷节点顺时针旋转(右旋) |
RL | 父节点顺时针旋转,爷爷节点逆时针旋转(左旋) |
所有的旋转都是绕着直接子孩子进行的旋转。 调整之后, 高度-1. 调整完成。
删除
分为两个过程
- 删除 删除方法与二叉搜索树相同
- 调整 找到层级最低(靠近叶子节点)失衡的节点C,然后确定类型和调整方式
找到C层级更深的子树A.
找到A层级更深的子树B.
AB对应上面的LL、RR、LR、RL四种情况,然后进行调整。
这里面有一种特殊情况: B不存在(A的左右子树深度一致)
如果是L型(A是左子树),进行顺时针旋转.如果是R型,进行逆时针旋转。
红黑树
插入
红黑树的插入容易违反:根叶黑和不红红的特性。
新插入的节点定义为红色
分下面几种情况进行讨论:
1. 新插入节点是根节点: 直接变黑 调整完成
2. 新插入节点的父节点是黑节点: 不需要调整
3. 新插入节点的父节点是红节点: 违反不红红的特点,参照下面的方法进行调整。
2.插入的是红色节点, 父亲是红色节点
如果叔叔是黑色,违反黑路同;
如果叔叔为红色,不能有子节点(红色违反不红红,黑色违反黑路同)
叔叔节点 | 调整方式 |
---|---|
R | 叔叔节点R->B, 父亲节点R->B,爷爷节点B->R, 从爷爷开始继续调整(不违反根叶黑、不红红就完成) |
不存在(或者为黑色节点) | 插入节点、父节点、爷爷节点 根据LL\RR\LR\RL进行旋转调整 |
变换后,设置新根节点(三个节点中)为黑色,其他2个节点为红色.
来一个插入演示。
Insert 34、23、15、10、13、14、35、36.
删除
红黑树删除容易破坏黑路同的性质。
通过节点比较 定位到要删除的节点
与二叉搜索树一样:如果左右子树都有 转化为中序遍历直接前驱或者直接后继(将节点内容用直接前驱或直接后继的值进行代替), 转化为对叶子节点或者单子树的删除。
叶子节点可能为红或者黑;
单子树只可能为黑色节点下面挂一个红色节点。
待删除节点为红色叶子节点,直接删除
待删除节点有单子树,将红色节点挂到子树上,变成黑色。
待删除节点为黑色叶子节点较为复杂:
兄弟节点颜色 | 兄弟节点有红孩 | 调整方式 |
---|---|---|
B | 有 | 待删除节点变成双黑节点 根据其类型参照下面表格进行旋转变色。 |
B | 无 | 兄弟变红, 双黑节点(可以理解为-1黑节点)上移到父节点 |
R | 无 | 兄父变色, 然后父节点绕兄弟节点旋转 双黑节点继续调整 |
双黑节点碰到红色节点 Red->Black 调整结束。
双黑碰到根节点, 直接变成黑节点 调整结束。
双黑节点碰到兄弟节点是null,调整结束。
删除节点为黑色节点,兄弟节点为黑色节点,兄弟至少有一个红孩
表格中的孩子指的是:兄弟的孩子,父节点指的是:当前节点的父节点(当然也是兄弟父节点)
变色和旋转情况如下:
兄弟 | 兄弟左孩子 | 兄弟右孩子 | 类型 | 变色与旋转 |
---|---|---|---|---|
左子树 | R | - | LL | 左孩子R->B, 兄弟节点变成父节点颜色, 父节点变黑。 然后进行旋转 |
右子树 | - | R | RR | 右孩子R->B, 兄弟节点变成父节点颜色, 父节点变黑。 然后进行旋转 |
左子树 | B(或者null) | R | LR | 右孩子变成父节点颜色, 父节点变黑。 然后进行旋转 |
右子树 | R | - | RL | 左孩子变成父节点颜色,父节点变黑。 然后进行旋转 |
删除顺序:
17 15 13 34 25 23 18 27 37 10 9 6
m阶BTree
插入
所有直接的插入都在叶子节点进行(从根节点定位到叶子节点);
1. 只有一个元素作为根节点
2. 从根部进行比较, 跳转到叶子节点后, 进行插入。
如果节点元素数=m, 需要进行分裂。 m/2位置元素上移, 以该元素作为分界点,将一个节点拆分为两个节点。然后将比较节点(m/2位置元素)移动到父节点。 继续判断父节点是否发生上溢, 继续进行调整。
m = 3
插入序列:
27 14 18 36 70 3 17 20 23 34 45 53 58 84
删除
- 定位到要删除的元素,如果发生在非叶子节点: 将中序遍历直接前驱或直接后继进行替换。 修改为删除直接前驱或直接后继节点
删除后,节点元素数>= (m-1)/2,结束.
如果<(m-1)/2,寻找左兄弟节点或者右兄弟节点进行借元素。
寻找左兄弟借元素 ,左兄弟 最大值上位, 父节点里面的父元素移动到节点左侧。
寻找右兄弟借元素 ,右兄弟 最小值上位, 父节点里面的父元素移动到节点右侧。
如果左右兄弟都不够借, 就与左兄弟或右兄弟合并。 与左兄弟合并的时候, 父节点的父元素下移到左兄弟,然后当前节点所有元素合并到左兄弟节点右侧。 此时, 如果父节点发生向下溢出,对父节点继续调整, 否则,调整结束。
m=3 最小节点数 (3-1)/2 == 1 ,不存在向下溢出的情况了, 这里使用m=5.进行演示
84 36 90 58 70 53 34 27 45 21 20 23 17
m 阶B+Tree
B+Tree所有元素都保存在叶子节点
插入都发生在叶子节点,进行分裂时, 分裂点左侧断裂, 向上copy一份中间元素。
左侧指向的索引节点小于当前索引值,右侧>=当前索引值
叶子节点有指向中序遍历后续叶子节点的指针。
插入
m = 5.
插入序列:
27 14 18 36 70 3 17 20 23 34 45 53 58 84 90
删除
删除非索引节点时,直接删除。
发生向下溢出,左右可以借的话, 进行左右借位。借位后,索引修改为借到元素,并将该元素合并过去
如果不够借,进行作用合并,注意索引的调整。 以及可能发生的父节点向下溢出。
删除序列:
53 36 34 20 58 70 20 84 14 27 45 18
参考内容
B站蓝不过海呀数据结构教学视频
旧金山大学数据结构可视化工具
相关文章:

Mysql InnoDB B+Tree是什么?
“mysql中常用的数据库搜索引擎InnoDB,其索引通过BTree的方式进行构建。” 实在想不起来BTree是怎么一回事了。以点带线,将涉及到的数据结构一起复习一下。 文章目录 数据结构定义红黑树定义使命 BTree定义使命 BTree定义 InnoDB BTree 旋转与调整二叉排序树插入删…...
Java基础(二)
提示:这部分内容对逆向重要,需重点掌握。 1.常见数据类型 1.1 List系列 类似于Python中的列表 List是一个接口,接口下面有两个常见的类型(目的是可以存放动态的多个数据) ArrayList,连续的内存地址存储(内部自动扩容) -> Python列表的特点LinkedList,底层基于链表…...
【网络协议】【http】【https】TLS1.3
【网络协议】【http】【https】TLS1.3 TLS1.3它的签名算法和密钥交换算法,默认情况下是被固定了下来的,他的加密套件里面呢,只包含了对称加密算法和摘要算法 客户端和服务器第一次连接 仍然需要1RTT ,不能0-RTT 第一次连接 1.客…...
K8S中Pod控制器之Job控制器
Job,主要用于负责批量处理(一次要处理指定数量任务)短暂的一次性(每个任务仅运行一次就结束)任务。 一次性任务:Job 用于运行那些只需要执行一次的任务,如数据分析、图像渲染或批量处理。 成功终止:Job 会跟踪其创建的 Pod 的成功…...

macOS安装Gradle环境
文章目录 说明安装JDK安装Gradle 说明 gradle8.5最高支持jdk21,如果使用jdk22建议使用gradle8.8以上版本 安装JDK mac系统安装最新(截止2024.9.13)Oracle JDK操作记录 安装Gradle 下载Gradle,解压将其存放到资源java/env目录…...

2024年美赛C题评委文章及O奖论文解读 | AI工具如何影响数学建模?从评委和O奖论文出发-O奖论文做对了什么?
模型假设仅仅是简单陈述吗?允许AI的使用是否降低了比赛难度?还在依赖机器学习的模型吗?处理题目的方法有哪些?O奖论文的优点在哪里? 本文调研了当年赛题的评委文章和O奖论文,这些问题都会在文章中一一解答…...

LDD3学习9--数据类型和定时器
这部分对应的是第七章和第十一章,因为内容也不是很多,就一起写了。里面的内容基本上就是一个个的点,所以也就一个个点简单总结一下。 1 数据类型 1.1 数据长度 不同操作系统类型长度可能不一样,看图的话最好用u8,u16&…...

一文夯实垃圾收集的理论基础
如何判断一个引用是否存活 引用计数法 给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使用的。 优点:可即刻回收垃圾&a…...
OpenWRT Conserver 共享串口服务实现
安装驱动 查看当前可在线安装的USB驱动 opkg update 查看安装的USB驱动 opkg list-installed *usb-serial* 查看所有的USB串口驱动 opkg list *usb-serial* 确认console线的芯片厂商 kmod-usb-serial-pl2303 - 5.15.167-1 - Kernel support for Prolific PL2303 USB-to…...
第12章:Python TDD完善货币加法运算(一)
写在前面 这本书是我们老板推荐过的,我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后,我突然思考,对于测试开发工程师来说,什么才更有价值呢?如何让 AI 工具更好地辅助自己写代码,或许…...
Springboot项目Jackson支持多种接收多种时间格式
前言 在springboot项目中经常会使用Jackson框架,当前端给后端传输时间类型时,我们一般需要先配置好时间格式,否则后端无法接收。以下是一些配置方法 统一配置 spring:jackson:time-zone: GMT+8date-format: yyyy-MM-dd HH:mm:ss这种配置就是要求前端统一传输的格式是yyyy-…...
两台电脑互PING不通的解决办法
当两台电脑无法通过网络Ping通时,可以按照以下步骤进行排查和解决: 一. 检查网络连接 确保两台电脑连接到同一个局域网。 如果是通过网线连接,检查网线是否松动或损坏。 如果是无线连接,确保Wi-Fi信号正常。 二. 检查IP配置 确…...

No. 34 笔记 | Python知识架构与数据类型相关内容 | 实操
在今天的Python学习中,我对Python的知识架构有了更深入的理解,同时也对Python的数据类型及其操作有了全面的认识和实践。 一、Python知识架构理解 Python是一门功能强大且应用广泛的编程语言,其知识架构可以从多个层面来理解。 从整体结构上…...

【2024年华为OD机试】 (B卷,100分)- 字符串分割(Java JS PythonC/C++)
一、问题描述 题目解析 问题描述 给定一个非空字符串 s,要求将该字符串分割成若干子串,使得每个子串的 ASCII 码值之和均为“水仙花数”。具体要求如下: 若分割不成功,则返回 0;若分割成功且分割结果不唯一,则返回 -1;若分割成功且分割结果唯一,则返回分割后子串的数…...

Pix2Pix :用于图像到图像转换的条件生成对抗网络
1. 背景与问题 图像到图像的转换(Image-to-Image Translation)是计算机视觉中的一个重要任务,指的是在输入一张图像的情况下,生成一张风格、内容或其他条件不同但语义一致的图像。随着深度学习的发展,尤其是生成对抗网…...

基于VSCODE+GDB+GDBSERVER远程单步调试设备篇(可视化界面)
目录 说明 配置方法 1)VSCODE必备插件 2)配置launch.json文件,用于GDB调试 调试步骤 目标板运行程序 1)已启动程序,通过attach方式进入调试 2)通过gdbserver启动时加载程序(程序路径根据实际情…...

CamemBERT:一款出色的法语语言模型
摘要 预训练语言模型在自然语言处理中已无处不在。尽管这些模型取得了成功,但大多数可用模型要么是在英语数据上训练的,要么是在多种语言数据拼接的基础上训练的。这使得这些模型在除英语以外的所有语言中的实际应用非常有限。本文探讨了为其他语言训练…...

0基础跟德姆(dom)一起学AI 自然语言处理18-解码器部分实现
1 解码器介绍 解码器部分: 由N个解码器层堆叠而成每个解码器层由三个子层连接结构组成第一个子层连接结构包括一个多头自注意力子层和规范化层以及一个残差连接第二个子层连接结构包括一个多头注意力子层和规范化层以及一个残差连接第三个子层连接结构包括一个前馈全连接子层…...

我的创作纪念日——我与CSDN一起走过的365天
目录 一、机缘:旅程的开始 二、收获:沿路的花朵 三、日常:不断前行中 四、成就:一点小确幸 五、憧憬:梦中的重点 一、机缘:旅程的开始 最开始开始写博客是在今年一二月份的时候,也就是上一…...

C++:bfs解决多源最短路与拓扑排序问题习题
1. 多源最短路 其实就是将所有源头都加入队列, 01矩阵 LCR 107. 01 矩阵 - 力扣(LeetCode) 思路 求每个元素到离其最近0的距离如果我们将1当做源头加入队列的话,无法处理多个连续1的距离存储,我们反其道而行之&…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...

通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...