尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
InnoDB存储结构:记录在页里,为什么不从第一行一直找?
我最开始整理 InnoDB列了很多问题没建索引怎么存页里有什么记录为什么有 next_record长字符串放哪里问题不少却没有把它们连接起来。这次先抓一个问题索引已经找到某个叶子页以后还要在里面找一条记录。难道从第一条一直遍历到最后一条本文以 MySQL 8.4 文档为概念基线页目录另引用官方源码说明。图是结构示意不是 .ibd 文件的实测字节布局本轮没有运行 MySQL 实例不虚构 EXPLAIN、页转储或 I/O 数字。1. 先分清在哪个页与页内哪条记录按主键找记录可以先这样理解两个层次聚簇索引 B 树 | v 定位叶子页 第一层在哪个页 | v 页目录缩小范围 - 记录链查找 第二层页内哪条记录这不是完整 SQL 执行流程省略了缓存、锁、可见性判断等工作。上一篇存储引擎笔记讨论页与缓存等层次本篇接着看页内组织。InnoDB 普通索引是 B 树结构。聚簇索引的叶子记录包含行数据二级索引记录则包含相应索引列和用于定位行的主键值不能说“所有索引里的记录都是完整业务行”。索引的物理结构、聚簇与二级索引。没有显式主键也不等于表没有聚簇索引InnoDB 会优先采用第一个所有键列都 NOT NULL 的 UNIQUE 索引没有合适索引时生成隐藏的 GEN_CLUST_INDEX使用 6 字节行 ID。同一官方说明。因此原笔记“必须有主键”应改成引擎需要组织聚簇索引但建表语句不一定声明 PRIMARY KEY。日常设计仍建议显式选择合适主键。2. 有序的是记录之间的逻辑关系不是连续数组学数组查找时我习惯把“有序”理解成连续存放a[0]、a[1]、a[2]。页内记录不能照搬这个想象。页内有记录之间的链接按索引键形成逻辑顺序。记录在页里的物理位置不必按键值紧挨着排列变长字段也让每条记录不一定等长。逻辑键顺序 10 - 20 - 30 - 40 页内位置 不保证是四个等长、连续的数组元素所以“第 100 条”的地址不能简单用起点加 100 倍记录长度得到。顺着 next_record 可以访问下一条逻辑记录但如果只有这条链查找可能走很多步。这里的 next_record 是记录头中的定位信息不是业务字段更不是 C 程序可以直接解引用的内存指针。解析真实文件时必须按对应版本和格式解释。3. 页目录先翻目录再看附近几条页目录保存槽槽指向记录组边界。它不像给每条记录都做一个完整目录而是把记录分组用较少槽缩小查找范围。下面故意用较小的组画出思想不是实际 InnoDB 分组大小记录链 10 - 20 - 30 | 40 - 50 - 60 | 70 - 80 - 90 示意槽 30 60 90 查 50 1. 先在槽里缩小到 (30, 60] 这一段 2. 从前一边界继续沿链查找40 - 50为什么不是“一路二分每条记录”因为完整记录不是可用下标随机访问的连续数组。但槽可以用于二分缩小范围剩下的一小段再沿链检查。为什么不是“所有记录只走链”因为随着页内记录增多长链查找重复比较太多。目录多花一点空间换来更短的查找路径。官方源码对槽所拥有记录数给出 4 与 8 的通常界限并明确首尾槽有例外。因此不能把图里的每组都画成固定 8 条更不能说“整页最多只比较 8 次”还有目录定位等比较。官方 page0page.h 源码说明。这里引用的是 8.0.46 源码文档不把它假称为 8.4 的现场转储。4. 找到记录以后行格式在解决什么问题定位到一条记录不代表它是一串无需解释的字段值。引擎还要知道哪些列是 NULL变长字段多长下一条记录在哪内容解决的问题记录头信息记录状态、逻辑链接等管理信息NULL 标记区分字段没有值与有实际内容变长字段长度信息确定变长字段边界字段数据保存实际值部分长值也可能使用页外存储这是职责概括不是四块必然按这个表格顺序排列的字节图。具体布局要看行格式。MySQL 8.4 支持 REDUNDANT、COMPACT、DYNAMIC、COMPRESSED。REDUNDANT 是较早格式但不能写成已经不支持。COMPACT 系列使用 NULL 位图没有可空列时不需要给 NULL 位图硬塞一个字节。官方行格式说明。5. 长字段不是“类型大就全放外面”页的空间有限一行中的长字段可能有页外部分但不能仅看到 VARCHAR 或 TEXT 就断定固定存法。COMPACT 与 DYNAMIC 的页外策略不同COMPACT 的长字段页外存储会保留页内前缀DYNAMIC 在需要页外存储时可以把长变长字段整体放到页外页内保留定位信息。不是每个字段都会发生溢出也不是每个字符串固定占 20 字节。行格式中的页外存储说明。这也说明为什么“VARCHAR 最多多少字符”不能只拿一个固定数字当答案字符集每字符最大字节数、其他列、行大小限制都有关。本文不通过一段 SQL 反推所有物理布局。6. 可以在自己的 MySQL 中观察什么以下只读语句可检查环境与已有表不要求修改全局参数。把表名替换成自己的测试表。SELECT VERSION(); SHOW VARIABLES LIKE innodb_page_size; SHOW CREATE TABLE your_test_table; SHOW TABLE STATUS LIKE your_test_table; SHOW INDEX FROM your_test_table;这些命令能看到版本、页大小配置、建表语句、行格式和索引定义不能直接显示页目录的每个槽也不能由 SHOW INDEX 没有显式主键就证明没有内部聚簇索引。真要研究槽和记录头下一步应针对确定版本做离线页解析而不是修改生产数据文件。7. 用一个小模型检查“目录 短链”的想法上面的三组示意可以做成一个独立程序先在组尾键里找边界再在所选组里找目标用完整顺序扫描作对照。验证时包含命中、落在键间、比最小值小和比最大值大。本次验证程序检查这幅示意中的全部整数查询范围并对不同长度的递增数组重复测试两种查法应得到同一位置或同为不存在。这个实验只能证明所画简化模型的查询结果一致。它没有实现 InnoDB 的槽维护、记录头、重复键规则或并发行为也不是对 MySQL 存储引擎做完整正确性验证。回头看有序与连续存储不是一回事记录链与二分查找也不互斥。InnoDB 用不同层次解决不同问题树先找页目录缩小页内范围记录信息再帮助定位和解释字段。这样学才不必把几十个名词孤立地背下来。
RELATED

