基于:Mysql 5.7

一、回顾 InnoDB 逻辑结构图

image.png
行格式对应的就是上图中的”row“。

二、InnoDB 行格式

InnoDB 存储引擎存储数据以行的形式存储。(页由一行行 row 组成)
针对 InnoDB 的存储格式,目前有四种行格式:

  • COMPACT行格式
  • Redundant行格式
  • Dynamic 行格式
  • Compressed 行格式

    2.1、行格式:COMPACT

    image.png
    行格式如图所示,分为三类

  • 记录的额外信息
    分为三个:变成字段长度列表、Null标志位列表、记录头信息
    变长字段长度列表:存储变成字段的长度,长度小于255 用1个字节标识,长度大于255用2个字节标识(最大两个字节标识 2^16 = 65535 所以字段长度最长为 65535)。
    NULL 标志位列表:如果不存在 NULL 值列,该字段不存在。否则:0 表示 非NULL,1表示 NULL。
    * 记录头信息:固定占用5个字节,40位。存储信息如下:
    image.png

  • 隐藏列
    分为三个:事务ID、回滚指针、RowID
    事务ID:占用 6 字节
    回滚指针:占用 7 字节
    * ROWID:占用 6 字节(没有设置primary key 时,会自动产生给字段
  • 真实数据
    存储每一列数据(NULL值不存储不占空间,只在 NULL标志位中有一个标识)

    小贴士: 在定义表结构时,一定要定义 primary key ,否则一条记录会多 6 个字节的浪费(ROWID)

2.2、行格式:Redundant

image.png
行格式如图所示,分为三类

  • 记录的额外信息
    分为两个:字段长度偏移列表、记录头信息
    字段长度偏移列表:字段的长度信息都进行存储,不过长度的计算是通过偏移量进行计算。
    记录头信息:固定占用6个字节,48位。存储信息如下:
    image.png
  • 隐藏列
    分为三个:事务ID、回滚指针、RowID
    事务ID:占用 6 字节
    回滚指针:占用 7 字节
    * ROWID:占用 6 字节(没有设置primary key 时,会自动产生给字段
  • 真实数据
    存储每一列数据(NULL值不存储不占空间,只在 NULL标志位中有一个标识)

    小贴士: 在定义表结构时,一定要定义 primary key ,否则一条记录会多 6 个字节的浪费(ROWID)

三、行格式:Dynamic

MySQL5.7 默认的行格式位:Dynamic 。
Dynamic 和 Compact 类似,不同点在于对行溢出的处理。
Dynamic 在行溢出时,会把所有的字节存储在其他页中,只在记录的真实数据存储处存储其他页面的地址(指针占用20字节),如下:
image.png
对比 Compact 行溢出,如下图:

保留前 768 字节,剩余的保存在 BLOB 页中。

image.png

四、行格式:Compressed

Compressed 和 Dynamic 类似,不同点在于 Compressed 在存储的时候会将行数据以 zlib 算法进行压缩。

五、知识点

1、

每个记录的头信息中都有⼀个next_record属性,从⽽使页中的所有记录串联成⼀个单链表。