InnoDB 引擎中一条记录是怎样存储的

页是 MySQL 中磁盘和内存交互的基本单位,也是 MySQL 管理存储空间的基本单位。一个页一般是 16KB,当记录中的数据太多,当前页放不下的时候,会把多余的数据存储到其他页中,这种现象称为行溢出。

记录在磁盘上的存放方式称为 行格式,InnoDB 存储引擎到现在为止设计了 4 种不同类型的行格式,分别是 CompactRedundantDynamic 和 Compressed 行格式。

Compact 行格式

InnoDB 引擎中一条记录是怎样存储的

变长字段长度列表

对于 varchar()text,或者以变长字符集(比如 utf-8)存储的 char(),等数据类型,存储多少字节的数据是不固定的,因此 InnoDB 会在记录的开头存储这些变长字段的真实数据占用的字节长度,形成一个变长字段长度列表,在这个列表中各变长字段占用的字节数按照列的顺序逆序存放。

变长字段长度列表中只存储值为 非 NULL 的列内容占用的长度,值为 NULL 的列的长度是不储存的 。并不是所有记录都有这个 变长字段长度列表 部分,比方说表中所有的列都不是变长的数据类型的话,这一部分就不需要有。

NULL 值列表

如果表中没有允许存储 NULL 的列,则 NULL 值列表 也不存在了,否则将每个允许存储 NULL 的列对应一个二进制位,二进制位按照列的顺序逆序排列。二进制位值为1表示该列的值为NULL。

MySQL 规定 NULL 值列表必须用整数个字节的位表示,如果使用的二进制位个数不是整数个字节,则在字节的高位补 0。

InnoDB 引擎中一条记录是怎样存储的

记录头信息

由固定 5 个字节组成,之后讲数据页结构的时候会详细解释字段代表的含义

记录的真实数据

除了我们自己定义的列数据以外,MySQL 会为每个记录默认的添加一些列(也称为隐藏列),包括 row_id(DB_ROW_ID)、transaction_id(DB_TRX_ID)和 roll_pointer(DB_ROLL_PTR)

InnoDB 表对主键的生成策略:优先使用用户自定义主键作为主键,如果用户没有定义主键,则选取一个 Unique 键作为主键,如果表中连 Unique 键都没有定义的话,则 InnoDB 会为表默认添加一个名为 row_id 的隐藏列作为主键。所以我们从上表中可以看出:InnoDB 存储引擎会为每条记录都添加 transaction_id 和 roll_pointer 这两个列,但是 row_id 是可选的(在没有自定义主键以及 Unique 键的情况下才会添加该列)。

Dynamic 和 Compressed 行格式

这两种行格式类似于 COMPACT 行格式,只不过在处理行溢出数据时有点儿分歧,它们不会在记录的真实数据处存储字符串的前 768 个字节,而是把所有的字节都存储到其他页面中,只在记录的真实数据处存储其他页面的地址。

Compressed 行格式和 Dynamic 不同的一点是,Compressed 行格式会采用压缩算法对页面进行压缩,以节省空间。

以上是 InnoDB 引擎中一条记录是怎样存储的 的全部内容, 来源链接: utcz.com/z/264393.html

回到顶部