InnoDB存储引擎-逻辑存储结构
1. 索引组织表
在 InnoDB存储引擎 中, 表都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表. 在 InnoDB存储引擎表中, 每张表都有个主键.
2. InnoDB 逻辑存储结构
在 InnoDB存储引擎的逻辑存储结构看, 所有的数据都被逻辑地放在一个空间中, 称为表空间.
表空间又分为 段 区 页 .
2.1 表空间
表空间可以看作是 InnoDB 存储引擎逻辑结构的最高层, 所有的数据都存放在表空间中.
2.2 段
表空间是由各个段组成的, 常见的有 数据段 索引段 回滚段等.
InnoDB 存储引擎表是索引组织的, 因此数据及索引, 索引即数据. 那么数据段即为 B+树的叶子节点, 索引段即为 B+ 树的非索引节点.
2.3 区
区是由连续页组成的空间, 在任何情况下每个区的大小都是 1MB. 默认情况下页大小为 16KB, 即一个区中一共有 64 个连续的页.
2.4 页
页是 InnoDB 存储引擎 对磁盘管理的最小单位. 默认大小为 16 KB.
常见的页类型有 数据页 undo页 系统页 事务数据页等
2.5 行
InnoDB 存储引擎是面向列的, 也就是说是按照行进行存放的. 每个页的行记录最多允许存放 16KB/2 - 200 = 7994 行.
3. InnoDB 行记录格式
InnoDB 存储引擎和大多数数据库一样, 记录是以行的形式存放的. 也就是说 页中保存着表中一行行的数据.
InnoDB 存储引擎提供了 Compact 和 Redundant 两种格式来存放行记录数据.
MySQL5.1 后默认的是 第一种格式.
3.1 Compact 格式
Compact 行记录的设计目的是高效地存储数据. 一个页中存放行数据越多, 其性能就越高.
变长字段长度列表: 若列的长度小于255字节, 用1字节表示; 若列的长度大于255字节, 用2字节表示.
NULL标志位: 1字节表示, 有NULL值用1表示.
记录头信息: 5字节, 记录了该行是否被删除,是否是叶子节点等信息.
后面的部分就是记录的真实数据, NULL是不占任何存储空间的(除了NULL标注位).
每行数据除了用户定义的列外, 还有两个隐藏列: ①事务ID, ②回滚指针列.
3.2 Redundant 格式
略
3.3 行溢出数据
3.3.1 啥是行溢出啊
MySQL InnoDB 的 行溢出数据(Row Overflow Data)是指当一行中的数据量过大,无法完全存储在单个数据页(默认 16KB)时,部分数据会被存储到其他页中的现象。这种情况通常出现在处理大字段(如 <font style="color:rgb(64, 64, 64);">TEXT</font>
、<font style="color:rgb(64, 64, 64);">BLOB</font>
或超长 <font style="color:rgb(64, 64, 64);">VARCHAR</font>
)时,不同行格式的处理方式有所不同。
3.3.2 不同行格式的处理方式
InnoDB 支持多种行格式,对溢出的处理策略不同:
行格式 | 溢出处理策略 |
---|---|
COMPACT | 大字段前 768 字节存储在原页,剩余数据存入溢出页,原页保留 20 字节指针。 |
REDUNDANT | 类似 COMPACT,但存储效率较低(旧格式)。 |
DYNAMIC | 所有大字段数据完全存入溢出页,原页仅保留 20 字节指针(默认推荐格式,更高效)。 |
COMPRESSED | 类似 DYNAMIC,但会对溢出数据进行压缩,节省空间(增加 CPU 开销)。 |
3.3.3 触发条件
- 显式触发:
- 单个
<font style="color:rgb(64, 64, 64);">BLOB</font>
/<font style="color:rgb(64, 64, 64);">TEXT</font>
/<font style="color:rgb(64, 64, 64);">VARCHAR</font>
列的数据超过 页大小阈值(如 16KB 页的 768 字节前缀)。
- 单个
- 隐式触发:
- 多列数据总长度超过页的可用空间(如多个长
<font style="color:rgb(64, 64, 64);">VARCHAR</font>
列总和超过 8000 字节)。
- 多列数据总长度超过页的可用空间(如多个长
3.3.4 其他
MySQL数据库的 varchar 类型可以存放 65535 字节. 注意是字节, 建表语句中的 varchar(100) 这个100是字符, 如果按照 UTF-8 字符编码来说, varchar(100) 占用的是 300 字节. 另一个 65535 说的是该表定义的 varchar 类型的总和, 不是单一字段.