当前位置: 代码网 > it编程>数据库>Mysql > MySQL之InnoDB引擎中的Compact行格式用法

MySQL之InnoDB引擎中的Compact行格式用法

2025年06月26日 Mysql 我要评论
1、背景mysql中数据存储是存储引擎干的事,innodb存储引擎以页为单位存储数据,每个页的大小为16kb,平时我们操作数据库都是以行为单位进行增删改查,行数据是存储在页上的,行的格式有4种:com

1、背景

mysql中数据存储是存储引擎干的事,innodb存储引擎以页为单位存储数据,每个页的大小为16kb,平时我们操作数据库都是以行为单位进行增删改查,行数据是存储在页上的,行的格式有4种:compat、redundant、dynamic、compressed,今天我们来讲一下compat行格式。

2、数据示例

我们建表语句中使用的varchar、text、blob等类型不确定长度的就使用了compact行格式,为了方便理解我们手动创建一个表并且插入两条记录,后面都结合这两条记录来进行compat行格式讲解,表和记录如下:

  • 创建表
create table test_compact
(
    id int auto_increment primary key,
    str1 varchar(255) not null default '',
    str2 varchar(255),
    str3 char(5)
) engine = innodb default charset = utf8mb4 row_format=compact;
  • 插入数据
insert into test_compact (str1, str2, str3)
values ('aa', 'bb', 'ccc'),
       ('aaa', null, null);
  • 查看数据
mysql [xxx]> select * from test_compact;
+----+------+------+------+
| id | str1 | str2 | str3 |
+----+------+------+------+
|  1 | aa   | bb   | ccc  |
|  2 | aaa  | null | null |
+----+------+------+------+
2 rows in set (0.001 sec)
  • 查看表的行格式
mysql [xxx]> show table  status like 'test_compact' \g;
*************************** 1. row ***************************
            name: test_compact
          engine: innodb
         version: 10
      row_format: compact //目前表使用的行格式
            rows: 2
  avg_row_length: 8192
     data_length: 16384
 max_data_length: 0
    index_length: 0
       data_free: 0
  auto_increment: 3
     create_time: 2024-12-13 17:20:47
     update_time: 2024-12-13 17:21:02
      check_time: null
       collation: utf8mb4_general_ci
        checksum: null
  create_options: row_format=compact  //创建表时指定的格式
         comment: 
max_index_length: 0
       temporary: n
1 row in set (0.001 sec)

3、compact解释

【1】组成

compact行格式组成图如下:

在这里插入图片描述

compact行由头部信息+隐藏行+数据列三部分组成。

  • 头部信息:由三部分组成,可变长度列的实际长度信息、列是否为null信息、描述记录信息。
  • 隐藏列:有三列,db_row_id、db_trx_id、db_roll_ptr,后面详细讲解。
  • 数据列:每一列的值。

【2】头部信息

头部信息可以如图表示:

在这插入图片描述

接下来就结合上面创建的test_compact表和插入的记录进行理解。

可变长度列指的就是表中的str1和str2字段,因为str1和str2长度不固定,所以需要额外花费空间来记录str1和str2的长度,str1和str2的值只有不为null的时候才需要记录长度,并且str1和str2长度的顺序是根据列顺序的逆序来存放。

存放str1和str2长度大小为1个或者2个字节,判断方法是:可变字段存储的最大字节>255字节并且真实存储的字节数>127字节就使用2个字节存储长度,否则使用1个字节存储长度。

可变字段存储的最大字节=varchar(n)里的n * 字符集的最大字节数。n代表的是字符数,而我们用的utf8mb4字符集1个字符用1~4个字节表示,可以用如下命令看:

mysql [xxx]> show charset like 'utf8mb4';
+---------+---------------+--------------------+--------+
| charset | description   | default collation  | maxlen |
+---------+---------------+--------------------+--------+
| utf8mb4 | utf-8 unicode | utf8mb4_general_ci |      4 |
+---------+---------------+--------------------+--------+
1 row in set (0.001 sec)

