[串讲]MySQL 存储原理 B+树

InnoDB 是一种兼顾高可靠性和高性能的通用存储引擎,在 MySQL 5.5 之后,InnoDB 是默认的 MySQL 存储引擎。 InnoDB 对每张表在磁盘中的存储以 xxx.ibd 后缀结尾,innoDB 引擎的每张表都会对应这样一个表空间文件,用来存储该表的表结构(frm、sdi)、数据和索引。

存储结构

InnoDB 的逻辑存储结构:表空间、段、区、页、行

https://img-blog.csdnimg.cn/95540eb1ea7349109d388ff6fc7f7cd7.png

InnoDB是以数据页为单位来读写数据的,数据页大小默认是16KB,每次从磁盘最少读取16KB的数据到内存,或者刷新内存中16KB的数据到磁盘

数据页

09b65c6b265cc577bf08a7f82ae31616

文件头记录数据页的信息,包括两个指针,一个指向上一个数据页,一个指向下一个数据页

每个数据页中存储了详细的记录数据

6c3f7e5741921f5c14903bbe06953adc

记录
  • UserRecord中存储了行记录,这些记录会通过单向链表按照主键的顺序有小到大排列
  • 单向链表的检索效率比较低,所以数据页中还有一个页目录结构帮助快速查找记录。
  • 数据页中的记录被分为若干组,当然,带有删除标识的不会参与分组;每组中的记录也是按照主键从小到大排序,每组中最后一条记录的主键值最大,它的头信息中记录了本组的记录条数(n_owned字段),页目录记录了每组最大最后一条记录的地址偏移量,叫做槽,它相当于指针指向了不同组的最后一条记录。
  • 当我们检索数据页中的记录时,由于记录都是按照主键大小排列的,可以使用槽号进行二分法定位某个槽,也就是定位到某一组,然后比较该组的最大记录的主键值,最终定位到某个槽。由于槽都是定位到每组最大的那条记录,所以如果要定位到最小的那条记录,可以通过查找上一个槽的最后一条记录,然后沿着单向链表向后检索

6675c6502cde217f24c3cff60c80212b

为了减少在某个分组中检索的时间复杂度,InnoDB规定了每个分组的大小

  1. 第一个分组只能有一条记录
  2. 最后一个分组记录条数在1-8之间
  3. 其余分组记录条数在4-8之间
B-树介绍

B-树,也称为B树,是一种平衡的多叉树。

        阶数:一个节点最多有多少个孩子节点。(一般用字母m表示)
        关键字:节点上的数值就是关键字
        度:一个节点拥有的子节点的数量。
一颗m阶的b-树:
        根结点至少有两个子女;
        每个非根节点所包含的关键字个数 j 满足:⌈m/2⌉ - 1 <= j <= m - 1.(⌈⌉表示向上取整)
        有k个关键字(关键字按递增次序排列)的非叶结点恰好有k+1个孩子。
        所有的叶子结点都位于同一层。
B+ 树原理

B+树是B-树的变体,也是一颗多路搜索树

  • 每个结点至多有m个子女;
  • 非根节点关键值个数范围:m/2 <= k <= m-1
  • 相邻叶子节点是通过指针连起来的,并且是关键字大小排序的。
## 区别:
B-树内部节点是保存数据的;而B+树内部节点是不保存数据的,只作索引作用,它的叶子节点才保存数据。
B+树相邻的叶子节点之间是通过链表指针连起来的,B-树却不是。
查找过程中,B-树在找到具体的数值以后就结束,而B+树则需要通过索引找到叶子结点中的数据才结束
B-树中任何一个关键字出现且只出现在一个结点中,而B+树可以出现多次。

