InnoDB行格式

查看默认行格式:
select @@innodb_default_row_format;
查看数据库表使用的行格式
mysql> use atguigudb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A Database changed
mysql> create table emp3 ( id int, name varchar(50) ) row_format=compact;
Query OK, 0 rows affected (0.02 sec) mysql> show table status like 'emp3'\G
*************************** 1. row ***************************
Name: emp3
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 0
Avg_row_length: 0
Data_length: 16384
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: NULL
Create_time: 2023-04-03 00:27:36
Update_time: NULL
Check_time: NULL
Collation: utf8mb3_general_ci
Checksum: NULL
Create_options: row_format=COMPACT
Comment:
1 row in set (0.00 sec)
修改行格式
mysql> alter table emp3 row_format=dynamic;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0 mysql> show table status like 'emp3'\G
*************************** 1. row ***************************
Name: emp3
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 0
Avg_row_length: 0
Data_length: 16384
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: NULL
Create_time: 2023-04-03 00:32:49
Update_time: NULL
Check_time: NULL
Collation: utf8mb3_general_ci
Checksum: NULL
Create_options: row_format=DYNAMIC
Comment:
1 row in set (0.00 sec)
compact行格式

  • 变长字段长度列表:mysql中支持变长的数据类型,即变长字段中存储的字节数不是固定的,如VARCHAR、VARBINARY、TEXT、BLOB类型,但是在实际存储真实数据的时候需要记录数据占用的字节数,COMPACT行格式将变长字段占用的长度放在记录的开头部位,形成变长字段长度列表

    字段的变长字段列表以及下面的存储都是倒序的,这是因为底层都是二进制,逆序正好是存放在低位

  • NULL值列表:Compact行格式会把表中可以为NULL的字段统一管理起来,存在这个标记为NULL值列表中,如果表中没有可以为NULL的字段,则NULL值列表也就不存在了

    如有三个字段a、b、c,其中a是主键,存储a=0,b=null,c=2,则行格式中的NULL值列表会存储01,0代表c不为null(倒序所以c在前面),0代表b为null,NULL值列表会自动跳过主键和NOT NULL字段

  • 记录头信息(5字节):前面讲了,见2.2

  • 记录的真实数据:一条记录的真实记录部分除了我们自己定义的列的数据,还会有三个隐藏列:

    • row_id:行id,唯一标识一条记录
    • transaction_id:事务id
    • roll_pointer:回滚指针

    row_id即是前面在介绍INNODB创建聚簇索引的时候,在没有主键和unique作为索引的情况下为每一列指定的一个自动主键

​ 下面创建一个表,来底层查看一下记录的二进制文件(开卷!)

​ 然后查看数据库表的十六进制显示的ibd文件:

  • 03 02 01:对应记录的变长字段长度列表,即倒序为col4、col2、col1的实际存储字节,col3为定长,所以不记录
  • 00:NULL值列表,表示全不为null
  • 00 00 10 00 2c(正好五个字节):记录头信息
  • 00 00 00 2b 68 00(6B):row_id
  • 00 00 00 00 06 05(6B):trasaction_id
  • 80 00 00 00 32 01 10(7B):roll_pointer
  • 61:16进制的a
  • 62 62: 16进制的bb
  • 62 62 20 ... 20:定长字段bb,20表示为空

Dynamic与Compressed行格式
行溢出

​ 在创建表的时候,如使用varchar变长类型,按照类型大小应该能够设置varchar(65535),提示创建失败:[Err] 1118 - Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs

CREATE TABLE test (
`name` VARCHAR(65535)
)CHARSET=ASCII ROW_FORMAT=COMPACT;

使用ASCII编码的原因是一个字符占一个字节(变长类型的括号中的是字符),否则默认的表编码为utf8,则是65535个字符 = 65535 / 3 个字节

​ 而使用65532就能创建成功

CREATE TABLE test (
`name` VARCHAR(65532)
)CHARSET=ASCII ROW_FORMAT=COMPACT;

原因就在于行格式中,由于记录变长,所以变长字段长度列表会占用两个字节,NULL值列表会占用1个字节

​ 如果使用NOT NULL约束,则就能创建65533大小的表:

CREATE TABLE test (
`name` VARCHAR(65533) NOT NULL
)CHARSET=ASCII ROW_FORMAT=COMPACT;

行溢出:一个页的大小为16KB,即16384个字节,而上面一个字段就用去65535,这种一个页存放不下一条记录的现象,叫做行溢出

页的扩展:在Compact和Redundant行格式中,当出现占用空间特别大的列导致行溢出的时候,在记录真实的数据出只会存储一部分数据,而把剩余数据分散存储在其他几个页中进行分页存储,并使用20个字节存储指向这些地址(并且包含这些分散在其他页的数据所占的字节数),从而可以找到剩余数据所在的页。

Dynamic与Compressed行格式

在MySQL8.0中,默认的行格式就是Dynamic,Dynamic、Compressed行格式和Compact行格式基本相同,只不过在处理行溢出上有所差异,采用的是完全的行溢出方式即行溢出的字段完全不存放真实的数据,只存放20字节存储溢出页的地址。

​ 而Compressed行格式则是在Dynamic的基础上对存储在行之中的数据使用zlib算法进行了压缩,因此对于BLOB、TEXT、VARCHAR这种大长度类型的数据进行有效的存储。

Redundant行格式

​ Redundant行格式是MySQL5.0之前InnoDB的行记录存储方式,和Compact的主要区别在于使用了字段长度偏移列表,而没有变长字段长度列表NULL值列表

