【MySQL】InnoDB 存储引擎篇(一)

这是讲 MySQL 的第一篇文档,我先把几个最核心的概念列出来,读者在后续阅读的过程中会频繁的见到这些概念和定义。暂时不理解不要紧,后面会对这些了解的更加清晰~

  1. 数据即索引,索引即数据
  2. 记录 = 行 = Rows,即我们说的一条记录,就是一行数据
  3. MySQL 查询的基础算法是 二分法
  4. 既是二分法,那么记录必然有排列顺序,这个顺序是通过数据表 主键 的大小排列,大小怎么比较出来的?通过 UTF-8 这些字符集比较的,比如 2 > 1, b > a 等等,所以文中说的 最大/最小主键 就是根据这个来的。

下面是两条记录,也就是两行数据:

数据页

先说几个核心概念:

  • 页:页是 InnoDB 管理存储空间的基本单位,也是磁盘 I/O 的基本单位,每个页的大小是 16KB,而 InnoDB 里有各种各样的页类型,各司其职。比如系统页、undo 日志页,数据页等等。
  • 数据页:这些页类型中,又以数据页为最核心最常用的页类型,因为它同时存储着表数据和索引信息,通俗的来说,就是既存着记录,又存着可以找到这条记录的地址。

数据页结构

我会讲解图中最重要的几个结构,其他的感兴趣的同学可以自行了解。

File Header: 页号、前后页指针,页类型等一些通用信息

Page Header: 已用空间、记录数,最小/最大主键等数据页专有的一些信息

Infimum + Supremum: 页面中的最小记录和最大记录,很重要的一个虚拟记录。

User Records: 这里存储着记录,是动态变化的。

Free Space: 空闲空间,整个页中尚未使用的空间。

Page Directory: 页目录,页中记录的相对位置,方便快速定位到记录

File Trailer: 校验和,页号等,用于校验页是否完整

通过以上结构,我们可以知道:

  • 页与页之间:通过 File Header 中的前后页指针相连,组成双向链表
  • 记录与记录之间:通过 User Records 中的下一条指针记录指针,组成单向链表

Page Directory 页目录

页目录,顾名思义,InnoDB 可以通过这个目录来快速查找到某条记录。

类似于书籍的 “目录”,通过预先生成的 “索引槽” 用二分法快速定位记录位置,避免全表扫描。

先说个 InnoDB 规定:Infimum 是页中的最小记录,Supremum 是页中的最大记录!!!

这个不用比较主键,就是单纯的规定!每个页中所有的记录都在这两个记录中间!

页目录的核心结构(槽)

页目录由一系列 “槽(Slot)” 组成,每个槽本质是一个 偏移量指针,指向页内某组记录中 “最大主键值的记录” 在页内的位置(字节偏移量)。

  1. 槽的组织方式:页目录中的槽按主键升序排列(与 User Records 中记录的顺序一致)。每个槽对应 1-8 条连续记录(InnoDB 会将相邻记录分组,每组分配一个槽),组内记录的最大主键值作为槽的 “标识”。Infimum 单独一个槽,Supremum 所在的槽最大可以放 8 条记录,其余中间的槽最大只能存放 4 条记录。槽的数量随记录数动态变化(记录越多,槽越多),但始终远小于记录总数(例如 1000 条记录约对应 250 个槽)。
  2. 包含的伪记录槽:页目录的第一个槽固定指向 Infimum(最小伪记录),最后一个槽固定指向 Supremum(最大伪记录)。用户记录的槽位于这两个伪记录槽之间,形成完整的索引范围。

数据的增删查

  1. 查询 salary = 5000 时:二分查找槽,确定 X 位于槽 1(最大主键 4500)和槽 2(最大主键 5100)之间 → 目标槽为槽 2。通 过槽 1 的偏移量找到槽 1 中最大主键记录(4500),向后遍历记录(4800、5000),最终找到 salary = 5000。
  2. 记录删除:记录被删除后,不会立即从页目录中移除对应的槽,而是标记为 “无效”,那条记录依然存在当页内空闲空间较多时,InnoDB 会触发 “页整理”,合并相邻组并删除无效槽,优化页目录效率。
  3. 记录插入:新记录插入时,若所在组的记录数超过 4 条,InnoDB 会拆分组并新增槽,维持 “1-4 条记录对应 1 个槽” 的规则。只有 supremum 所在的槽最大数量为 8 条。重复插入删除的记录时,会复用之前标记为“无效”的记录,只是改变一下标志位。

File Header 文件头

里面记录着页号,上一页的页号,下一页的页号,这些页组成一个双向链表,分散的存储在磁盘中。(因为无法给这么多页分配一个连续的非常大的存储空间)

其他的结构了解即可,一般面试也不会过多询问。详细讲解页目录结构是因为可以更好的学习和理解 索引

面试官提问

其实针对这一章的内容,面试官一般不会问得这么详细,这篇文档的介绍主要还是帮助大家理解 InnoDB 的底层结构,以便大家可以更好的学习后面索引的内容。

  • 页在 InnoDB 中起什么作用?
  • 每个页的大小为 16KB,InnoDB 以页为基本单位从磁盘中读取,而不是一个一个记录的读取,大大提升了磁盘 I/O 的效率。
  • 为什么页是B+树的物理载体(基本单位)?
  • B+树的每个节点对应一个数据页:
  • 非叶子节点存储索引键+子页指针(File Header中的前后页指针实现双向链表);
  • 叶子节点存储实际数据(User Records)。
  • 槽的概念在查询过程中的实际作用?
  • 页目录的槽机制加速了节点内的记录查找,支撑B+树的O(log n)查询效率。(二分法)
#MySQL##MySQL必知必会##后端##Java#
后端技术学习 文章被收录于专栏

这个专栏我将对后端技术进行总结和复盘,以在字节输出文档的态度来要求自己。包括但不限于八股、算法、架构、系统设计、场景、智力题等。

全部评论

相关推荐

评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务