可以看到utf8mb4可以表示的一个字符最大字节为4,所以str1和str2列可以存储的最大字节数为255 * 4 = 4080,ascii字符只占用1个字节,第一条记录中的str1和str2实际长度都为2个字节。

同样的str3的类型为char(5),根据字符集决定存它储字节的范围为5~20,所以str3的长度信息也需要进行存储。

第一条记录str3内容’ccc’长度看起来虽然为3,实际上长度为5,这是为了防止更新str3为大于3小于5的数据时,以前的空间就成为了空间碎片需要释放。

可以用下图表示上面2条记录长度的存储信息:

可以为null列表指的就是没有not null修饰的str2和str3列,用二进制的0和1来表示列是否为null值,0代表非null,1代表null,根据列的顺序逆序排列null信息,必须用二进制的整数倍来存储null信息,不足1字节高位补0,上面2条记录的null信息如下:

在这里插入图片描述

行记录描述信息是由5个字节也就是40个二进制位组成,不同位代表不同的含义,不做过多解释。

【3】隐藏列

innodb存储引擎会为每一行数据额外分配三个列:db_row_id、db_trx_id、db_roll_ptr,通过表格来理解一下:

隐藏列描述大小
db_row_id唯一标识6字节
db_trx_id事务id6字节
db_roll_ptr指向要回滚数据的地址7字节

db_row_id只有主键和unique健都不存在时,innodb存储引擎会创建一个大小为6字节作为隐藏主键id使用。

【4】数据列

数据列只需要注意值为null的列不需要再去花空间去存储,因为头部信息的null列表已经存储了是否为null,所以上面2条记录完整表示如下:

在这里插入图片描述

4、总结

本篇文章讲了compact行格式组成,其它几种格式都差不多,redundant会记录所有列的长度信息,通过相邻列的偏移量来计算列的长度;dynamic、compressed格式在行溢出(列数据过于大页面存不下)时列数据只存储其它页的地址,数据全存储在其它页通过链表连接;compact和redundant会在当前页存储一部分数据信息和在其它页的剩余数据地址。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

  • MySQL之InnoDB存储引擎中的索引用法及说明

    MySQL之InnoDB存储引擎中的索引用法及说明

    1、背景innodb存储引擎的基本存储单位是页,索引也是存储在页上的,b+树中非叶子节点的页也是数据页,和我们插入数据的区别是存放的行记录叫目录项记录,我们插入... [阅读全文]
  • mysql中的数据目录用法及说明

    mysql中的数据目录用法及说明

    1、背景安装mysql之后,在安装目录下会有一个data目录,我们创建的数据库、创建的表、插入的数据都是存储在这个目录中,可以大概了解一下这个目录下是怎么存储数... [阅读全文]
  • MySQL之InnoDB存储页的独立表空间解读

    1、背景我们往一张表里插入的行数据是存储在页上的,一张页的大小为16kb,数据量大的时候一张页不可能存储完一张表里的所有数据,所以需要多张页来进行存储,这多张页所在的存储空间就叫表…

    2025年06月26日 数据库
  • MySQL中的InnoDB单表访问过程

    MySQL中的InnoDB单表访问过程

    1、背景mysql通过查询条件查询到结果的过程就叫访问方法,一条查询语句的访问方法有很多种,接下来我们就来讲一下各种访问方法。2、环境创建表:mysql>... [阅读全文]
  • MySQL 中 ROW_NUMBER() 函数最佳实践

    MySQL 中 ROW_NUMBER() 函数最佳实践

    mysql 中row_number()函数详解row_number()是 sql 窗口函数中的一种,用于为查询结果集中的每一行分配一个​​唯一的连续序号​​。与... [阅读全文]
  • MySQL中的表连接原理分析

    MySQL中的表连接原理分析

    1、背景在进行sql查询时有时需要多张表的查询结果组成一个共同的结果返回,这时就用到了mysql中连接的用法,接下来就以两张表来讲解表连接的原理。2、环境创建两... [阅读全文]

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com