a1076f005aabf2afd20d9f74ab7d5b91

  1. 插入

    流程:

    1.B+树插入都是在叶子结点进行的,就是插入前,需要先找到要插入的叶子结点。

    2.如果被插入关键字的叶子节点,当前含有的关键字数量是小于阶数m,则直接插入。

    3.如果插入关键字后,叶子节点当前含有的关键字数目等于阶数m,则插,该节点开始分裂为两个新的节点,一个节点包含⌊m/2⌋ 个关键字,另外一个关键字包含⌈m/2⌉个关键值。(⌊m/2⌋表示向下取整,⌈m/2⌉表示向上取整,如⌈3/2⌉=2)。

    4.分裂后,需要将第⌈m/2⌉的关键字上移到父结点。如果这时候父结点中包含的关键字个数小于m,则插入操作完成。

    5.分裂后,需要将⌈m/2⌉的关键字上移到父结点。如果父结点中包含的关键字个数等于m,则继续分裂父结点。

    参考:https://juejin.cn/post/6929833495082565646?searchId=20240301221957FB5B4942920DC0A4744E

  2. 查找

    单值查询:查找32

    第一次磁盘 I/O,查找磁盘块1,即根节点(36,43),因为32小于36,因此访问根节点的左边第一个孩子节点

    第二次磁盘 I/O, 查找磁盘块2,即根节点的第一个孩子节点,获得区间(28,32),遍历即可得32.

    img

    范围查询: [32,40]

    第一步先访问根节点,发现区间的左端点32小于36,则访问根节点的第一个左子树(28,32);

    第二步访问节点(28,32),找到32,于是开始遍历链表,把[32,40]区间值找出来,这也是B+树比B-树高效的地方。

  3. 删除
  • 找到包含关键值的结点,如果关键字个数大于m/2,直接删除即可;
  • 找到包含关键值的结点,如果关键字个数大于m/2,并且关键值是当前节点的最大(小)值,并且该关键值存在父子节点中,那么删除该关键字,同时需要相应调整父节点的值。
  • 找到包含关键值的结点,如果删除该关键字后,关键字个数小于⌈m/2⌉,并且其兄弟结点有多余的关键字,则从其兄弟结点借用关键字
  • 找到包含关键值的结点,如果删除该关键字后,关键字个数小于⌈m/2⌉,并且其兄弟结点没有多余的关键字,则与兄弟结点合并。
常见问题
  1. InnoDB一棵B+树可以存放多少行数据?

    约2千万行

    在计算机中,磁盘存储数据最小单元是扇区,一个扇区的大小是512字节。
    文件系统中,最小单位是块,一个块大小就是4k;
    InnoDB存储引擎最小储存单元是页,一页大小就是16k。
    
    • 如果一行记录的数据大小为1k,那么单个叶子节点可以存的记录数 =16k/1k =16.
    • 假设主键ID为bigint类型,长度为8字节,而指针大小在InnoDB源码中设置为6字节,非叶节点的一条记录为8+6=14字节,可存放16k/14B= 1170条
    • 因此,一棵高度为2的B+树,能存放1170 * 16=18720条这样的数据记录。同理一棵高度为3的B+树,能存放1170 *1170 *16 =21902400,也就是说,可以存放两千万左右的记录。B+树高度一般为1-3层,已经满足千万级别的数据存储。

    img

  2. 为什么索引结构默认使用B+树,而不是hash,二叉树,红黑树,B-树?
    • Hash哈希,只适合等值查询,不适合范围查询。

    • 一般二叉树,可能会特殊化为一个链表,相当于全表扫描。

    • 红黑树,是一种特化的平衡二叉树,MySQL 数据量很大的时候,索引的体积也会很大,内存放不下的而从磁盘读取,树的层次太高的话,读取磁盘的次数就多了。

    • B-Tree,叶子节点和非叶子节点都保存数据,相同的数据量,B+树更爱矮壮,也是就说,相同的数据量,B+树数据结构,查询磁盘的次数会更少。

  3. B-树和B+树的区别
    • B-树内部节点是保存数据的;而B+树内部节点是不保存数据的,只作索引作用,它的叶子节点才保存数据。
    • B+树相邻的叶子节点之间是通过链表指针连起来的,B-树却不是。
    • 查找过程中,B-树在找到具体的数值以后就结束,而B+树则需要通过索引找到叶子结点中的数据才结束
    • B-树中任何一个关键字出现且只出现在一个结点中,而B+树同一个键值可在不同层级的节点中重复出现。
  4. B+树和红黑树的区别
    • B+树的所有值都存在于叶子节点,并且叶子节点之间通过指针连接,形成一个有序链表。这种结构非常适合范围查询,红黑树虽然在单个元素查找上有优势,但需要进行额外的遍历才能完成范围查询。
    • 由于B+树具有顺序访问的特性,数据库系统可以利用预读优化来提高连续磁盘块的读取性能。而红黑树的结构不容易进行批量的顺序读取操作,因此无法充分利用预读特性。
    • B+树通过将键和数据分离使得节点可以存放更多的键。这样就可以减少树的高度,红黑树作为二叉树在存储大量数据时会占据更多空间,因为每个节点只有两个子节点的指针。
  5. 为什么索引使用B+树不使用跳表?

    磁盘I/O效率:B+树特别适合于磁盘存储的优化。它们能够最小化磁盘I/O操作,因为一个节点通常对应一个磁盘块的大小,这样可以减少读取数据时所需的磁盘访问次数。跳表在内存中运行效率较高,但当涉及到磁盘操作时,其性能可能会下降,因为跳表的节点间隔是不规则的,不一定能有效利用磁盘块的空间。

    删除操作:在B+树中,插入和删除操作可以更容易地保持树的平衡,而且不需要重新组织整个数据结构。虽然跳表支持比较简单的插入和删除操作,但在大量的更新操作后可能需要额外的工作来重新平衡。

    存储利用率:B+树的节点通常设计为页大小,以便与磁盘或文件系统页面对齐,从而实现高效的空间利用。而跳表可能会因为其节点大小不一致而在某些情况下导致存储空间利用率不高。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

