前言

了解行结构的意义:

  1. 知道设置好的主键可以节省空间
  2. 知道char的大小设置错误还不如varchar
  3. 知道字符集对变长字段类型的影响
  4. 知道null 和 空串的区别
  5. 还有一些…我还没发现

Compact行结构 一图以弊之

一、Innodb四种行格式

  1. COMPACT 紧凑型行格式
  2. REDUNDANT 字段长度偏移类型
  3. DYNAMIC 动态行格式
  4. COMPRESSED 压缩行格式

二、COMPACT行格式示意图

三、变长字段长度列表

1.目的

针对于变长字段列入VARCHAR,VARBINARY,TEXT,BLOB等变长字段类型,由于存储的字段长度不固定,如果不记录该字段的真实长度,那么就无法计算出这一行的准确长度,那么就无法进行行与行的切分。
所以变长字段会占用两部分空间,第一部分是数据的长度,另一部分是该数据所占用的字节数。

2.规则

  1. 变长字段长度列表是按照逆序存放 的,(这是跟页读取有关,后面补充)
  2. 变长字段的值为null时,不显示在变长字段长度列表中
  3. 变长字段的实际字节长度小于127时,用一个字节表示。 大于127时,用两个字节表示,最多也只需要用2个字节(这个跟内存页的规定有关,这里暂不拓展)
  4. 一个字节8个比特位,最高位为0时,表示这个字段占一个字节,2^7-1 = 127。如果是两个字节,那么第一个字节的最高位应该为1,这样才会读取第二个字节跟第一个字节进行组合表示。

3.逆序读取变长字段长度列表

在经过2次尝试后,发现变长字段长度列表是从后往前读的。虽然知道字段的摆放顺序是逆序的,但是对于读取的顺序是逆序的很多文档和书籍中并没有提到。
16进制变长字段长度列表为: 03 0e 81
先读取81,发现最高位为1,那么表示这是一个双字节表示一个字段的实际长度,接着读取0e,将81的最高位改为0后,组成的双字节数字就是该字段的实际长度270
(03) 这里首位字符为0表示单字节表示一个字段的实际长度,字段实际长度为3

4.字符与字节之间的计算

变长字段长度列表存储的是该字段字节的长度,而我们在定义的时候一般是定义的字符的长度,那么如何计算呢?
变长字段最大字节数计算公式:
最大字节数 = 字段最大字符数*字符集单个字符最大字节数
这里有几个定义需要解释一下
字段最大字符数是指的在你定义varchar(M)时,这个M就是你能存储的最大字符数
字符集单个字符最大字节数指的是该字符集最多用几个字节来表示一个字符。
最常见的utf8mb4字符集就是用1~4个字节来表示一个字符。

四、null值列表

1.目的

null值列表就是告知在字段中,哪些可能为null的值是null,哪些不是null。这样就能按照顺序正确的读取字段的值。

2.规则

  1. 只有字段值可为null的字段才能显示在null值列表中
  2. null值列表是通过bit位来进行标识的,一个字段占一个比特位
  3. null值列表bit位是按照字段逆序排列的
  4. 当字段的比特位不够8的倍数时,需要在高位补0
  5. 字段值为null的bit位为1,否则为0

五、固定头信息

1.目的

记录行的位置,页信息,记录类型等信息,是固定的五个字节的大小

2.头信息的组成

名称 大小(bit位) 描述
预留位 1 没有使用
预留位 1 没有使用
delete_flag 1 删除标识
min_rec_flag 1 B+树每层非叶子节点中最小的目录项记录都会添加该标记(涉及到索引,后面会写)
n_owned 4 一个页有多条记录,这些记录会再进行分组,每个分组有个老大,老大回存储这个分组中有几条记录,这个是给老大用的
heap_no 13 当前记录在页中相对位置
record_type 3 记录类型 0表示普通记录 1表示B+树非叶子节点的目录项记录 2表示Infimum记录 3表示Supremum记录
next_record 16 下调记录的相对位置

以上表格中刚好可以组成一个5字节的头信息数据

六、额外信息

1.作用

