mysql原理--InnoDB记录结构

news2024/11/25 11:03:27

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 2151
假设要存储一个占据257字节的变长字段,数值为0x101,结合小端存储,最高位固定为1。所以,MySQL存储上先是0x01,再是0x81。
当可变字段实际尺寸很长,以至于超过 2 15 − 1 2^{15} - 1 2151时,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_ID6 字节行ID,唯一标识一条记录
DB_TRX_ID6 字节事务ID
DB_ROLL_PTR7 字节回滚指针

这里需要提一下 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切割。每个切割出的内容构成一个页。每个页按其性质有特定的页内数据组织方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1287700.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

罗技鼠标使用接收器和电脑重新配对

罗技鼠标使用接收器和电脑重新配对 文章目录 罗技鼠标使用接收器和电脑重新配对1\. 前言2\. 安装软件3\. 进行配对3.1. 取消之前的配对3.2. 重新配对3.3 配对完成 4\. 报错4.1. 重新配对时显示配对未成功 1. 前言 罗技的鼠标出厂的时候&#xff0c;默认的是将通道一设置为接收…

『亚马逊云科技产品测评』活动征文|基于亚马逊EC2云服务器部署Gogs服务

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 亚马逊EC2云服务器&#xff08;Elastic Compute Cloud&#xff09;是亚马…

Redis穿透以及解决方法

Redis穿透是指当一个请求在缓存中和数据库都找不到对应的数据时&#xff0c;导致每次请求都要查询数据库&#xff0c;从而产生了大量的无效数据库查询&#xff0c;大量无效的数据库查询会导致数据库负载增加&#xff0c;降低数据库的性能和响应能力甚至宕机的风险。 这种情况通…

nodejs+vue+微信小程序+python+PHP天天网站书城管理系统的设计与实现-计算机毕业设计推荐

本项目主要分为前台模块与后台模块2个部分&#xff0c;详细描述如下&#xff1a;   &#xff08;1&#xff09;前台模块 首页: 首页可以起到导航的作用&#xff0c;用户想要了解网站 &#xff0c;网站首页为用户可以深入了解网站提供了一个平台&#xff0c;它就向一个“导游”…

【模型可解释性系列一】树模型-拿到特征重要度-打印关键因素

接下来一段时间内&#xff0c;会主要介绍下模型可解释性方向的一些常用方法。 模型可解释性&#xff1a;主要用来解释为什么这个样本的特征是这样的时候&#xff0c;模型结果是那样。面向老板汇报工作(尤其是不懂算法的老板)和业务方。 常用的树模型 xgboost、lightgbm这两个…

京东数据分析:2023年10月京东打印机行业品牌销售排行榜

鲸参谋监测的京东平台10月份打印机市场销售数据已出炉&#xff01; 10月份&#xff0c;打印机市场整体销售下滑。鲸参谋数据显示&#xff0c;今年10月份&#xff0c;京东平台打印机的销量将近60万&#xff0c;环比降低约2%&#xff0c;同比降低约5%&#xff1b;销售额为4.4亿&a…

Install4J安装界面中如何使用脚本找到依赖程序XShell的安装位置

前言 写了一个工具, 使用Install4j打包, 但因为需要用到XShell, 所以希望在安装界面能够提前让用户配置好XShell的安装位置, 所以对Install4j的安装界面需要自定义, 后期在程序中直接过去安装位置就可以正常使用. 调研 和git-bash不一样, 安装版的XShell没有在注册表里存储安…

通过keepalived+nginx实现 k8s apiserver节点高可用

一、环境准备 K8s 主机配置&#xff1a; 配置&#xff1a; 4Gib 内存/4vCPU/60G 硬盘 网络&#xff1a;机器相互可以通信 k8s 实验环境网络规划&#xff1a; podSubnet&#xff08;pod 网段&#xff09; 10.244.0.0/16 serviceSubnet&#xff08;service 网段&#xff09;: 1…

quickapp_快应用_快应用与h5交互

