当前位置: 首页 > news >正文

MySQL InnoDB 表数据结构存储方式详解

InnoDB 是 MySQL 默认的存储引擎,采用 行存储,支持 事务、行级锁、外键,并通过 B+ 树索引 高效管理数据。本笔记详细介绍 InnoDB 表的数据存储结构索引组织表(Clustered Index)二级索引页结构行格式 及相关机制。


一、InnoDB 表的整体存储结构

InnoDB 的存储结构分为以下几个层次:


表空间(Tablespace)
├── 段(Segment)
│     ├── 区(Extent)
│           ├── 页(Page)
│                 └── 行(Row)
  • 表空间(Tablespace)
    存放表数据和索引的逻辑容器,可以是系统表空间(ibdata)或独立表空间(.ibd 文件)。
  • 段(Segment)
    表空间中的逻辑分配单位,分为 数据段(Data Segment)索引段(Index Segment)
  • 区(Extent)
    每个区大小固定为 1MB,包含 64 个页(每页 16KB)
  • 页(Page)
    InnoDB 的最小磁盘管理单元,大小为 16KB
  • 行(Row)
    页中存储的数据行,具体格式由 行格式(ROW_FORMAT) 决定。

二、索引组织表(Clustered Index)

InnoDB 表数据的存储方式

  • InnoDB 表是 索引组织表(Index-Organized Table,IOT),即 数据按照主键顺序存放在聚簇索引(Clustered Index)中
  • 表数据即索引的一部分
    • 每个 InnoDB 表 必须有主键(如果没有定义,系统会隐式创建一个 ROW_ID)。
    • 主键索引(聚簇索引)中的叶子节点存储整行数据。

聚簇索引的特点:

  • 数据按照 主键顺序 存储。
  • 叶子节点存放完整行记录。
  • 一个表只有 一个聚簇索引

示意图:


Clustered Index (B+ Tree)
├── Root Page
│     └── Branch Page
│           └── Leaf Page → \[row1, row2, row3, ...] (完整行数据)

三、二级索引(Secondary Index)

  • 二级索引的 叶子节点 不存储整行数据,只存储:
    • 索引列值
    • 对应的主键值(row_id)
  • 查询时如果二级索引不能覆盖查询列,需要回表(回到聚簇索引查完整数据),称为 回表操作

示意图:


Secondary Index (B+ Tree)
├── Root
│     └── Branch
│           └── Leaf → \[index\_column\_value, primary\_key]

四、InnoDB 的页结构(Page Structure)

每个页(Page)大小固定为 16KB,主要用于存储索引和数据。
页的结构如下:


+---------------------+
\| File Header (38B)   |
\| Page Header (56B)   |
\| Infimum & Supremum  |
\| User Records        |
\| Free Space          |
\| Page Directory      |
\| File Trailer (8B)   |
+---------------------+
  • File Header:页的通用信息,如页号、校验和。
  • Page Header:页类型、记录数等。
  • Infimum & Supremum:页内的最小/最大虚拟记录。
  • User Records:实际用户数据。
  • Free Space:空闲空间,用于插入新记录。
  • Page Directory:指向记录的槽位,用于快速定位。
  • File Trailer:页的完整性校验。

五、InnoDB 行格式(Row Format)

行格式决定了数据在页中的存储方式,常见的行格式有:

行格式特点
COMPACT默认行格式,数据紧凑存放,字段长度 + 数据值。
REDUNDANT旧版本使用,字段信息存储冗余。
DYNAMIC大字段(TEXT/BLOB)只存放 20B 指针,实际数据放在溢出页。
COMPRESSED压缩页数据,提高存储效率。

行记录结构:


\[变长字段长度列表]\[NULL 值列表]\[记录头信息]\[列数据]

六、InnoDB 数据存储示意图


表空间 (.ibd 文件)
↓
段 (数据段 / 索引段)
↓
区 (1MB)
↓
页 (16KB)
↓
行 (行格式存储)

七、InnoDB 表存储的关键特性

  1. 行级锁:基于索引实现。
  2. 事务支持:通过 Undo Log 回滚、Redo Log 持久化。
  3. MVCC:通过 Undo Log 提供一致性读。
  4. 数据页缓存:Buffer Pool 提升性能。

八、面试高频问答

Q1:InnoDB 为什么是索引组织表?

  • 因为 InnoDB 聚簇索引的叶子节点存储整行数据,表数据与索引存储在一起。

Q2:聚簇索引和二级索引区别?

  • 聚簇索引:叶子节点存储完整行数据。
  • 二级索引:叶子节点存储索引列和主键,需要回表。

Q3:InnoDB 的页大小是多少?

  • 默认 16KB,可以配置(但常用 16KB)。

Q4:大字段 TEXT/BLOB 如何存储?

  • 在 DYNAMIC 行格式下,字段只存储 20B 指针,实际数据存储在溢出页。

Q5:为什么建议 InnoDB 表必须有主键?

  • 因为聚簇索引基于主键,如果没有主键,InnoDB 会自动创建隐藏的 row_id,占用空间且影响性能。

九、总结

存储单位大小
页(Page)16KB
区(Extent)1MB(64 页)

InnoDB 采用 B+ 树 组织数据,表是索引组织表,聚簇索引的叶子节点存放整行数据,二级索引存储主键,实现高效查询。

http://www.dtcms.com/a/315108.html

相关文章:

  • pathspec ‘with_def_layout‘ did not match any file(s) known to git`
  • Vue 详情header组件
  • Go语言Context
  • ISO(感光度)的工作原理
  • 接口权限(@SaCheckPermission)
  • ebaz4205矿板以太网连接不稳定问题解决方案
  • SQL基础语法(四个分类、库和表的增删改)
  • 【笔记】ROS1|6 中间人攻击移动过程【旧文转载】
  • 私有化部署即时通讯,企业专属通讯系统BeeWorks
  • 计算机网络:网络号和网络位是不是同一个意思
  • 4.5 点云表达方式——图
  • 纯前端使用ExcelJS插件导出Excel
  • 并发编程常用工具类(上):CountDownLatch 与 Semaphore 的协作应用
  • C++信息学奥赛一本通-第一部分-基础一-第一章
  • 高并发抢单系统核心实现详解:Redisson分布式锁实战
  • Swin-Transformer从浅入深详解
  • ubuntu 20.04 C和C++的标准头文件都放在哪个目录?
  • 安卓逆向(基础①-Google Pixel-Root)
  • <PhotoShop><JavaScript><脚本>基于JavaScript,利用脚本实现PS软件批量替换图片,并转换为智能对象?
  • 【拓扑序 时间倒流法】P7077 [CSP-S2020] 函数调用|省选-
  • 嵌入式开发入门——电子元器件~电容
  • RLCraft开服踩坑记录
  • 防火墙web页面练习
  • 使用AWS for PHP SDK实现Minio文件上传
  • Centos7离线安装Mysql8.0版本
  • 政务云数智化转型:灵雀云打造核心技术支撑能力
  • HarmonyOS 多屏适配最佳实践:基于 ArkUI 的响应式 UI 方案
  • 在CentOS 7上安装配置MySQL 8.0完整指南
  • [Oracle] TO_NUMBER()函数
  • C 语言结构体与 Java 类的异同点深度解析