这个信息是mysql自动生成的信息,主要包括row_id 行号 ,trx_id事务id ,roll_pointer 回滚指针。因为mysql是聚簇索引,所有的记录其实就是一颗索引树,所有的记录在树的最底层的叶子节点上。如果我们没有设置主键,也没有一个不存在null值的Unique键,那么mysql会为我们创建一个row_id来作为主键。

名称 大小(字节数) 是否必须 描述
row_id 6 行号,当没有主键也没有不为null的Unique键时才会生成
trx_id 6 事务ID
roll_pointer 6 回滚指针

七、真实记录

在额外信息之后,就是字段的真实数据,按照顺序排放,null值字段被省略(通过null值列表进行组合成完整的字段记录数据)

八、验证

1.基于最简单的ASCII测试与解析行格式

# 创建数据库
create database mysqlstudy;# 创建基础表
create table compact_record_demo(col1 varchar(10),col2 char(5),col3 int,col4 varchar(5),col5 varchar(15) not null
) charset=ascii row_format=COMPACT;

# 插入数据
insert into compact_record_demo (col1,col2,col3,col4,col5) values ('aa','bbb',4,null,'cccc');
insert into compact_record_demo (col1,col2,col3,col4,col5) values ('0',null,5,null,'cccc');

2.获取数据文件

然后去/var/lib/mysql/mysqlstudy 目录下去取出数据文件 compact_record_demo.ibd文件

3.找到行记录所在位置

Sublime Text打开ibd文件, 根据ASCII对照找到a所对应的16进制值61 。然后再Sublime Text中搜索

这一块就是真实数据内容了
那我们开始解析第一条行记录

4.变长字段长度列表计算流程:

col1 长度是2,对应的十六进制就是0x02 ,计入变长字段列表
col2 长度是3,对应十六进制就是0x03,但是是定长字符类型,所以不计入变长字段列表
col3 定长数字 不计入变长字段长度列表
col4 值为null ,不计入变长字段长度列表,计入null值列表
col5 长度为4,对应十六进制值为0x04,计入变长字段列表
那么变长字段列表的16进制展示形式为 0x04 0x02,而这条记录的尾部为’cccc’,十六进制展现形式为63636363,那么根据一头一尾,我们可以确定整条行记录的信息为一下的内容

5.compact_record_demo的第一条记录解析:

0402 // 变长字段列表
08 // null值列表
00 00 10 00 2a //固定头信息 5个字节
00 00 00 00 24 00 // 没有主键时,固定6个字节的rowId,作为主键
00 00 00 26 5a c8 // 事务ID 固定6个字节
ba 00 00 01 f6 01 10 // 回滚指针 固定7个字节
61 61 // 字段col1
62 62 62 20 20 // 字段col2 值为 bbb ,由于是定长char,所以会在后面补20空格
80 00 00 04 // 字段col4 值为4(整型数据表示法会在后面进行补充
63 63 63 63 // 字段5 值为cccc

6.null值列表计算

col1 col2 col3 col4 都可以为null ,所以需要四个bit位来展示,那么会占用一个字节,所以08表示null值列表
二进制表现形式:00001000
基于前面null值列表的规则,可以计算出每个字段对应的位置和对应位置bit位的值

九、小结

在学习的过程中,只有不断理解,不断验证,最后进行归纳总结,才能转化为自己的东西。其中可能有些谬误之处,希望不会对后来者造成坏的影响。我所使用的mysql版本是5.7。