全局自定义指令实现图片懒加载,vue2通过js和vueuse的useintersectionObserver实现

整体逻辑&#xff1a; 1.使用全局自定义指令创建图片懒加载指令 2.在全局自定义指令中获取图片距离顶部的高度和整个视口的高度 3.实现判断图片是否在视口内的逻辑 一、使用原生js在vue2中实现图片懒加载 1.创建dom元素,v-lazy为自定义指令&#xff0c;在自定义指令传入图片…

python使用pygame做第一个孩子游戏

作者&#xff1a;ISDF 功能&#xff1a;孩子游戏 版本&#xff1a;3.0 日期&#xff1a;03/29/2019作者&#xff1a;ISDF 功能&#xff1a;孩子游戏 版本&#xff1a;4.0 日期&#xff1a;03/27/2024 import pygame from pygame.locals import * import sys from itertools imp…

Python7:接口自动化学习1 RPC

API&#xff08;Application Programmming Interface&#xff09; 应用编程接口&#xff0c;简称“接口” 接口&#xff1a;程序之间约定的通信方法 特点&#xff1a;约定了调用方法&#xff0c;以及预期的行为&#xff0c;但是不透露具体细节 意义&#xff1a;程序能解耦&…

FPGA高端项目:解码索尼IMX390 MIPI相机转HDMI输出,提供FPGA开发板+2套工程源码+技术支持

目录 1、前言2、相关方案推荐本博主所有FPGA工程项目-->汇总目录我这里已有的 MIPI 编解码方案 3、本 MIPI CSI-RX IP 介绍4、个人 FPGA高端图像处理开发板简介5、详细设计方案设计原理框图IMX390 及其配置MIPI CSI RX图像 ISP 处理图像缓存HDMI输出工程源码架构 6、工程源码…

Trapcode Particular---打造惊艳粒子效果

Trapcode Particular是Adobe After Effects中的一款强大3D粒子系统插件&#xff0c;其能够创造出丰富多样的自然特效&#xff0c;如烟雾、火焰和闪光&#xff0c;以及有机的和高科技风格的图形效果。Trapcode Particular功能丰富且特色鲜明&#xff0c;是一款为Adobe After Eff…

视觉里程计之对极几何

视觉里程计之对极几何 前言 上一个章节介绍了视觉里程计关于特征点的一些内容&#xff0c;相信大家对视觉里程计关于特征的描述已经有了一定的认识。本章节给大家介绍视觉里程计另外一个概念&#xff0c;对极几何。 对极几何 对极几何是立体视觉中的几何关系&#xff0c;描…

新能源汽车充电桩主板各模块成本占比解析

汽车充电桩主板是汽车充电桩的重要组件&#xff0c;主要由微处理器模块、通信模块、控制模块、安全保护模块、传感器模块等多个模块构成。深入探究各模块在总成本中的比重&#xff0c;我们可以更好地优化成本结构、提高生产效率&#xff0c;并为未来的技术创新和市场需求变化做…

网络层介绍,IP地址分类以及作用

IP地址组成&#xff1a; TTL&#xff1a;生存时间 基于ICMP报文 特殊地址&#xff1a; 0.0.0.0-0.255.255.255 1.代表未指定的地址 默认路由 DHCP下发地址的时候&#xff0c;发个报文给DHCP服务器 临时用0.0.0.0借用地址&#xff0c;未指定地址。 2.全网地址&#xff1a;目…

iNet Network Scanner Mac 网络扫描工具

