Mysql InnoDB B+Tree是什么?

“mysql中常用的数据库搜索引擎InnoDB,其索引通过B+Tree的方式进行构建。”

实在想不起来B+Tree是怎么一回事了。以点带线,将涉及到的数据结构一起复习一下。

文章目录

  • 数据结构定义
    • 红黑树
      • 定义
      • 使命
    • BTree
      • 定义
      • 使命
    • B+Tree
      • 定义
    • InnoDB B+Tree
  • 旋转与调整
    • 二叉排序树
      • 插入
      • 删除
    • 平衡二叉树
      • 插入
    • 删除
    • 红黑树
      • 插入
      • 删除
    • m阶BTree
      • 插入
      • 删除
    • m 阶B+Tree
      • 插入
      • 删除
  • 参考内容

数据结构定义

数据结构
定义
二叉树每个节点最多有两个子树
二叉排序树又叫二叉搜索树。在二叉树的基础上,递归定义 任意子树根节点大于其左子树最大值小于右子树最小值. 左<根<右
平衡二叉树在二叉排序树的基础上, 递归定义 任意节点 左右子树的高度差≤1.
红黑树在二叉排序树的基础上,递归定义 见下方
BTreeB-Tree 同一个东西。见下方
B+Tree见下方

如果插入的是有序序列, 二叉排序树的效率降低为O(n). 所以推出 平衡二叉树

红黑树

定义

  1. 左中右: 前提是一棵二叉搜索树(左<中<右)
  2. 根、叶黑: 根节点和叶子结点都是黑色
  3. 不红红: 不存在两个红色节点有直接父子关系
  4. 黑路同: 任意节点到所有叶子节点经过的黑色节点数相同

使命

红黑树并不是在平衡二叉树的基础上定义的。

由于平衡二叉树左右子树高度差≤1,要求过于严格。虽然查询效率较高,但插入、删除时,调整频繁, 因此引入红黑树。

由于不红红和黑路同的性质可以推断出:红黑树左右子树最长路径节点数不超过最短路径的2倍。

相对于平衡二叉树,插入、删除效率有所提升。

BTree

BTree 就是多路查找树(一个节点内可以有多个元素),每个元素都有左右子树。 2阶BTree, 退化成平衡二叉树

定义

  1. 有序 1. 结点元素内有序 2. 元素的左子树都小于它,右子树都大于它

  2. 平衡 所有的叶结点都在同一层

  3. 节点限制 m阶BTree

    根节点至少有1个元素,2个分支

    其他节点 至少有(m+1)/2个分支, (m-1)/2个元素(左右间隙肯定要比元素数多1)

    所有节点元素数<m, 分支数≤m。 所有叶子节点在同一层上

使命

数据是存储在磁盘上,每次将节点读入内存,就需要一次IO操作,IO操作是比较耗时。树的高度,限制了数据的查找效率。

一次IO读取连续地址的多个字节和读取一个字节几乎没有什么差别。

通过增加节点元素数,降低树的高度 就成为了必然的选择。

一个节点可以有多个元素 每个元素左右间隙指向后续节点。将左右间隙视为左右子树。

B+Tree

定义

从BTree基础上发展而来,

  1. 非叶子结点直接存储索引,>左子树最大值,<=右子树最小值
  2. 叶结点包含全部关键字及指向相应记录的指针,非叶结点只作索引
  3. 所有节点元素数<m(也有地方说是<=m), 分支数≤m
  4. 每一个叶子节点都有指向后续叶子节点的指针

请添加图片描述

InnoDB B+Tree

对经典B+Tree进行改造,除了记录叶子节点的头部位置,后续叶子节点外, 记录了前驱节点。提升了中序遍历和范围查找效率。

旋转与调整

二叉树就是为了阐述的需要,没有实际应用的意义,不存在调整的问题。

二叉排序树

插入

与当前节点比较, 小于当前节点在左子树进行比较 大于当前节点在右子树进行比较。
最后插入到叶子节点上。

Insert 4 2 3 1

请添加图片描述

删除

通过比较查找定位到待删除的节点

叶子节点,直接删除

只有左子树或只有右子树 删除后,让子树占据其位置

左右子树都有 需要进行转化 让其中序遍历前驱节点或后继结点占据其位置,转化为删除中序遍历前驱节点或后继结点。转化为前两种情况。

演示一下删除节点50的过程

请添加图片描述

  1. 节点50左右子树都有,使用中序遍历定位后继节点。将节点65放到节点50的位置
  2. 待删除的节点只有右子树, 将右子树直接挂上

平衡二叉树

插入

通过递归进行节点比较,插入到叶子节点。 然后判定是否出现左右子树高度差>1的情况。
没有出现, 插入结束。否则根据下面四种情况进行调整