mysql学习-Innodb行格式compact行记录解析相关推荐

  1. MySQL原理 - InnoDB引擎 - 行记录存储 - Compact 行格式

    MySQL 服务器上负责对表中数据的读取和写入工作的部分是存储引擎,比如 InnoDB.MyISAM.Memory 等等,不同的存储引擎一般是由不同的人为实现不同的特性而开发的,目前OLTP业务的表如 ...

  2. mysql行格式_MySQL 行格式

    以 MySQL 默认的存储引擎 InnoDB 为例 InnoDB 包含以下四种行格式 Compact Redundant Dynamic Compressed 指定行格式 CREATE TABLE 表 ...

  3. Mysql学习笔记4-外键约束的要求解析

    有foreign关键词的pid称为外键列和id参照列具有相同/相似的数据类型,在数字的情况下必须相同,字符的情况下可以不同:外键列和参照列必须创建索引,相同长度.有无符号位相同的特征: 有外键的表称为 ...

  4. mysql format row_MySQL之InnoDB存储引擎:Row Format行格式

    MySQL下用的比较多.比较广的存储引擎就属InnoDB.这里我们来介绍下InnoDB存储引擎下数据记录的存储格式--Row Format行格式 基本操作 在MySQL中,所谓Row Format行格 ...

  5. 深入理解InnoDB(1)—行的存储结构

    1.InnoDB页的简介 页(Page)是 Innodb 存储引擎用于管理数据的最小磁盘单位.常见的页类型有数据页.Undo 页.系统页.事务数据页等 2.InnoDB行的存储格式 我们插入MySQL ...

  6. MySQL中InnoDB

    MySQL中有很多存储引擎,MyISAM.InnoDB.BDB(支持事务).MEMORY(存储在内存中).MERGE.NDB Cluster.ARCHIEVE.CSV.BLACKHOLE.FEDERA ...

  7. mysql compact_[MySQL]InnoDB行格式剖析_MySQL - compact

    ... $this->layout->main=View::make('dash')->nest('content','comments.list',compact('comment ...

  8. 【MySQL】InnoDB行格式、数据页结构以及索引底层原理分析

    目录 一.MySQL架构图 二.InnoDB数据页结构 2.1 局部性原理 2.2 InnoDB的数据页格式 三.InnoDB的行格式 3.1 Compact行格式 3.1.1 变长字段长度列表 3. ...

  9. MySQL InnoDB存储引擎下的行格式与页格式

    InnoDB存储引擎是面向行的,也就是说数据是按照行进行存放的.常用的行记录格式有Compact和Redundant. Compact行记录格式 Compact行记录的格式如下 变长字段长度列表 NU ...

最新文章

  1. 函数字节不对齐函数崩溃_Excel中统计字符数,不需要一个一个的数,len函数能轻松搞定...
  2. python使用笔记:if __name__ == ‘__main__‘ 如何理解
  3. CDN加速服务有什么功能和作用?
  4. 华为Android9.0谷歌框架,华为Mate9怎样登陆谷歌商店 Mate9如何安装谷歌服务框架【详解】...
  5. 用VuePress来搭建一个极简的静态网站
  6. dma访问主存时_DMA导致Cache数据一致性问题的原因及其解决方式(理论篇)
  7. tp_link路由器 重新设置
  8. OS-written test2
  9. javascript开发HTML5游戏--斗地主(单机模式part1)
  10. excel中vlookup函数的使用方法_Excel中Vlookup——从入门到放弃
  11. 中国多端柔性直流输电行业发展分析及投资可行性调研报告2022-2028年版
  12. java 微信 图灵机器人_使用图灵api创建微信聊天机器人
  13. 丰厚资本杨守彬:创业就是从地狱到天堂,路过人间而已
  14. 颜色,色相环知识分享
  15. 把视频转换成图片帧的代码
  16. 自驾游分享你的快乐来[有车大师]吧!
  17. 三相逆变器双pi控制器参数如何调节_光伏逆变器MPPT基本原理李星硕
  18. 北邮校长方滨兴将离职 临别奉送学生“六好”锦囊
  19. Elmo NAACl 2018
  20. 把Kingston优盘做成USB-CDROM启动盘

热门文章

  1. 3.python数据分析处理库pandas(学习笔记)
  2. Max GCD(暴力)
  3. LIGO找到首个超越广义相对论的证据?
  4. OC:关于Itunes你了解多少?
  5. 超详细,Python库 Bokeh 数据可视化实用指南
  6. Dr.COM宽带认证客户端网络环境使用路由器上网
  7. iMazing如何恢复苹果手机被下架App软件应用
  8. 程序员北漂奋斗九年 终于在北京买房
  9. macbook有什么好用的软件吗?macbook上好用的软件推荐
  10. 1.前端笔记之html