Skip to content

至今为止, Mysql 还是一个黑盒, 在使用层面我们只需要在客户端编写好 sql 发送给 mysql 服务端之后等待服务器的返回结果. 那么表中的数据存储到哪里了? 存储的是什么格式? 怎么存储的? 又是怎么访问这些数据的?Mysql 服务端的数据存储和处理是由 存储引擎 来进行处理的, Mysql 中由有很多不同的存储引擎 InnoDB MyISAM 等, 这些不同的存储引擎一般是由不同的人为实现不同的特性而开发的. , 甚至有的存储引擎压根就没有做数据刷盘的操作, 例如 Memory 这种引擎直接就是在内存上进行操作的, 当 Mysql 服务端发生关闭/重启时数据就全部丢掉了.

InnoDB 页简介

InnoDB 是一个将数据处理到磁盘中的存储引擎, 也就是它会把数据库持久化到磁盘中, 这个操作是在内存中实现的. 而内存与磁盘的读写速度差距很大. Innodb 又是如何解决这个问题的呢?, 为了提升效率, 尽量减少磁盘 IO. 读取磁盘时往往不是严格的按需读取, 而是每次都会 预读 即使当前只需要 1 个字节的数据, Mysql 也是会从这个位置开始顺序往后读取一定长度的数据放入内存,这个称之为 预读. InnoDB 的基本单元叫 每一页数据16KB (默认), 不管是写入到内存中还是读取到磁盘中, 都是以 来作为基本单元的数据操作

InnoDB 行格式

我们一般向数据库 insert 一条数据都是以行格式去新增数据的. 这些记录在磁盘上的存储方式为 行格式 或者叫 记录格式InnoDB 在设计之初做了四种不同类型的行格式, 紧凑 Compact, 压缩 Compressed , 动态 Dynamic (默认) , 冗余 Redundant.

查看 Mysql 默认的行格式

shell
mysql> show variables like 'innodb_default_row_format';
+---------------------------+---------+
| Variable_name             | Value   |
+---------------------------+---------+
| innodb_default_row_format | dynamic |
+---------------------------+---------+
1 row in set (0.05 sec)
mysql>

我们可以在创建/修改表的语句上指定行格式

sql
create table 表名 row_format = 行格式名称[Compact,Compressed,Dynamic,Redundant]

Compact 行格式

Compact 行格式一条完整的记录由 记录的额外信息, 记录的真实数据 两大部分组成.

记录的额外信息

Mysql 为了描述当前这行信息不得不额外做的记录信息, 总共有三大类

变长字段长度列表

我们知道 MySQL 支持一些变长的数据类型,比如 VARCHAR(M)VARBINARY(M)、各种 TEXT 类型,各种 BLOB 类型,我们也可以把拥有这些数据类型的列称为 变长字段,变长字段中存储多少字节的数据是不固定的,所以我们在存储真实数据的时候需要顺便把这些数据占用的字节数也存起来,这样才不至于把 MySQL 服务器搞懵,所以这些变长字段占用的存储空间分为两部分:

  1. 真正的数据内容 (可变字段)
  2. 占用的字节数 (长度) 在 Compact 中, 把所有变长字段的真实数据、占用的字节长度都存放在记录的开头部位,从而形成一个变 , 每个变长字段数据及其占用的字节数. 所有的数据都是的 把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位,从而形成一个变长字段长度列表,各变长字段数据占用的字节数按照列的顺序逆序存放
Null 值列表
记录头信息

参考 《MySQL 是怎样运行的:从根儿上理解 MySQL》

waitingresult.com