iNet Network Scanner for Mac是一款功能强大的网络扫描工具&#xff0c;专为Mac用户设计。它提供了全面而深入的网络分析功能&#xff0c;使用户能够轻松获取Mac连接的网络和设备的详细信息。 软件下载&#xff1a;iNet Network Scanner Mac v3.1.0激活版 这款软件具备多种扫描…

自动驾驶-如何进行多传感器的融合

自动驾驶-如何进行多传感器的融合 附赠自动驾驶学习资料和量产经验&#xff1a;链接 引言 自动驾驶中主要使用的感知传感器是摄像头和激光雷达&#xff0c;这两种模态的数据都可以进行目标检测和语义分割并用于自动驾驶中&#xff0c;但是如果只使用单一的传感器进行上述工作…

使用Spark单机版环境

在Spark单机版环境中&#xff0c;可通过多种方式进行实战操作。首先&#xff0c;可使用特定算法或数学软件计算圆周率π&#xff0c;并通过SparkPi工具验证结果。其次&#xff0c;在交互式Scala版或Python版Spark Shell中&#xff0c;可以进行简单的计算、打印九九表等操作&…

Gerber文件输出

Gerber文件输出 综述&#xff1a;本文主要讲述了AD软件中相关文件的导出&#xff08;装配图、BOM表、Gerber文件&#xff09;及文件的整理。 1. 输出装配图 方法一&#xff1a;点击“文件”→“装配输出”→“Assembly Drawings”&#xff0c;即可输出装配图&#xff0c;但是…

代码随想录 图论-并查集

代码随想录 (programmercarl.com) 寻找图中是否存在路径这道题中的类可看做并查集的标准类 目录 1971.寻找图中是否存在路径 684.冗余连接 685.冗余连接II 1971.寻找图中是否存在路径 1971. 寻找图中是否存在路径 已解答 简单 相关标签 相关企业 有一个具有 n 个顶…

文心一言指令词宝典之职场效率篇

作者&#xff1a;哈哥撩编程&#xff08;视频号、抖音、公众号同名&#xff09; 新星计划全栈领域优秀创作者博客专家全国博客之星第四名超级个体COC上海社区主理人特约讲师谷歌亚马逊演讲嘉宾科技博主极星会首批签约作者 &#x1f3c6; 推荐专栏&#xff1a; &#x1f3c5;…

OriginBot智能机器人开源套件

详情可参见&#xff1a;OriginBot智能机器人开源套件——支持ROS2/TogetherROS&#xff0c;算力强劲&#xff0c;配套古月居定制课程 (guyuehome.com) OriginBot智能机器人开源套件 最新消息&#xff1a;OriginBot V2.1.0版本正式发布&#xff0c;新增车牌识别&#xff0c;点击…

C# wpf 嵌入hwnd窗口

WPF Hwnd窗口互操作系列 第一章 嵌入Hwnd窗口&#xff08;本章&#xff09; 第二章 嵌入WinForm控件 第三章 嵌入WPF控件 文章目录 WPF Hwnd窗口互操作系列前言一、如何实现1、继承HwndHost2、实现抽象方法3、xaml中使用HwndHost控件 二、具体实现1、Win32窗口2、HwndSource窗…

html 元素宽度自适应 占据剩余宽度

弹性盒实现 父元素设置display: flex; 需要自适应宽度的子元素设置flex: 1; <html lang"en"> <head><style>*{margin: 0;padding: 0;}.main{display: flex;}.box1,.box2{width: 100px;height: 200px;}.box1{background: rgb(134 187 233);}.box2…

String类(三)

文章目录 string类&#xff08;三&#xff09;string类的模拟实现&#xff1a;1.默认成员变量和函数2.string的长度和下表引用3.字符串拷贝构造4. 赋值拷贝5.字符串比较6.字符串的增添操作7.insert插入操作8.遍历字符 string类&#xff08;三&#xff09; string类的模拟实现&…

存内计算:释放潜能的黑科技

什么是存内计算&#xff1f; 存内计算技术是一种新型的计算架构&#xff0c;它将存储器和计算单元融合在一起&#xff0c;以实现高效的数据处理。存内计算技术的优势在于能够消除数据搬运的延迟和功耗&#xff0c;从而提高计算效率和能效比。目前&#xff0c;存内计算技术正处…

【SAP2000】碰撞分析 Impact Analysis

碰撞分析 Impact Analysis CSI程序的动力分析功能非常广泛。一个例子是分析两个质量或结构之间碰撞效应的能力。 The possibilities of dynamic analysis with CSI programs are very extensive. An example of this is the ability to analyze the effects of collision bet…
最新文章