类型调整方式
LL爷爷节点顺时针旋转(右旋)
RR爷爷节点逆时针旋转(左旋)
LR父节点逆时针旋转,爷爷节点顺时针旋转(右旋)
RL父节点顺时针旋转,爷爷节点逆时针旋转(左旋)

平衡树调整的四种类型

所有的旋转都是绕着直接子孩子进行的旋转。 调整之后, 高度-1. 调整完成。

删除

分为两个过程

  1. 删除 删除方法与二叉搜索树相同
  2. 调整 找到层级最低(靠近叶子节点)失衡的节点C,然后确定类型和调整方式
    找到C层级更深的子树A.
    找到A层级更深的子树B.
    AB对应上面的LL、RR、LR、RL四种情况,然后进行调整。

这里面有一种特殊情况: B不存在(A的左右子树深度一致)
如果是L型(A是左子树),进行顺时针旋转.如果是R型,进行逆时针旋转。

A存在B不存在

红黑树

插入

红黑树的插入容易违反:根叶黑和不红红的特性。

新插入的节点定义为红色

分下面几种情况进行讨论:

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, 兄弟节点变成父节点颜色, 父节点变黑。 然后进行旋转
右子树-RRR右孩子R->B, 兄弟节点变成父节点颜色, 父节点变黑。 然后进行旋转
左子树B(或者null)RLR右孩子变成父节点颜色, 父节点变黑。 然后进行旋转
右子树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

请添加图片描述

删除

  1. 定位到要删除的元素,如果发生在非叶子节点: 将中序遍历直接前驱或直接后继进行替换。 修改为删除直接前驱或直接后继节点