快应用与h5交互 h5跳转到快应用[1] 判断当前环境是否支持组件跳转快应用[2] h5跳转到快应用(1)deeplink方式进行跳转(推荐)(2)h5点击组件(接收参数存在问题)(3)url配置跳转(官方不推荐) 问题-浏览器问题 web组件h5页面嵌入快应用快应用发送消息到h5页面h5页面接收快应用发送的消…

微前端 前置知识2--- monorepo架构

目录 前言 pnpm vs npm pnpm设计思想 硬连接 软链接 &#xff08;符号链接&#xff09; 原理 pnpm 指令 monorepo架构 介绍 配置monorepo pnpm --filter 前言 我们采用的是微前端一个主应用&#xff0c;和多个子应用&#xff0c;我们肯定不会一个一个去install安装…

【教程】苹果推送证书的创建和使用流程详解

摘要 本篇博客主要介绍了苹果推送证书的使用流程。首先&#xff0c;在苹果开发者中心创建推送证书&#xff0c;然后在应用程序中使用该证书进行消息推送。文章详细说明了创建推送证书的步骤&#xff0c;并提供了在应用程序中注册推送服务、发送推送消息以及处理推送消息的相关…

CentOS最小化安装后怎么转图形界面/可视化桌面?

文章目录 1、命令行和图形界面切换方式一方式二 2、最小化安装转桌面1-设置网络2-测试网络3-更新文件4-安装图形5-查看默认6-设置默认 界面效果参考视频 1、命令行和图形界面切换 如果安装的是最小化&#xff0c;那么init 5 (进入图像化桌面)命令是无效的 方式一 1.如果在命…

把 Windows 11 装进移动硬盘:Windows 11 To Go

本篇文章聊聊如何制作一个可以“说带走就带走”的 Windows 操作系统&#xff0c;将 Windows11 做成能够放在 U 盘或者移动硬盘里的 WinToGo “绿色软件”。 写在前面 在《开源的全能维护 U 盘工具&#xff1a;Ventoy》这篇文章的最后&#xff0c;我提到了一个关键词 “WinToG…

带你学C语言:带你学函数

目录 &#x1f30d;函数的概念 ★★☆☆☆库函数 ★★★★☆自定义函数 ★★★☆☆形参与实参 ★★★☆☆return语句 ★★★☆☆数组做函数参数 ★★★☆☆嵌套调用和链式访问 ★★★☆☆函数的声明和定义 ✍结束语 &#x1f30d;函数的概念 数学中我们其实就见过函数…

校园局域网规划设计

摘 要 随着网络技术的发展&#xff0c;校园网的建设已经进入到一个蓬勃发展的阶段。校园网的建成和使用&#xff0c;对于提高教学和科研的质量、改善教学和科研条件、加快学校的信息化进程&#xff0c;开展多媒体教学与研究以及使教学多出人才、科研多出成果有着十分重要而深远…

Oracle连接错误:ORA-28040:没有匹配的验证协议

一、产生原因&#xff1a;oci动态库版本太低&#xff0c;无法连接高版本的数据库 二、解决办法 1、下载高版本的oci库 https://www.oracle.com/database/technologies/instant-client/winx64-64- downloads.html 2、解压并复制oci动态库 3、粘贴到相应的目录

学校图书管理系统的开发

目 录 摘要 1 Abstract. 1 1 引言 2 1.1 图书管理的现状 2 1.2 现有图书管理系统的概述 3 1.3 选题的目的、意义 3 1.4 图书管理系统的可行性分析 4 1.5 系统开发运行环境 4 2 图书管理系统开发相关技术的介绍 5 2.1 Asp.net的介绍 5 2.1.1 Asp.net的优势介绍 5 2.1.2 Asp.net…

3D模型制作木质纹理贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 本文将讲解如何使用GLTF 编辑器 -NSDT 在线材质编辑工具为3D模型设置…

逆水行舟!浅谈24届双非本科秋招

逆水行舟&#xff01;浅谈24届双非本科的秋招 逆水行舟&#xff01;浅谈24届双非本科的秋招0、背景 -- 写下本文的初衷1、实习 -- 秋招的预备战役1.1 科大讯飞1.2 三七互娱 2、秋招 -- 一场没有硝烟的战争3、总结 -- 做好自己想做的事情 0、背景 – 写下本文的初衷 如题&#…

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…