字段长度偏移列表:与变长长度列表主要有两处不同:

  • Redundant行格式会将该条记录的所有列(包含隐藏列)的长度按照逆序存储到字段长度偏移列表(记录了全部长度,自然也就不需要NULL值列表了)
  • 使用的是相邻两个数值的差值来计算每个列值的长度

​ 除此之外还有头记录信息中的两个不同,这里就不写了 - -

MySQL(九)InnoDB行格式的更多相关文章

  1. Mysql之InnoDB行格式、数据页结构

    Mysql架构图 存储引擎负责对表中的数据的进行读取和写入,常用的存储引擎有InnoDB.MyISAM.Memory等,不同的存储引擎有自己的特性,数据在不同存储引擎中存放的格式也是不同的,比如Mem ...

  2. 数据页结构 .InnoDb行格式、以及索引底层原理分析

    局部性原理 局部性原理是指CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中. 首先要明白局部性原理能解决的是什么问题,也就是主存容量远远比缓存大, CP ...

  3. InnoDB行格式(compact,redundant)对照

    InnoDB行格式分两种格式(COMPACT,redundant)默觉得COMPACT compact的存储格式为 首部为一个非NULL的变长字段长度列表,并且是依照列的顺序逆序放置的,当列的长度小于 ...

  4. mysql:InnoDB行/表级锁实现/事务

    转载:http://book.51cto.com/art/200803/68127.htm 20.3.4 InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL ...

  5. MySQL锁---InnoDB行锁需要注意的细节

    前言 换了工作之后,接近半年没有发博客了(一直加班),emmmm.....今天好不容易有时间,记录下工作中遇到的一些问题,接下来应该重拾知识点了.因为新公司工作中MySQL库经常出现查询慢,锁等待,节 ...

  6. MySQL Replication--TABLE_ID与行格式复制

    BINLOG中的TABLE_ID 在ROW格式的二进制中,事件信息中没有列的信息,需要通过Table_Map将表名对于的表信息加载到cache中,然后根据事件信息中的列下标来定位到数据列,每次表信息加 ...

  7. 使用MYSQL的INNODB实现任务分发机制

    最近公司有个项目,需要多并发完成任务,也就是一个任务控制中心控制多个WORKER的问题,这里的核心点在于如果WORKER_A正在执行1号任务,任务中心不能让WORKER_B重复执行1号任务,即WORK ...

  8. MySQL Internal - InnoDB存储引擎(行结构)

    InnoDB行存储的三个组成部分(说明: F字符表示列的数量) 名称(Name) 大小(Size) Field Start Offsets (F*1) or (F*2) bytes Extra Byt ...

  9. MySQL InnoDB 行记录格式(ROW_FORMAT)

    MySQL InnoDB 行记录格式(ROW_FORMAT) 一.行记录格式的分类和介绍 在早期的InnoDB版本中,由于文件格式只有一种,因此不需要为此文件格式命名.随着InnoDB引擎的发展,开发 ...

  10. MyISAM和InnoDB的行格式ROW_FORMAT

    MyISAM行存储 MyISAM有3种行存储格式:fixed / dynamic / compressed: 格式 说明 备注   fixed  只有当表不包含变长字段(varchar/varbina ...

随机推荐

  1. 盒模型属性-width height-padding-border-margin

    宽度 width: 作用:设置可以添加元素内容的区域的宽度. 属性值:  特殊应用: • 如果一个元素不添加width 属性,默认属性值为auto,不同的元素浏览器会根据其 特点自动计算出实际宽度,例 ...

  2. Linux 配置nginx 代理tomcat,配置ssl

    我就直接干活不废话: 配置文件nginx, nginx.conf #user nobody;worker_processes 1; #error_log logs/error.log;#error_l ...

  3. String类、StringBuffer类、StringBuilder类

    String类.StringBuffer类.StringBuilder类 String类的创建 // 方式一 直接赋值 String s = "woshihaoren"; // 方 ...

  4. Java线上日志分析

    1.查询关键字前后30行 cat 日志文件名.log | grep -30 '关键字' 例: cat mcs-all.log | grep -30 '2019-04-08 13:30:04,271' ...

  5. 9.29 2020 实验 4:Open vSwitch 实验——Mininet 中使用 OVS 命令

    一.实验目的 Mininet 安装之后,会连带安装 Open vSwitch,可以直接通过 Python 脚本调用Open vSwitch 命令,从而直接控制 Open vSwitch,通过实验了解调 ...

  6. VBA中的结构体

    结构体必须放在"模块"中: Type Org tag As String person As New Collection End Type 使用: Sub testType() ...

  7. vue省市区级联

    省市区级联 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <tit ...

  8. 详解数仓中sequence的应用场景及优化

    摘要:本文简单介绍sequence的使用场景及如何修改sequence的cache值提高性能. 本文分享自华为云社区<GaussDB(DWS)关于sequence的那些事>,作者:Arro ...

  9. Android笔记--通过MediaStore查询图片

    相关描述 已经完成发送彩信功能之后,就来继续向前走一步,来到MediaStore查询图片界面啦! 具体步骤实现 1.简简单单地一个界面 <?xml version="1.0" ...

  10. 顺应潮流,解放双手,让ChatGPT不废话直接帮忙编写可融入业务可运行的程序代码(Python3.10实现)

    众所周知,ChatGPT可以帮助研发人员编写或者Debug程序代码,但是在执行过程中,ChatGPT会将程序代码的一些相关文字解释和代码段混合着返回,如此,研发人员还需要自己进行编辑和粘贴操作,效率上 ...