当前位置: 首页 > 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.lryc.cn/news/610403.html

相关文章:

  • 川翔云电脑:引领开启算力无边界时代
  • 数学 理论
  • 哪些企业需要私有化部署?有没有推荐的私有化im
  • 段落注入(Passage Injection):让RAG系统在噪声中保持清醒的推理能力
  • [Shell编程] 零基础入门 Shell 编程:从概念到第一个脚本
  • 【RH124知识点问答题】第8章 监控和管理 Linux 进程
  • Linux 磁盘管理详解:分区、格式化与挂载全流程指南
  • 内联函数:提升效率的空间换时间艺术
  • C++面试题及详细答案100道( 01-10 )
  • mongodb源代码分析创建db流程分析
  • 【论文阅读】ACE: Explaining cluster from an adversarial perspective
  • Makefile文件写法模板
  • 数据与模型优化随机森林回归进行天气预测
  • CLM陆面过程模式实践技术应用
  • 攻防世界-Mobile-easyjni
  • 8.高斯混合模型
  • 基于Springboot+Mybatis+thymeleaf的个人博客系统的设计与实现
  • 监控插件(二)prometheus(2)API CounterGauge
  • Linux下PXE服务器搭建
  • EdgeView for macOS:解决图像管理痛点的利器
  • 【BUUCTF系列】[极客大挑战 2019]LoveSQL 1
  • Scrapy爬虫集成MongoDB存储
  • FinalShell 跳板机proxyjump使用
  • Go 与 Python 爬虫代码实操对比
  • Python接口自动化测试之之request
  • SpringMvc跨域配置方法详解
  • Jmeter进行性能并发测试
  • 设计模式-创建型-工厂模式
  • Clion STM32CubeMX LED闪灯
  • CentOS卸载、安装MySQL8(yum操作)