目录

  • InnoDB 的行格式
  • COMPACT 行格式
  • REDUNDANT 行格式
  • 溢出列
  • DYNAMIC 行格式和 COMPRESSED 行格式


啥是存储引擎呢? 简单来说就是数据的存储一般是在硬盘,而数据的处理一般是在内存,但是这两者速度差距又比较大,势必会影响处理速度,存储引擎就是在这个问题上想了想办法。
那具体是啥办法呢?我们需要处理数据时,要把数据都从硬盘搞到内存是不太现实,因为又不是都有用,再说了就是都有用空间也不应定够,空间够时间也不允许。所以就得一块一块的搞过来,InnoDB就是先把数据分了页,一页一般是16KB,一次就搞一页到内存,或者从内存到硬盘。当然了这个页的大小可以通过 系统变量 innodb_page_size 设置。需要注意的是这个只能第一次初始化数据目录时指定(mysql --initialize)。

页是 lnnoDB 中磁盘和内存交互的基本单位,也 lnnoDB 管理存储空间的基本单位,默
认大小为 16KB

下边讲的是页里边存的东西。

InnoDB 的行格式

数据在磁盘上存的格式为行格式(或记录格式)。目前有4种行格式:COMPACT、REDUNDANT、DYNAMIC 和 COMPRSSED。我们可以使用如下语句设置和更改表的行格式:

CREATE TABLE 表名 (列的信息) ROW_FORMAT=行的格式;
ALTER TABLE 表名 ROW_FORMAT=行的格式;

下面我们来介绍一下几种行格式:

COMPACT 行格式

他主要由“记录的额外信息”和“记录的真实数据”两部分构成。大概长这个样子:

mysql innodb文件丢失_数据

  1. 额外信息-变长字段长度列表
    存储了一些变长的字段(VARCHAR、TEXTD等)他们的实际长度。进而组成了一个变长字段长度列表,其中按照 列的顺序 逆序存放。那具体来说,是用一个字节来表示实际长度还是两个呢?总体的原则呢要么就是设置表结构时所设的最大长度就是小于255的那就用一个没问题。但是如果大于255,那就意味着这个变长字段可能用一个字节表示其长度,也可能用两个。这就完蛋了,因为我们不知道是一个还是两个,所以要留出一个位标识一下,也就是如果实际长度小于等于127就用一个字节,大于127就用2个。(NULL 值不存储)
  2. 额外信息-NULL值列表
    所有允许存储NULL 值的列都对应一个二进制位,是0说明不为空,1说明为空。这些二进制位也是安照列顺序逆序存放。存储空间为整数个字节,不足高位补零。
  3. 额外信息-记录头信息
    此部分固定为5个字节的长度,不同位的信息如下所示:

mysql innodb文件丢失_database_02

是不是有点多,看一眼涨涨见识吧,别为难自己。

  1. 真实数据
    此部分除了存储实际的列信息也会有隐藏列,如下:

mysql innodb文件丢失_mysql_03

其中我们发现row_id并不是必须的,为啥呢?因为InnoDB生成表的主键是先用用户定义的,没有就找不允许NULL且UNIQUE的,没有就创建这个row_id的隐藏列作为主键。
接下来,就存真实列数据,NULL不存,固定长的字符没有用完的位用空格补高位。

注意: 对于CHAR(M),当用定长编码集时不会加入到变长列表,当用变长编码集时会加入变长列表。但对CHAR(M) 的列数据要求是至少占M个字节,对VARCHAR没要求。也就是说CHAR(10) 在编码为utf8的列 占用范围为(10-30)

REDUNDANT 行格式

注意: REDUNDANT有点过时了,了解即可.

他的格式如下所示:

mysql innodb文件丢失_mysql_04

  1. 字段长度偏移列表
    记录了包含隐藏列的字段偏移,依旧是按列顺序逆序存储
  2. 记录头信息
    REDUNDANT 行格式多了 n_field(记录中列的数量,n_field所占大小10位) 和 1byte_offs_flag(记录字段长度偏移列表中的偏移量是用一个字节还是两个) 这两个属性,没有了record_type这个属性。

关于1byte_offs_flag的确定还是参考了真实数据的实际长度0-127 一字节,128-0x7fff两字节。

  1. NULL值要看列类型是否为变长,具体来说就是变长没有值就是NULL不占空间,但是不变长没有值还是会占空间,用0x00填充。至于如何表示NULL,使用的是字段长度偏移的首位表示。

溢出列

溢出列是啥呢?我们在前边说了一般MySQL一个数据页的大小是16k,我们介绍了半天介绍的是行格式,那这一页存不下一行咋办呢?就溢出了呗,这就是溢出列。(MySQL规定的是一页至少存两行记录,存不下两行就会成为溢出列)

DYNAMIC 行格式和 COMPRESSED 行格式

DYNAMIC 行格式是MySQL5.7默认的行格式,这两个行格式和我们介绍的COMPACT行格式比较像。他们相较于COMPACT主要是对溢出列的处理不同,COMPACT当发生溢出时会先存一些真实数据,有一部分放入溢出列,然后记录溢出列的地址和剩余大小; 这两种行格式是都把真实数据放到溢出列,只记录溢出列的地址和剩余大小。另外,COMPRESSED 对真实数据做了压缩处理。