MySQL:一行记录如何
1、表空间文件结构
表空间由段「segment」、区「extent」、页「page」、行「row」组成,InnoDB存储引擎的逻辑存储结构大致如下图:
行
数据库表中的记录都是按「行」进行存放的,每行记录根据不同的行格式,有不同的存储结构。
页
记录是按照行来存储的,但是数据库的读取并不以「行」为单位,否则一次读取(也就是一次 I/O 操作)只能处理一行数据,效率会非常低。
因此,InnoDB 的数据是按「页」为单位来读写的,也就是说,当需要读一条记录的时候,并不是将这个行记录从磁盘读出来,而是以页为单位,将其整体读入内存。
默认每个页的大小为 16KB,也就是最多能保证 16KB 的连续存储空间。
页是 InnoDB 存储引擎磁盘管理的最小单元,意味着数据库每次读写都是以 16KB 为单位的,一次最少从磁盘中读取 16KB 的内容到内存中,一次最少把内存中的 16KB 内容刷新到磁盘中。
区
B+ 树中每一层都是通过双向链表连接起来的,如果是以页为单位来分配存储空间,那么链表中相邻的两个页之间的物理位置并不是连续的,可能离得非常远,那么磁盘查询时就会有大量的随机 I/O,随机 I/O 是非常慢的。
【怎么解决呢?】
在表中数据量大的时候,为某个索引分配空间的时候就不再按照页为单位分配了,而是按照「区」为单位分配。每个区的大小为 1MB,对于 16KB 的页来说,连续的 64 个页会被划为一个区,这样就使得链表中相邻的页的物理位置也相邻,就能使用顺序 I/O 了。
段
表空间是由各个段组成的,段是由多个区组成的。段一般分为「数据段」、「索引段」和「回滚段」等。
- 索引段:存放 B + 树的非叶子节点的区的集合。
- 数据段:存放 B + 树的叶子节点的区的集合。
- 回滚段:存放的是回滚数据的区的集合,MVCC 利用了回滚段实现了多版本查询数据。
2、InnoDB 行格式
有下面 4 种行格式:
- Redundant:MySQL 5.0 版本之前用的行格式,不紧凑。
- Compact:MySQL 5.1 版本之后,行格式默认设置成 Compact。一种紧凑的行格式,可以让一页存储更多行记录。
- Dynamic 和 Compressed:从 MySQL5.7 版本之后,默认使用 Dynamic 行格式。 两个都是紧凑的行格式,它们的行格式都和 Compact 差不多,都是基于 Compact 改进一点东西。
COMPACT 行格式
记录的额外信息
1. 变长字段长度列表
varchar(n)和char(n)的区别:char是定长的,varchar是变长的,变长字段实际存储的数据的长度(大小)不固定的。
在存储数据的时候,要把数据占用的大小存起来,存到「变长字段长度列表」里面,读取数据的时候才能根据这个「变长字段长度列表」去读取对应长度的数据。其他 TEXT、BLOB 等变长字段也是这么实现的。
【示例】创建下面表进行演示:
假设有下面三条记录:

第一条记录「只看变长字段」:
name字段值为a,占 1 字节。phone字段值为123,占 3 字节。
这些变长字段的真实数据占用的字节数会按照列的顺序 逆序存放,所以「变长字段长度列表」里的内容是「 03 01」,而不是 「01 03」。
同理,第二条记录:
第三条记录 中 phone 列的值是 NULL,NULL 是不会存放在行格式中记录的真实数据部分里的,所以「变长字段长度列表」里不需要保存值为 NULL 的变长字段的长度。
【为什么「变长字段长度列表」的信息要按照逆序存放】
因为「记录头信息」中指向下一个记录的指针,指向的是下一条记录的「记录头信息」和「真实数据」之间的位置,这样的好处是向左读就是记录头信息,向右读就是真实数据,比较方便。
「变长字段长度列表」中的信息之所以要逆序存放,是因为这样可以使得位置靠前的记录的真实数据和数据对应的字段长度信息可以同时在一个 CPU Cache Line 中,这样就可以提高 CPU Cache 的命中率。
当数据表没有变长字段的时候,比如全部都是 int 类型的字段,这时候表里的行格式就不会有「变长字段长度列表」了,因为没必要,不如去掉以节省空间。
所以「变长字段长度列表」只出现在数据表有变长字段的时候。
2. NULL 值列表
表中的某些列可能会存储 NULL 值,如果把这些 NULL 值都放到记录的真实数据中会比较浪费空间,所以 Compact 行格式把这些值为 NULL 的列存储到 NULL 值列表中。
如果存在允许 NULL 值的列,则每个列对应一个二进制位(bit),二进制位按照列的顺序逆序排列。
- 二进制位的值为
1时,代表该列的值为 NULL。 - 二进制位的值为
0时,代表该列的值不为 NULL。
另外,NULL 值列表必须用整数个字节的位表示(1字节8位),如果使用的二进制位个数不足整数个字节,则在字节的高位补 0。
当一条记录有 9 个字段值都是 NULL,那么就会创建 2 字节空间的「NULL 值列表」,以此类推。
当数据表的字段都定义成 NOT NULL 的时候,这时候表里的行格式就不会有 NULL 值列表了。
所以在设计数据库表的时候,通常都是建议将字段设置为 NOT NULL,这样可以至少节省 1 字节的空间(NULL 值列表至少占用 1 字节空间)。
【举例】以上面表举例:
第一条记录:

