《MySQL高级篇》五、InnoDB数据存储结构(四)

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 《MySQL高级篇》五、InnoDB数据存储结构

3.4.2 记录头信息(record header)

不同于Compact行格式,Redundant行格式中的记录头信息固定占用6个字节(48位),每位的含义见下表

0f9500a21737b6a198d37642ea859665.jpg

与Compact行格式的记录头信息对比来看,有两处不同:(下面的解释,了解即可)


Redundant行格式多了n_field和1byte_offs_flag这两个属性。

Redundant行格式没有record_type这个属性。

其中,n_fields:代表一行中列的数量,占用10位,这也很好地解释了为什么MySQL一个行支持最多的列为1023。另一个值为1byte_offs_flags,该值定义了偏移列表占用1个字节还是2个字节。当它的值为1时,表明使用1个字节存储。当它的值为0时,表明使用2个字节存储。


1byte_offs_flag的值是怎么选择的 ?


我们前边说过每个列对应的偏移量可以占用1个字节或者2个字节来存储,那到底什么时候用1个字节,什么时候用2个字节呢?其实是根据该条Redundant行格式记录的真实数据占用的总大小来判断的:


当记录的真实数据占用的字节数值不大于127(十六进制0x7F,二进制01111111)时,每个列对应的偏移量占用1个字节。


当记录的真实数据占用的字节数大于127,但不大于32767(十六进制0x7FFF,二进制0111111111111111)时,每个列对应的偏移量占用2个字节。


有没有记录的真实数据大于32767的情况呢?有,不过此时的记录已经存放到了溢出页中,在本页中只保留前768个字节和20个字节的溢出页面地址。因为字段长度偏移列表处只需要记录每个列在本页面中的偏移就好了,所以每个列使用2个字节来存储偏移量就够了。


大家可以看出来,Redundant行格式还是比较简单粗暴的,直接使用整个记录的真实数据长度来决定使用1个字节还是2个字节存储列对应的偏移量。只要整条记录的真实数据占用的存储空间大小大于127,即使第一个列的值占用存储空间小于127,那对不起,也需要使用2个字节来表示该列对应的偏移量。简单粗暴,就是这么简单粗暴(所以这种行格式有些过时了)。


为了在解析记录时知道每个列的偏移量是使用1个字节还是2个字节表示的,Redundant行格式特意在记录头信息里放置了一个称之为1byte_offs_flag的属性:


Redundant行格式中NULL值的处理


因为Redundant行格式并没有NULL值列表,所以Redundant行格式在字段长度偏移列表中的各个列对应的偏移量处做了一些特殊处理 —— 将列对应的偏移量值的第一个比特位作为是否为NULL的依据,该比特位也可以被称之为NULL比特位。也就是说在解析一条记录的某个列时,首先看一下该列对应的偏移量的NULL比特位是不是为1。如果为1,那么该列的值就是NULL,否则不是NULL。


这也就解释了上边介绍为什么只要记录的真实数据大于127(十六进制0x7F,二进制01111111)时,就采用2个字节来表示一个列对应的偏移量,主要是第一个比特位是所谓的NULL比特位,用来标记该列的值是否为NULL。


但是还有一点要注意,对于值为NULL的列来说,该列的类型是否为定长类型决定了NULL值的实际存储方式,我们接下来分析一下record_test_table表的第二条记录,它对应的字段长度偏移列表如下:

A4 A4 1A 17 13 0C 06

按照列的顺序排放就是:

06 0C 13 17 1A A4 A4

我们分情况看一下:


如果存储NULL值的字段是定长类型的,比方说CHAR(M)数据类型的,则NULL值也将占用记录的真实数据部分,并把该字段对应的数据使用0x00字节填充。

如图第二条记录的c3列的值是NULL,而c3列的类型是CHAR(10),占用记录的真实数据部分10字节,所以我们看到在Redundant行格式中使用0x00000000000000000000来表示NULL值。

另外,c3列对应的偏移量为0xA4,它对应的二进制实际是:10100100,可以看到最高位为1,意味着该列的值是NULL。将最高位去掉后的值变成了0100100,对应的十进制值为36,而c2列对应的偏移量为0x1A,也就是十进制的26。36 - 26 = 10,也就是说最终c3列占用的存储空间为10个字节。