相关推荐

Moodle 主题图标尺寸控制指南:从 `{{pix}}` 模板助手到 `icon-size` 工具类

Moodle 主题图标尺寸控制指南:从 `{{pix}}` 模板助手到 `icon-size` 工具类

教育后端前端 【免费下载链接】moodle Moodle - the worlds open source learning platform 项目地址: https://gitcode.com/gh_mirrors/mo/moodle 点击查看 免费下载 导读:本文以 public/admin/tool/componentlibrary/content/moodle/themes/iconsizes…

📅 2026/10/6 2:19:44
Rufus 3.22 还能做 Windows 7 启动盘吗?版本边界一查便知

Rufus 3.22 还能做 Windows 7 启动盘吗?版本边界一查便知

Rufus 3.22 还能做 Windows 7 启动盘吗?版本边界一查便知 【免费下载链接】rufus The Reliable USB Formatting Utility 项目地址: https://gitcode.com/GitHub_Trending/ru/rufus Rufus 是 USB 启动盘格式化工具,核心能力是格式化 U 盘并写入 IS…

📅 2026/10/6 2:19:44
cppcheck 的 uselessCallsConstructor 检查:识别容器自我切片赋值的低效构造调用

cppcheck 的 uselessCallsConstructor 检查:识别容器自我切片赋值的低效构造调用

开发工具静态分析代码质量质量保障 【免费下载链接】cppcheck static analysis of C/C code 项目地址: https://gitcode.com/gh_mirrors/cpp/cppcheck 点击查看 免费下载 导读 uselessCallsConstructor 是 C 静态分析工具 cppcheck 在 STL 相关检查(Ch…

📅 2026/10/6 2:19:44
MORE NEWS

更多资讯

📰

Java+SQL Server图书馆管理系统:JDBC连接、事务与避坑实践

简介:这是一份基于Java与SQL Server的简易图书馆管理系统课程设计资源,专门面向计算机相关专业正在准备数据库课程设计的学生,也适合入门级Java开发人员用于学习项目整合。系统围绕图书馆日常业务,完整实现了图书信息录入与修改、…

📰

PASCAL VOC标注的IP102害虫数据集:格式解析、YOLO转换与训练避坑指南

简介:IP102数据集PASCAL VOC格式标注文件包,适合计算机视觉研究人员、深度学习开发者以及农业智能应用工程师使用。数据集覆盖IP102害虫类别,提供9997张原始图片对应的标注信息,解决农业害虫识别场景中高质量标注数据稀缺、格式不…

📰

SAP BTP实战:ABAP事件推送Launchpad通知中心全流程

做 SAP BTP ABAP 环境项目这一年多,业务方追问最多的不是报表有多快,而是:后端 ABAP 里状态变了,能不能直接推到 Launchpad 的通知中心?这里说的通知,既不是邮件,也不是应用里的 toast&#xff…

📰

Suricata网络入侵检测系统毕设实战:规则、告警与排错指南

简介:基于Suricata的简单网络入侵检测系统源码与项目截图打包,面向计算机、数学、电子信息等专业正在准备毕业设计或课程设计的学生,也适合需要实战练习的学习者。资源以完整工程形式提供,包含入侵检测系统核心模块,如…

📰

基于MQTT协议的AGV调度系统:通信架构、Topic设计与多车路径规划实战

简介:面向物联网、自动化物流方向的AGV调度毕业设计,‘基于MQTT协议的AGV调度系统’提供了一套轻量级发布/订阅通信与调度实现方案。它选用MQTT作为核心通信协议,借助低开销、小延迟、支持多级QoS的特点,适配低带宽或不稳定网络&a…

📰

C++静态分配顺序表:从连续内存到底层实现细节

如果让我用一道题来检验一个人的 C 基础扎不扎实,我会选顺序表,而且是静态分配那种。这题看起来太简单了——不就是给数组包一层壳吗?可等你真动手写一个支持插入、删除、查找的完整类,再把所有边界情况跑一遍,就会发现…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