但是 InnoDB 是用整数字节的二进制位来表示 NULL 值列表的,现在不足 8 位,所以要在高位补 0,最终用二进制来表示:

第二条记录:

第三条记录 phone 列 和 age 列是 NULL 值,所以,对于第三条数据,NULL 值列表用十六进制表示是 0x06。

NULL 值列表填充完毕后,行格式为下面这样:
3. 记录头信息
列举比较重要的几个:
- delete_mask:标识此条数据是否被删除。执行
detele删除记录的时候,并不会真正的删除记录,只是将这个记录的 「delete_mask」标记为 1 - next_record:下一条记录的位置。记录与记录之间是通过链表组织的,指向的是下一条记录的「记录头信息」和「真实数据」之间的位置,这样的好处是向左读就是记录头信息,向右读就是真实数据,比较方便。
- record_type:表示当前记录的类型,0 表示普通记录,1 表示 B+ 树非叶子节点记录,2 表示最小记录,3 表示最大记录。
记录的真实数据
记录真实数据部分除了自定义的字段,还有三个隐藏字段,分别为:row_id、trx_id、roll_pointer。
-
row_id:建表的时候指定了主键或者唯一约束列,那么就没有 row_id 隐藏字段了。如果既没有指定主键,又没有唯一约束,那么 InnoDB 就会为记录添加 row_id 隐藏字段。row_id 不是必需的,占用 6 个字节。
-
trx_id:事务id,表示这个数据是由哪个事务生成的。 trx_id 是必需的,占用 6 个字节。
-
roll_pointer:这条记录上一个版本的指针。roll_pointer 是必需的,占用 7 个字节。
MVCC 机制就跟 trx_id 和 roll_pointer 的作用有关。
varchar(n) 中的 n 最大取值
MySQL 规定除了 TEXT、BLOBs 这种大对象类型之外,其他所有的列(不包括隐藏列和记录头信息)占用的字节长度「加起来」不能超过 65535 个字节。
varchar(n) 字段类型的 n 代表的是最多存储的字符数量,并不是字节大小。
要算 varchar(n) 最大能允许存储的字节数,还要看数据库表的字符集,因为字符集代表着:1个字符要占用多少字节,比如 ascii 字符集, 1 个字符占用 1 字节,那么 varchar(100) 意味着最大能允许存储 100 字节的数据。
【单字段情况】
在算 varchar(n) 中 n 最大值时,需要减去 「变长字段长度列表」和 「NULL 值列表」所占用的字节数的。
【多字段情况】
如果有多个字段的话,要保证「所有字段的长度 + 变长字段字节数列表所占用的字节数 + NULL值列表所占用的字节数」 <= 65535。
行溢出后,如何存储数据
如果一个数据页存不了一条记录,InnoDB 存储引擎会自动将溢出的数据存放到「溢出页」中。
在记录的真实数据处只会保存该列的一部分数据,而把剩余的数据放在「溢出页」中,然后「真实数据」处用 20 字节存储指向溢出页的地址,从而可以找到剩余数据所在的页。
转载:MySQL 一行记录是怎么存储的? | 小林coding (xiaolincoding.com)
相关文章:
MySQL:一行记录如何
1、表空间文件结构 表空间由段「segment」、区「extent」、页「page」、行「row」组成,InnoDB存储引擎的逻辑存储结构大致如下图: 行 数据库表中的记录都是按「行」进行存放的,每行记录根据不同的行格式,有不同的存储结构。 页…...
‘grafana.ini‘ is read only ‘defaults.ini‘ is read only
docker安装grafana 关闭匿名登录情况下的免密登录遇到问题 grafana.ini is read only defaults.ini is read only 参考回答(Grafana.ini giving me the creeps - #2 by bartweemaels - Configuration - Grafana Labs Community Forums) 正确启动脚本 …...
博途PLC 面向对象系列之“输送带控制功能块“(SCL代码)
这篇是面向对象系列之"输送带功能块"的封装,面向对象是系列文章,相关链接如下: 1、面向对象系列之找"对象" https://rxxw-control.blog.csdn.net/article/details/136150027https://rxxw-control.blog.csdn.net/article/details/1361500272、面向对象…...
2024-02学习笔记
1.当我们向Set集合中添加一个已经存在的元素时 当我们向Set集合中添加一个已经存在的元素时,Set集合会如何处理呢?实际上,Set集合不会将重复的元素添加到集合中。当我们向Set集合中添加一个元素时,Set集合会首先判断该元素是否已…...
最新消息:英特尔宣布成立全新独立运营的FPGA公司——Altera
今天,英特尔宣布成立全新独立运营的FPGA公司——Altera(2015年6月Intel以 167 亿美元的价格,收购FPGA厂商Altera)。首席执行官Sandra Rivera和首席运营官Shannon Poulin分享展示其在超过550亿美元的市场中保持领先性的战略规划&am…...
RC正弦波振荡电路
RC正弦波振荡电路 RC正弦波振荡电路又称文氏电桥振荡电路,可以设计频率为f1/2πRC的正弦波发生器。 RC正弦波振荡电路设计:50Hz,振幅为3.47V 电路分析: 1.起振条件取决于R1, R4,R2与1N4148并联电阻(下面简称Rf&#…...
【Git学习笔记】提交PR
step1 克隆一个仓库 git clone .....step2 创建一个分支 (Creating a branch) # 创建并切换到本地新分支,分支的命名尽量简洁,并与解决的问题相关 git checkout -b delete-unused-linkstep3 做出修改 (Make changes) step4 提交修改 # 保存本地修…...
线程池的相关参数
在Java中线程池是一种池化技术,用于管理和复用线程,提高线程的利用率和性能。下面是一些常见的线程池的参数及其解释: 一:线程池的七大参数 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTim…...
图书推荐||Word文稿之美
让你的文档从平凡到出众! 本书内容 《Word文稿之美》是一本全面介绍Word排版技巧和应用的实用指南。从初步认识数字排版到高效利用模板、图文配置和表格与图表的排版技巧,再到快速修正错误和保护文件,全面系统地讲解数字排版的技术和能力&…...
前端导出word文件的多种方式、前端导出excel文件
文章目录 纯前借助word模板端导出word文件 (推荐)使用模板导出 前端通过模板字符串导出word文件前端导出 excel文件,node-xlsx导出文件,行列合并 纯前借助word模板端导出word文件 (推荐) 先看效果…...
Linux和Windows操作系统在腾讯云幻兽帕鲁服务器上的内存占用情况如何?
Linux和Windows操作系统在腾讯云幻兽帕鲁服务器上的内存占用情况如何? 对于Linux操作系统,有用户分享了个人最佳实践来解决内存问题,包括使用Linux脚本让服务器每天重启一次,以及建议在不需要时尽量减少虚拟内存的使用。此外&…...
腾讯云4核8G的云服务器性能水平?使用场景说明
腾讯云4核8G服务器适合做什么?搭建网站博客、企业官网、小程序、小游戏后端服务器、电商应用、云盘和图床等均可以,腾讯云4核8G服务器可以选择轻量应用服务器4核8G12M或云服务器CVM,轻量服务器和标准型CVM服务器性能是差不多的,轻…...
1_SQL
文章目录 前端复习SQL数据库的分类关系型数据库非关系型数据库(NoSQL) 数据库的构成软件架构MySQL内部数据组织方式 SQL语言登录数据库数据库操作查看库创建库删除库修改库 数据库中表的操作选择数据库创建表删除表查看表修改表 数据库中数据的操作添加数…...
PoC免写攻略
在网络安全领域,PoC(Proof of Concept)起着重要的作用,并且在安全研究、漏洞发现和漏洞利用等方面具有重要的地位。攻击方视角下,常常需要围绕 PoC 做的大量的工作。常常需要从手动测试开始编写 PoC,再到实…...
c1-周考2
c1-第二周 9月-技能1.一个岛上有两种神奇动物,其中神奇鸟类2个头3只脚,神奇兽类3个头8只脚。游客在浓雾中看到一群动物,共看到35个头和110只脚,求可能的鸟类和兽类的只数2.构建一个长度为5的数组,并且实现下列要求3.构…...
express+mysql+vue,从零搭建一个商城管理系统7--文件上传,大文件分片上传
提示:学习express,搭建管理系统 文章目录 前言一、安装multer,fs-extra二、新建config/upload.js三、新建routes/upload.js四、修改routes下的index.js五、修改index.js六、新建上传文件test.html七、开启jwt验证token,通过login接…...
markdown的使用(Typora)
文章目录 markdown的使用(Typora)一.标题二.段落格式2.1 换行2.2 分割线2.3 字体2.4 上下标2.5 脚注2.6 改变字体颜色 三.列表3.1 无序列表3.2 有序列表3.3 列表嵌套3.4 任务列表 四.区块五.代码显示5.1 行内代码5.2 代码块 六.链接七.图片八.表格九.表情符号大纲十、流程图10.…...
【python】json转成成yaml中文编码异常显示成:\u5317\u4EAC\u8DEF123\u53F7
姊妹篇:【python】json转成成yaml json数据 {"name": "张三","age": 30,"isMarried": false,"children": [{"name": "小王","age": 5},{"name": "小李",&qu…...
Python 实现Excel自动化办公(中)
在上一篇文章的基础上进行一些特殊的处理,这里的特殊处理主要是涉及到了日期格式数据的处理(上一篇文章大家估计也看到了日期数据的处理是不对的)以及常用的聚合数据统计处理,可以有效的实现你的常用统计要求。代码如下࿱…...
MCTS代码
这段代码的背景是玩一个游戏。游戏的参数有NUM_TURNS,在第i回合,你可以从一个整数[-2,2,3,-3]*(NUM_TURNS1-i)中进行选择。例如,在一个4回合的游戏中,在第1回合,你可以从[-8,8,12&am…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架
1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...
