MySQL——行格式介绍

文章目录

  • 一、行格式介绍及特点
  • 二、4种行格式的介绍
    • 1、REDUNDANT行格式(冗余行格式)
      • REDUNDANT行格式的特点
    • 2、COMPACT行格式
      • COMPACT行格式的特点
    • 3、DYNAMIC行格式(动态行格式)
    • 4、COMPRESSED行格式(压缩行格式)
  • 三、故障处理

一、行格式介绍及特点

1、行格式的应用都是针对于表的,只有在创建表的时候才能使用row_format,在创建库的时候无法指定行格式。

2、表的行格式也是决定了这张表下面的物理存储方式,会影响查询和DML操作的性能。

3、常见的表格式有以下4种:
(1)REDUNDANT
(2)COMPACT
(3)DYNAMIC
(4)COMPRESSED
各种表格式的特点及缺点:
MySQL——行格式介绍_第1张图片
4、随着更多的行适合单个的磁盘页面,查询和索引查找可以更快的工作,因为更多的行在同一个页面上,所需要写或者读的IO会需要的更少,所以能更大程度的提升性能。

5、每个表的数据一般的话会被分成几个页,每个表里面的页都会组成相应的B树索引,根据索引去排列数据的顺序。

6、可变长度的列值,因为其变长的特性,可能会无法容纳在B树页面上,而是会单独分配到磁盘页面上,这些磁盘页面的话称为溢出页面。这些列的话是称为页外列。这些列的话会存储在溢出页面的单链表中,然而这样的列如果过多的话,是会有一个或者多个这种溢出页面的列表。

7、根据列的长度,所有的列值或可变长度的列值的前缀都会存储在B树中,用来避免浪费存储空间而去读取单独的页面。这样的话会降低磁盘使用率,还增加了IO的负载。

8、一般的变长字段列类型有:varchar、varbinary、blob、text类型

二、4种行格式的介绍

1、REDUNDANT行格式(冗余行格式)

(1)redundant行格式的表会把前768字节的变长列值存在在B树节点的索引记录中,多余的一些字节会被存在在溢出页。而大于这个768字节的固定长度列会被编码为可变长度列,可以放在页面外进行存储。
(2)例1:char(10)当char的字符集最大长度为3,其实是可以超过30个字节,与utf8mb4字符集相同。
(3)如果列值小于768字节,则不会使用溢出页,该列的值会全部存在在B树节点中,这样也可以节省IO去页溢出页
(4)对于一些列类型为blob的较短值比较友好,但是如果B树节点存储了数据,而没有存储键值的话,效率也会变低。

REDUNDANT行格式的特点

1、该行格式索引记录标头为6字节,标头会将连续的数据存在在一起,用于行锁定。

2、聚集索引会把所有用户定义的列字段记录进去,会有一个6字节的txid字段和一个7字节的roll pointer field。

3、如果没定义主键,聚集索引会包含一个6字节的行ID字段。

4、每个二级索引中包含的是聚集索引定义的主键值,而并非每一行的数据。

5、每条记录都会有一个指向这条记录每个字段的指针。字段总长小于128字节,指针为1字节,否则指针为2字节。

6、定长字段列char(10)以定长格式存储,后面的空格不会从varchar字段中截断。

7、大于768的固定长度会被编码为可变长度列,可以存储在页面外。在例1中提到了

8、一条SQL中,NULL值在这行的数据页中会保留一个或者两个字节。NULL如果存储在可变长度列中,在数据部分则是0字节。如果在固定长度列,该列的固定长度会保留在数据部分,因为万一有数据插入进来,这个保留的NULL值空间可以从原来的NULL值位置更新为非NULL值,这样的话就不会造成索引页碎片。

2、COMPACT行格式

1、与REDUNDANT相比,COMPACT的行格式将存储空间减少了20%,如果有调整缓存命中率和磁盘速度的限制,那COMPACT会更快。
但是也会增加一些CPU的使用率,如果是在有大量运算的一些环境下,这种格式可能会比REDUNDANT较慢一些。

2、使用这种格式的页,前768字节的变长列值存储在B树索引记录中,其余的一些字段被存储在溢出页上,大于或等于768字节的固定长度也会被编码为可变长度列,可以存储在页面外。参考例1

3、列值小于或等于768字节,不使用溢出页,这样的话就完全存储在B树索引中,节省IO。参考REDUNDANT行格式第5条。

COMPACT行格式的特点

1、该行格式索引记录标头为5字节,这个标头的前面可以有一个可变长度的标头,按列的顺序逆序放置。标头也是用来链接记录,用于行锁定。

2、提到的可变长度的标头实际是用来存储NULL列的,索引中可为NULL的列为Y的话,这个可变长度的标头长度就为Y字节。

3、标头的可变长度部分还包含可变长度列的长度。每个长度占用一个或两个字节,具体取决于列的最大长度。如果列中都是固定长度,,记录头的话就没有可变长度的部分。

4、记录头后面跟的是非NULL的列值。

5、聚集索引还是包含6字节的TXID和7字段的roll pointer field。

6、如果表中没有主键,还会有一个6字节的ROWID

7、如果主键列是可变长度,即使二级索引定义了固定长度列,每个二级索引记录头在他们的记录长度中都会有一个可变长度部分。

8、引用REDUNDANT第6条

9、对于可变长度字符集utf8mb3和utf8mb4,如果数据的字节长度超过了列类型的字节长度,列的类型为char(n)列的最大长度将变成“最大字节长度*N”。

3、DYNAMIC行格式(动态行格式)

这种行格式有和COMPACT行格式相同的行存储方式,只是在其基础上增加了long variable-length columns 和large index key prefixes。
特点:
1、长可变列(long variable-length)
2、更大的索引键前缀的存储能力(maximum byte length)
3、支持索引键前缀3072字节

4、COMPRESSED行格式(压缩行格式)

该行格式与DYNAMIC行格式有相同的存储特性和功能,在这个基础上还添加了对表和索引数据压缩的支持。
1、如果要使用该行格式的话需要启用innodb_file_per_table。

三、故障处理

因为传统的两种行格式是支持utf8的3字节最大长度,所以在255的情况下,varchar超出了最大列的长度,超过了755字节,所以报错了,需要设置成dynamic行格式或者compressed格式。
报错:

db01 [pavthistory]>create table alert_record1 ( id bigint(25) not null, belong_device varchar(255) default null,  update_time datetime not null, serial bigint(25) default null, event_name varchar(255) default null, detail varchar(255) default null, primary key (`id`,`update_time`)using btree, key `alert_device_time` (`belong_device`,`update_time`)using btree ) engine=innodb charset=utf8mb4 row_format=compact;
ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.

解决办法:

create table alert_record1 (.....) engine=innodb charset=utf8mb4 row_format=dynamic;
Query OK, 0 rows affected (0.01 sec)

改变相应行格式即可解决!
部分内容借鉴官方文档!
提供官方链接感兴趣的小伙伴也可以去官方文档查看相关内容。

你可能感兴趣的:(数据库层面)