mysql原理--InnoDB记录结构
1.InnoDB行格式
我们平时是以记录为单位来向表中插入数据的,这些记录在磁盘上的存放方式也被称为 行格式 或者 记录格式 。
设计 InnoDB 存储引擎的大叔们到现在为止设计了4种不同类型的 行格式 ,分别是 Compact 、 Redundant 、Dynamic 和 Compressed 行格式。
1.1.指定行格式的语法
我们可以在创建或修改表的语句中指定 行格式 :
CREATE TABLE 表名 (列的信息) ROW_FORMAT=行格式名称;
ALTER TABLE 表名 ROW_FORMAT=行格式名称;
1.2.实例解析
我们后续基于下述实例进行说明。
mysql> CREATE TABLE record_format_demo (-> c1 VARCHAR(10),-> c2 VARCHAR(10) NOT NULL,-> c3 CHAR(10),-> c4 VARCHAR(10)-> ) CHARSET=ascii ROW_FORMAT=COMPACT;
mysql> INSERT INTO record_format_demo(c1, c2, c3, c4) VALUES('aaaa', 'bbb', 'cc', 'd'), ('eeee', 'fff', NULL, NULL);
1.3.COMPACT行格式

1.3.1.记录的额外信息
(1). 变长字段长度列表
我们知道 MySQL 支持一些变长的数据类型,比如 VARCHAR(M) 、 VARBINARY(M) 、各种 TEXT 类型,各种 BLOB 类型,我们也可以把拥有这些数据类型的列称为 变长字段 ,变长字段中存储多少字节的数据是不固定的,所以我们在存储真实数据的时候需要顺便把这些数据占用的字节数也存起来,这样才不至于把 MySQL 服务器搞懵,所以这些变长字段占用的存储空间分为两部分:
a. 真正的数据内容
b. 占用的字节数
在 Compact 行格式中,把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位,从而形成一个变长字段长度列表,各变长字段数据占用的字节数按照列的顺序逆序存放。
我们拿 record_format_demo 表中的第一条记录来举个例子。因为 record_format_demo 表的 c1 、 c2 、 c4 列都是 VARCHAR(10) 类型的,也就是变长的数据类型,所以这三个列的值的长度都需要保存在记录开头处,因为 record_format_demo 表中的各个列都使用的是 ascii 字符集,所以每个字符只需要1个字节来进行编码,来看一下第一条记录各变长字段内容的长度:

由于第一行记录中 c1 、 c2 、 c4 列中的字符串都比较短,也就是说内容占用的字节数比较小,用1个字节就可以表示,但是如果变长列的内容占用的字节数比较多,可能就需要用2个字节来表示。具体用1个还是2个字节来表示真实数据占用的字节数, InnoDB 有它的一套规则,我们首先声明一下 W 、 M 和 L 的意思:
(1). 字符集中表示一个字符最多需要使用的字节数为 W。
(2). 对于变长类型 VARCHAR(M) 来说,这种类型表示能存储最多 M 个字符(注意是字符不是字节),所以这个类型能表示的字符串最多占用的字节数就是 M×W 。
(3). 它实际存储的字符串占用的字节数是 L 。
确定使用1个字节还是2个字节表示真正字符串占用的字节数的规则就是这样:
(1). 如果 M×W <= 255 ,那么使用1个字节来表示真正字符串占用的字节数。
(2). 如果 M×W > 255 ,则分为两种情况:
a. 如果 L <= 127 ,则用1个字节来表示真正字符串占用的字节数。
b. 如果 L > 127 ,则用2个字节来表示真正字符串占用的字节数。
当用两字节存储占用字节数时,首先MySQL采用小端存储,然后两字节的数值的最高位固定为1。所以,可存储的最大值为: 2 15 − 1 2^{15} - 1 215−1。
假设要存储一个占据257字节的变长字段,数值为0x101,结合小端存储,最高位固定为1。所以,MySQL存储上先是0x01,再是0x81。
当可变字段实际尺寸很长,以至于超过 2 15 − 1 2^{15} - 1 215−1时,MySQL有溢出页机制来处理。
(2).NULL值列表
我们知道表中的某些列可能存储 NULL 值,如果把这些 NULL 值都放到 记录的真实数据 中存储会很占地方,所以 Compact 行格式把这些值为 NULL 的列统一管理起来,存储到 NULL 值列表中,它的处理过程是这样的:
a. 首先统计表中允许存储 NULL 的列有哪些。
主键列、被 NOT NULL 修饰的列都是不可以存储 NULL 值的。
b. 如果表中没有允许存储 NULL 的列,则 NULL值列表 也不存在了,否则将每个允许存储 NULL 的列对应一个二进制位,二进制位按照列的顺序逆序排列,二进制位表示的意义如下:
b.1.二进制位的值为 1 时,代表该列的值为 NULL 。
b.2.二进制位的值为 0 时,代表该列的值不为 NULL 。
因为表 record_format_demo 有3个值允许为 NULL 的列,所以这3个列和二进制位的对应关系就是这样:

c. MySQL 规定 NULL值列表 必须用整数个字节的位表示,如果使用的二进制位个数不是整数个字节,则在字节的高位补 0 。
表 record_format_demo 只有3个值允许为 NULL 的列,对应3个二进制位,不足一个字节,所以在字节的高位补 0 ,效果就是这样:

上述实例中插入两行后,存储信息如下:

(3).记录头信息
是由固定的 5 个字节组成。 5 个字节也就是 40 个二进制位,不同的位代表不同的意思,如图:

1.3.2.记录的真实数据
对于 record_format_demo 表来说, 记录的真实数据 除了 c1 、 c2 、 c3 、 c4 这几个我们自己定义的列的数据以外, MySQL 会为每个记录默认的添加一些列(也称为 隐藏列 ),具体的列如下:
| 列名 | 是否必须 | 占用空间 | 描述 |
|---|---|---|---|
| DB_ROW_ID | 否 | 6 字节 | 行ID,唯一标识一条记录 |
| DB_TRX_ID | 是 | 6 字节 | 事务ID |
| DB_ROLL_PTR | 是 | 7 字节 | 回滚指针 |
这里需要提一下 InnoDB 表对主键的生成策略:优先使用用户自定义主键作为主键,如果用户没有定义主键,则选取一个 Unique 键作为主键,如果表中连 Unique 键都没有定义的话,则 InnoDB 会为表默认添加一个名为 DB_ROW_ID 的隐藏列作为主键。所以我们从上表中可以看出:InnoDB存储引擎会为每条记录都添加 DB_TRX_ID 和 DB_ROLL_PTR 这两个列,但是 DB_ROW_ID 是可选的(在没有自定义主键以及Unique键的情况下才会添加该列)。
上述实例插入两行的实际内容:

1.3.3.CHAR(M)列的存储格式
如果采用变长的字符集(也就是表示一个字符需要的字节数不确定,比如gbk 表示一个字符要1~2个字节、 utf8 表示一个字符要1~3个字节等)的话,此时即使列的类型是形如 CHAR(M) 类型时,也视为变长字段。相应的变长字段长度列表会包含此列尺寸信息。
变长字符集的 CHAR(M) 类型的列要求至少占用 M 个字节,而 VARCHAR(M) 却没有这个要求。比方说对于使用 utf8 字符集的 CHAR(10) 的列来说,该列存储的数据字节长度的范围是10~30个字节。即使我们向该列中存储一个空字符串也会占用 10 个字节。
2.行溢出数据
2.1.VARCHAR(M)最多能存储的数据
MySQL内部限制用户表一行存储中,剔除行中类型BLOB,TEXT类型字段,剔除隐藏列,记录头后剩余部分累计尺寸不可超过65535。因此,VARCHAR(M)中 M 受此限制影响可设置的最大值是有限制的。
2.2.记录中的数据太多产生的溢出
MySQL 中磁盘和内存交互的基本单位是 页 ,也就是说 MySQL 是以 页 为基本单位来管理存储空间的,我们的记录都会被分配到某个 页 中存储。而一个页的大小一般是 16KB ,也就是 16384 字节,而一个 VARCHAR(M) 类型的列就最多可以存储 65532 个字节,这样就可能造成一个页存放不了一条记录的尴尬情况。
在 Compact 和 Reduntant 行格式中,对于占用存储空间非常大的列,在 记录的真实数据 处只会存储该列的一部分数据,把剩余的数据分散存储在几个其他的页中,然后 记录的真实数据 处用20个字节存储指向这些页的地址(当然这20个字节中还包括这些分散在其他页面中的数据的占用的字节数),从而可以找到剩余数据所在的页,
如图所示:

从图中可以看出来,对于 Compact 和 Reduntant 行格式来说,如果某一列中的数据非常多的话,在本记录的真实数据处只会存储该列的前 768 个字节的数据和一个指向其他页的地址,然后把剩下的数据存放到其他页中,这个过程也叫做 行溢出 ,存储超出 768 字节的那些页面也被称为 溢出页 。
最后需要注意的是,不只是 VARCHAR(M) 类型的列,其他的 TEXT、BLOB 类型的列在存储数据非常多的时候也会发生 行溢出 。
2.3.行溢出的临界点
MySQL 中规定一个页中至少存放两行记录。当无法在一个页中完成两行记录的完整存储时,会通过页溢出来完成记录信息存储。
2.4.理解MySQL磁盘和内存交互以页面为单位
上述实例表对应一个磁盘上的文件record_format_demo.ibd,就是说上述文件内容按16KB切割。每个切割出的内容构成一个页。每个页按其性质有特定的页内数据组织方式。
相关文章:
mysql原理--InnoDB记录结构
1.InnoDB行格式 我们平时是以记录为单位来向表中插入数据的,这些记录在磁盘上的存放方式也被称为 行格式 或者 记录格式 。 设计 InnoDB 存储引擎的大叔们到现在为止设计了4种不同类型的 行格式 ,分别是 Compact 、 Redundant 、Dynamic 和 Compressed 行…...
ES6基础语法
目录 一、解构 数组解构 对象解构 字符串解构 数值解构 布尔值解构 二、箭头函数 和普通函数区别? 三、拓展运算符 ... 一、解构 给右侧值匹配对应的变量 等号两侧模式一定要匹配 数组解构 /*** 解构:从数组或者对象中提取值,给变量进行赋值操作就…...
java8 常用code
文章目录 前言一、lambda1. 排序1.1 按照对象属性排序:1.2 字符串List排序:1.3 数据库排序jpa 2. 聚合2.1 基本聚合(返回对象list)2.2 多字段组合聚合(直接返回对象list数量) 二、基础语法2.1 List2.1.1 数…...
docker 镜像管理
搜索镜像:这种方法只能用于官方镜像库搜索基于 centos 操作系统的镜像# docker search centos 按星级搜索镜像: 查找 star 数至少为 100 的镜像,默认不加 s 选项找出所有相关 ubuntu 镜像: # docker search ubun…...
Jira 中如何修改时间为绝对时间
问题描述 在使用Jira的时候,有一些时间显示的是相对时间,如:2天前,3个小时前等,有些用户不习惯这样的显示方式,希望使用绝对的时间格式,如:2022年2月22日 22:22 应该怎样修改 解…...
班级查分软件制作教程:老师必备技能!
首先,你需要选择一个合适的软件平台来制作班级查分软件。推荐使用群发成绩,因为它是一个功能强大且易于使用的在线查询系统,可以帮助你快速高效地制作班级查分软件。 在制作班级查分软件之前,你需要准备好学生的成绩数据。这可以…...
Linux 的性能调优的思路
Linux操作系统是一个开源产品,也是一个开源软件的实践和应用平台,在这个平台下有无数的开源软件支撑,我们常见的apache、tomcat、mysql等。 开源软件的最大理念是自由、开放,那么Linux作为一个开源平台,最终要实现的是…...
如何通过webdriver禁用浏览器定位功能
今天碰到一个小问题,在使用了代理ip的情况下访问某些站点,但是还是显示本地的ip地址,这个是什么问题呢,原来是谷歌浏览器默认打开了定位功能 那么问题来了,如何在使用webdriver的时候关闭浏览器的定位功能呢࿱…...
网卡bonding绑定
目录 一、概念 1、概述: 二、实验 1、绑定案例: 一、概念 1、概述: 将多个物理网卡进行排列组合,形成逻辑网卡,网卡的高可用 绑定模式 mode0(平衡负载模式):平时两块网卡均工…...
flink运行报Exception in thread “main“ java.lang.IllegalStateException
问题描述 运行flink程序时报异常,异常信息如下: Exception in thread "main" java.lang.IllegalStateException: No ExecutorFactory found to execute the application.at org.apache.flink.core.execution.DefaultExecutorServiceLoader.g…...
易点易动设备管理系统--提升设备备品备件管理效率的工具
设备备品备件管理是市场推广人员关注的重要问题之一。为了帮助市场推广人员提升设备备品备件管理效率,易点易动设备管理系统应运而生。本文将详细介绍易点易动设备管理系统的功能和优势,以及如何借助该系统提高设备备品备件管理效率,提升企业…...
第二十一章——网络通信
一.网络程序设计基础 1.局域网与互联网 2.网络协议 1.IP协议 IP是Internet Protocol的简称,是一种网络协议。 1.1 TCP/IP层次结构 2.TCP与UDP协议 TCP可保证数据从一端送至另一端时,能够确实送达,而且抵达的数据的排列顺序和送出时的顺序相…...
Siemens-NXUG二次开发-打开与关闭prt文件[Python UF][20231206]
Siemens-NXUG二次开发-打开与关闭prt文件[Python UF][20231206] 1.python uf函数1.1 NXOpen.UF.Part.Open1.2 NXOpen.UF.Part.LoadStatus1.3 NXOpen.UF.Part.Close1.4 NXOpen.UF.Part.AskUnits 2.示例代码3.运行结果3.1 内部模式3.2 外部模式 1.python uf函数 1.1 NXOpen.UF.P…...
2015年五一杯数学建模C题生态文明建设评价问题解题全过程文档及程序
2015年五一杯数学建模 C题 生态文明建设评价问题 原题再现 随着我国经济的迅速发展,生态文明越来越重要,生态文明建设被提到了一个前所未有的高度。党的十八大报告明确提出要大力推进生态文明建设,报告指出“建设生态文明,是关系…...
java:slf4j、log4j、log4j2、logback日志框架的区别与示例
文章目录 背景SLF4J - 简单日志门面:Log4j - 强大而古老的日志框架:Log4j2 - Log4j的升级版:Logback - Log4j的继任者:比较Springboot集成slf4j、log4j2参考 背景 在Java开发中,日志记录是一个不可或缺的组成部分。为了满足不同的需求,Java社区涌现出多…...
Mysql学习查缺补漏----02 mysql之DCL 数据控制语言
查看数据库里都有哪些用户。 使用root任何一个用户都可以登录。 本机登录。 也可以这样登录其他的机器。 、 修改user表。 刷新权限: 现在我们看到了只有本机才能登陆。 我们这样就可以限制这个mysql指定某台服务器登录。 详解忘记密码以及如何修改用户密码 我们…...
【Flink基础】-- 延迟数据的处理
目录 一、关于延迟的一些概念 1、什么是延迟? 2、什么导致互联网延迟?...
通过keepalived+nginx实现 k8s apiserver节点高可用
一、环境准备 K8s 主机配置: 配置: 4Gib 内存/4vCPU/60G 硬盘 网络:机器相互可以通信 k8s 实验环境网络规划: podSubnet(pod 网段) 10.244.0.0/16 serviceSubnet(service 网段): 1…...
JavaScript 数组
JavaScript 数组 用来存储一系列相关数据的一种数据类型 创建数组 字面量方式 ----- [1,2,3,4,5,6];实例化构造函数 ----- new Array(1,2,3,4,5,6);组成数组的元素可以是任意的数据类型包括数组本身; new Array(n): n 表示数组的长度 内容操作 获取(查…...
【数据结构】二叉树的实现
目录 1. 前言2. 二叉树的实现2.1 创建一棵树2.2 前序遍历2.2.1 分析2.2.2 代码实现2.2.3 递归展开图 2.3 中序遍历2.3.1 分析2.3.2 代码实现2.3.3 递归展开图 2.4 后序遍历2.4.1 分析2.4.2 代码实现2.4.3 递归展开图 2.5 求节点个数2.5.1 分析2.5.2 代码实现 2.6 求叶子节点个数…...
【权威实测】Perplexity UI v2.8.3组件查询API响应延迟骤降76%的6项必调参数
更多请点击: https://intelliparadigm.com 第一章:Perplexity UI组件库查询的性能瓶颈全景图 Perplexity UI 是一个面向复杂数据交互场景的前端组件库,其核心查询能力依赖于动态 Schema 解析与实时渲染管道。在高并发、多层级嵌套组件查询场…...
固态存储寿命优化与文件系统写入放大实战
1. 固态存储寿命与文件系统的隐秘战争当我在2015年第一次拆解一块过早失效的工业级固态硬盘时,发现其内部闪存单元的磨损程度存在严重不均。这个现象引发了我对文件系统与固态存储寿命关系的长期研究。传统认知中,我们更关注SSD的TBW(总写入字…...
AugGPT:基于上下文感知的AI代码生成器设计与实现
1. 项目概述:当代码生成器遇上“增强现实”如果你和我一样,长期在代码的海洋里“游泳”,那么对GitHub上琳琅满目的代码生成工具一定不陌生。从早期的代码片段补全,到如今能生成完整函数甚至模块的AI助手,它们确实极大地…...
汽车电子功能安全:锁步核与ECC技术解析
1. 功能安全与汽车电子:为什么它如此重要?在现代汽车电子系统中,功能安全已经从"锦上添花"变成了"不可或缺"。想象一下,当你的车辆以120km/h在高速公路上行驶时,电子稳定控制系统(ESC)突然因为一个…...
【仅剩47份】Midjourney商业设计实战包:含12套行业LORA模型、287组可商用Prompt库、PS/AI智能对接插件
更多请点击: https://intelliparadigm.com 第一章:Midjourney商业设计实战包核心价值解析 Midjourney商业设计实战包并非通用提示词合集,而是一套面向品牌视觉资产量产的工程化工具链,聚焦于可复用性、合规性与交付确定性三大维…...
3分钟搞定京东自动抢购:Python工具终极完整指南
3分钟搞定京东自动抢购:Python工具终极完整指南 【免费下载链接】autobuy-jd 使用python语言的京东平台抢购脚本 项目地址: https://gitcode.com/gh_mirrors/au/autobuy-jd 还在为京东秒杀总是抢不到而烦恼吗?手动操作总是慢人一步,眼…...
Ironclad/Rivet:现代开发者的效率革命,从环境配置到工具链整合
1. 项目概述:从“铁甲”到“铆钉”,一个现代开发者的效率革命 如果你和我一样,常年混迹在代码仓库和命令行之间,那你一定对“工具链”这个词又爱又恨。爱的是,一套顺手的工具能让开发效率飞起;恨的是&#…...
绍兴geo优化:亲测高性价比公司分享
绍兴GEO优化:亲测高性价比公司分享 随着AI搜索流量占比持续攀升,绍兴企业正面临传统推广方式成本高、效率低的挑战。在这样的背景下,GEO(地理围栏优化)技术成为了提高本地精准流量获取的关键手段。本文基于最新的调研…...
EDEM-Fluent-CFD风道耦合:多物理场协同仿真实战指南
1. 从零开始理解EDEM-Fluent-CFD风道耦合 第一次接触气固两相流仿真时,我被各种专业术语搞得晕头转向。直到在风机设计项目中踩了三次坑,才真正理解EDEM-Fluent-CFD耦合的价值。简单来说,这就像给风道系统做"数字CT"——用EDEM模拟…...
PyTorch进阶教程:从模型部署到工程化实战全解析
1. 项目概述与核心价值最近在深度学习社区里,一个名为“TingsongYu/PyTorch-Tutorial-2nd”的项目引起了我的注意。作为一名在算法工程领域摸爬滚打了多年的从业者,我深知对于初学者和希望系统进阶的开发者来说,一份结构清晰、内容扎实、且能…...