如果该存储NULL值的字段是变长数据类型的,则不在记录的真实数据处占用任何存储空间。

比如record_test_table表的c4列是VARCHAR(10)类型的,VARCHAR(10)是一个变长数据类型,c4列对应的偏移量为0xA4,与c3列对应的偏移量相同,这也就意味着它的值也为NULL,将0xA4的最高位去掉后对应的十进制值也是36,36 - 36 = 0,也就意味着c4列本身不占用任何记录的实际数据处的空间。

除了以上的几点之外,Redundant行格式和Compact行格式还是大致相同的


总结:Redundant行格式和Compact行格式的差异


Redundant 没有了NULL值列表


Redundant 行格式的记录头信息


多了n_field和1byte_offs_flag这两个属性


没有record_type这个属性。


4. 区、段与碎片区


4.1 为什么要有区?


cc9c31b2cb20557f155603d2a7a1808a.png


4.2 为什么要有段?


83270d06213714324b7a30d719bda0a1.png


4.3 为什么要有碎片区?


e41b32861564137f58fe41728b82a9ef.png


4.4 区的分类


81463d574dd046dd77da21b23a8092e8.png


5. 表空间


cbed1716576f4e27d142559011b03c59.png


5.1 独立表空间


178597e1944fad58f8313aaac58c02ba.png

dd237a7f0284949e0d244252f0cab2f6.png


你能看到inndb_file_per_table=ON,这意味着每张表都会单独保存一个.ibd文件


5.2 系统表空间


c18249567339aec25ba18ed2dba745b3.png

dbb058b4d753805962f0dec24893eb89.png

63348a04060bcc58aa0ccd3630450724.png

9cce6527bec50757b268d56f01251296.png


c3f5caf7ff225f829cec3efdf3d48db9.png


附录:数据页加载的三种方式


d89509efe70ea245216a69458c590fd0.png


a7841e72a92ef8a596a724178e132c4a.png


338ba6d172863e78b0523bee03dac980.png


7cd18a848b70bdd008252c5d8dd65e23.png





相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
存储 关系型数据库 MySQL
MySQL InnoDB数据存储结构
MySQL InnoDB数据存储结构
|
1月前
|
存储 缓存 关系型数据库
MySQL的varchar水真的太深了——InnoDB记录存储结构
varchar(M) 能存多少个字符,为什么提示最大16383?innodb怎么知道varchar真正有多长?记录为NULL,innodb如何处理?某个列数据占用的字节数非常多怎么办?影响每行实际可用空间的因素有哪些?本篇围绕innodb默认行格式dynamic来说说原理。
828 6
MySQL的varchar水真的太深了——InnoDB记录存储结构
|
8天前
|
存储 关系型数据库 MySQL
MySQL引擎对决:深入解析MyISAM和InnoDB的区别
MySQL引擎对决:深入解析MyISAM和InnoDB的区别
24 0
|
2月前
|
SQL 关系型数据库 MySQL
mysql语句结构
mysql语句结构
23 3
|
11天前
|
关系型数据库 MySQL 数据库
mysql卸载、下载、安装(window版本)
mysql卸载、下载、安装(window版本)
|
1月前
|
关系型数据库 MySQL 数据库连接
关于MySQL-ODBC的zip包安装方法
关于MySQL-ODBC的zip包安装方法
|
29天前
|
关系型数据库 MySQL 数据库
rds安装数据库客户端工具
安装阿里云RDS的数据库客户端涉及在本地安装对应类型(如MySQL、PostgreSQL)的客户端工具。对于MySQL,可选择MySQL Command-Line Client或图形化工具如Navicat,安装后输入RDS实例的连接参数进行连接。对于PostgreSQL,可以使用`psql`命令行工具或图形化客户端如PgAdmin。首先从阿里云控制台获取连接信息,然后按照官方文档安装客户端,最后配置客户端连接以确保遵循安全指引。
82 1
|
24天前
|
Ubuntu 关系型数据库 MySQL
Ubuntu 中apt 安装MySQL数据库
Ubuntu 中apt 安装MySQL数据库
66 0
|
3天前
|
关系型数据库 MySQL Linux
Linux联网安装MySQL Server
Linux联网安装MySQL Server
13 0
|
3天前
|
关系型数据库 MySQL Linux
centos7安装mysql-带网盘安装包
centos7安装mysql-带网盘安装包
33 2