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

发布于:2025-08-05 ⋅ 阅读:(14) ⋅ 点赞:(0)

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+ 树 组织数据,表是索引组织表,聚簇索引的叶子节点存放整行数据,二级索引存储主键,实现高效查询。


网站公告

今日签到

点亮在社区的每一天
去签到