删除后,节点元素数>= (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

B+Tree插入

删除

删除非索引节点时,直接删除。
发生向下溢出,左右可以借的话, 进行左右借位。借位后,索引修改为借到元素,并将该元素合并过去
如果不够借,进行作用合并,注意索引的调整。 以及可能发生的父节点向下溢出。

删除序列:

53 36 34 20 58 70 20 84 14 27 45 18

B+Tree删除

参考内容

B站蓝不过海呀数据结构教学视频
旧金山大学数据结构可视化工具

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/893195.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB基础应用精讲-【数模应用】粒子群与遗传算法相结合(PSO-GA)应用(附MATLAB代码实现)

目录 前言 几个高频面试题目 遗传算法、粒子群优化算法和强化学习对比 1 遗传算法(Genetic Algorithm, GA) 2 粒子群优化算法(Particle Swarm Optimization, PSO) 3 强化学习(Reinforcement Learning, RL) 4 遗传算法、粒子群优化算法和强化学习在智能方面的比较。…

对人型机器人的研究和展望

目录 概述 1 核心软硬件部件 1.1 运动控制部分 1.1.1 减速机 1.1.2 编码器 1.1.3 直流无刷电机 1.2 智能仿生手 1.3 控制板卡 2 人型机器人的应用 3 未来展望 概述 如果现在有人问&#xff1a;当前那个行业最火&#xff1f;毫无疑问答案肯定是人型机器人了。当前各类机…

Flask:后端框架使用

文章目录 1、介绍2、demo演示3、Flask请求和响应 3.1 演示demo3.2 request获取请求体数据3.3 requests发送请求3.4 响应返回和接收 4、特殊路由 4.1 路由重定向4.2 路由拦截器 1、介绍 Flask是由python语言编写的轻量级Web应用框架&#xff0c;主要应用于后端框架&#xff…

递归算法学习v2.3

目标和 设置全局变量&#xff1a; class Solution {int ret,path,aim;public int findTargetSumWays(int[] nums, int target) {aim target;dfs(nums,0);return ret;}public void dfs(int[] nums,int pos){if(pos nums.length){if(path aim){ret ;}return;}path nums[pos…

红黑树封装map和set(c++版)

前言 在前面&#xff0c;我们介绍了c中map和set库的使用&#xff0c;也实现了一颗简单的红黑树。那么现在我们就利用这两部分的知识&#xff0c;实现一个简单的myMap和mySet。 源码阅读 在我们实现之前&#xff0c;我们可以阅读一些标准库的实现&#xff0c;学习标准库的实现…

Windows 服务程序实现鼠标模拟

cpp #include <windows.h> #include <fstream> #include <string> #include <tchar.h> #include <thread> #include <vector> #define SERVICE_NAME _T("MouseSimulationService") // 全局变量 SERVICE_STATUS g_Servi…

ui设计公司分享:浅色 UI 设计

在数字化产品琳琅满目的今天&#xff0c;用户对于界面的要求早已不止于功能的实现&#xff0c;更追求一种舒适、无压的交互体验。而浅色UI设计&#xff0c;凭借其独特的魅力&#xff0c;正逐渐成为众多设计师营造优质体验的首选。 一、浅色UI设计的视觉优势 &#xff08;一&a…

Nacos:使用PgSQL数据源

数据源插件开源仓库地址&#xff1a;nacos-datasource-extend-plugins 一、PostgreSQL数据库安装 1、本文使用Docker进行数据库的安装&#xff0c;使用docker命令拉取的PG14版本的数据库&#xff1a; docker pull postgres:14.6 2、创建PG容器并启动&#xff0c;映射了5432…

Linux——入门基本指令汇总

目录 1. ls指令2. pwd3. whoami指令4. cd指令5. clear指令6. touch指令7. mkdir指令8. rm指令9. man指令10. cp指令11. mv指令12. cat指令13. tac指令14. more指令15. less指令16. head指令17. tail指令18. date指令19. cal指令20. find指令21. which指令22. alias指令23. grep…

C语言之装甲车库车辆动态监控辅助记录系统

&#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 C语言之装甲车库车辆动态监控辅助记录系统 目录 一、前言 1.1 &#xff08;一&#xff09;…

2024年Vue面试题汇总

流程图如下&#xff1a; vue核心知识——语法篇 1.请问 v-if 和 v-show 有什么区别&#xff1f; 相同点&#xff1a; 两者都是在判断DOM节点是否要显示。 不同点&#xff1a; a.实现方式&#xff1a; v-if是根据后面数据的真假值判断直接从Dom树上删除或重建元素节点。 v-…

centos搭建 Node.js 开发环境

Node.js &#xff0c;通常简称为Node&#xff0c;是一个事件驱动 I/O 服务端 JavaScript 环境&#xff0c;基于 Chrome V8引擎&#xff0c;具备速度快、性能强等特点&#xff0c;可用于搭建各类网络应用&#xff0c;及作为小程序后端服务环境。npm 和 npx 都是和 Node.js 相关的…

DuckDB:精通Insert语句处理数据冲突

本文介绍DuckDB insert语句用法&#xff0c;包括常规的批量插入&#xff0c;尤其是插入数据冲突的处理&#xff0c;最后还提及returning子句的用法&#xff0c;每个用法提供示例说明。 insert插入数据 INSERT INTO向表中插入新行。可以插入由值表达式指定的一行或多行&#xf…

【Linux系统】Ext系列磁盘文件系统二:引入文件系统(续篇)

inode 和 block 的映射 该博文中有详细解释&#xff1a;【Linux系统】inode 和 block 的映射原理 目录与文件名 这里有几个问题&#xff1a; 问题一&#xff1a; 我们访问文件&#xff0c;都是用的文件名&#xff0c;没用过 inode 号啊&#xff1f; 之前总是说可以通过一个…

第2章:Python TDD构建Dollar类基础

写在前面 这本书是我们老板推荐过的&#xff0c;我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后&#xff0c;我突然思考&#xff0c;对于测试开发工程师来说&#xff0c;什么才更有价值呢&#xff1f;如何让 AI 工具更好地辅助自己写代码&#xff0c;或许…

SpringBoot实现定时任务,使用自带的定时任务以及调度框架quartz的配置使用

SpringBoot实现定时任务&#xff0c;使用自带的定时任务以及调度框架quartz的配置使用 文章目录 SpringBoot实现定时任务&#xff0c;使用自带的定时任务以及调度框架quartz的配置使用一. 使用SpringBoot自带的定时任务&#xff08;适用于小型应用&#xff09;二. 使用调度框架…

26. 【.NET 8 实战--孢子记账--从单体到微服务】--需求更新--用户注销、修改用户名、安全设置

在实际开发过程中&#xff0c;项目需求的变更和增加是常见的情况&#xff0c;因此这篇文章我们就模拟一下项目需求新增的情况。 一、需求 项目经理今天提出了新的功能&#xff0c;需要增加重置密码、安全设置、修改用户名、注销账户这四个功能&#xff0c;这四个功能必须是独…

Nginx反向代理架构介绍

Nginx反向代理架构是一种强大的服务器架构模式&#xff0c;它位于用户和原始服务器之间&#xff0c;接收用户的请求并将其转发到一个或多个后端服务器&#xff0c;然后将从后端服务器获取的响应返回给用户&#xff0c;就好像这些内容都是由代理服务器本身直接提供的一样。以下是…

flutter 使用google_mlkit_image_labeling做图片识别

在AI横行的如今&#xff0c;相信大家或多或少都做过跟AI接轨的需求了吧&#xff1f;今天我说的是关于图片识别的需求&#xff0c;flutter的专属图片识别插件google_mlkit_image_labeling。 google_mlkit_image_labeling它是Google旗下的Google Cloud Vision API中分支出来的一部…

自定义BeanPostProcessor实现自动注入标注了特定注解的Bean

定义注解 Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Documented public interface MyAnno { }定义一个配置类 Configuration public class RestConfig {MyAnnoBeanpublic PayDTO payDTO(){PayDTO payDTO …