《从根上理解MySQL是怎样运行的》第四章学习笔记

第四章:从一条记录说起-InnoDB记录结构

准备工作

我们目前只知道我们使用客户端发送请求,然后服务器接收到了请求处理过后将结果反馈给我们,但是这个过程具体是怎样的呢?

请求的处理是交给存储引擎来落地实现的,真实数据在不同的存储引擎中存储的格式一般都是不同的。

这里我们来探索最常用的存储引擎------InnoDB。看看这个存储引擎的具体实现和数据存储结构,这个搞懂了其他的存储引擎也大差不差了


InnoDB页简介

它是一个将表中的数据存储到磁盘上的存储工具,断点以后数据还是在的。真正的数据处理发生在内存中,需要将磁盘中的数据加载到内存上。如果处理修改请求的话,还需要重写内容刷新磁盘。

磁盘读写速度很慢,InnoDB为了解决速度问题将数据划分为若干个页面,然后以页面作为磁盘和内存之间交互的基本单位,InnoDB中页的大小一般为16kb。也就是一般情况下一次最少从磁盘中读取16kb的数据到内存中,一次最少将内存中的16kb刷新到磁盘中

个人理解:这个InnoDB页就是数据交互单位,平常存储都是多少多少kb或者mb,到了存储引擎就是多少多少16kb,也就是多少多少页了。


InnoDB行格式

平时我们使用数据库是一条一条的记录为单位来向表格插入数据的,这些记录在磁盘中存放的方式为行格式或者记录格式。

目前有四种行格式:Compact Redundant Dynamic Compressed行格式


指定行格式的语法

创建或者修改表的语句中指定行格式

CREATE TABLE 表名(列的信息) ROW-FORMAT = 行格式名称

ALTER TABLE 表名 ROW-FORMAT = 行格式

那么不同的行格式存储的方式有什么不同呢?


COMPACT行格式

分成两个部分: 额外信息 + 真实信息


额外信息

为了描述这条记录必须添加的信息

变长字段长度列表

MySQL支持一些变长的数据类型,比如VARCHAR或者TEXT类型。这些类型存储多少字节的数据是不一定的,所以存储的时候要把占用的字节数也存起来

因此变长字段占用的存储空间 = 真正的数据内容 + 占用的字节数

Compact格式中所有列占用的字节数是放在开头的,并且顺序是列的逆序排列


Null值列表

Null直接放到真实数据的存储中会很占地方,所以Compact行格式将值为Null的列统一管理,存储到Null值列表中

处理过程:

(1)首先统计允许存储Null的列,如果表中没有这种类型的列,那么Null值列表也不存在了

(2)将每个允许Null列存储的列都对应一个二进制位,然后按照列的顺序逆序存放

二进制位1代表列值为null,反之亦然

(3)规定Null列值表用整数个字节的位表示,不是整数则高位补0


记录头信息

用于描述记录,它是由固定的5个字节组成的,一共40个二进制位,不同的位表示不同的意思

现在不同在乎一个位表示什么意思,后续碰到来回过头来看即可

---------------------------------------------------------------------------记录的真实数据

除了自己定义的列的数据以外,MySQL还会为每个记录添加隐藏列

Row-id 行Id用于表示一条记录

Transaction-id 事务Id

Roll-pointer 回滚指针

主键策略:

用户优先,否则选取一个Unique键作为主键,还没有的话则为表默认添加一个隐藏列------row-id

Row-id是可选的,其他两个隐藏列是自动添加的


行溢出的数据

VARCHAR(M)最多能存储的数据

已知VARCHAR(M)类型的列最多可以占用65535个字节

M代表该类型最多存储的字符数量

M最大值取决于使用的字符集表示一个字符所需要的最多的字节数,比如gbk字符集表示一个字符最多需要两个字节,于是M就是总的字节数除以2为32766个字节

M就是字符个数,可以说就是存储单位,由总的可用字节总数除以单个字符最大需要的字节数就是M了

不包括隐藏列和记录头信息,一行中所有的列占用的字节长度不可以超过总的字节数,这个就和M无关了,M专注于字符


记录中数据太多产生溢出

InnoDB存储引擎是以页为单位进行存储的,一页是16kb,也就是16384个字节,但是VARCHAR(M)是最多可以存储65532个字节的,所以可能一页都存不下一条记录

但是Compact格式很聪明,如果一列中数据很多的话,那么只存一部分在真实记录数据,另一部分用一个指向其他列的地址,然后剩余的数据存放到其他页中

这种情况叫做行溢出,存储超过768字节的页面叫做溢出页

不只是VARCHAR(M)类型的列,其他的类型的列存储数据非常多的时候也会发生行溢出


行溢出的临界点

什么时候发生行溢出?

反正存储了很大的数据的时候就有可能发生行溢出


总结

(1)页是MySQL中磁盘和内存交互的基本单位,也就是MySQL管理存储空间的基本单位

(2)指定和修改行格式的语法:

CREATE TABLE 表名(列的信息) ROW-FORMAT = 行格式名称

ALTER TABLE 表名 ROW-FORMAT = 行格式名称

(3)InnoDB目前定义了四种行格式

COMPACT、Redundant、Dynamic、Compressed

Compressed行格式可以采用压缩算法对页面进行压缩

(4)一页一般是16kb,当记录中的数据太多的时候,就将多出的数据存放到其他页中,这种现象就是行溢出现象

相关推荐
行业探路者5 小时前
二维码标签是什么?主要有线上生成二维码和文件生成二维码功能吗?
学习·音视频·语音识别·二维码·设备巡检
逑之6 小时前
C语言笔记5:函数
java·c语言·笔记
li星野6 小时前
OpenCV4X学习—核心模块Core
人工智能·opencv·学习
@zulnger6 小时前
python 学习笔记(多线程和多进程)
笔记·python·学习
gravity_w6 小时前
Hugging Face使用指南
人工智能·经验分享·笔记·深度学习·语言模型·nlp
凉、介6 小时前
SylixOS 中的 Unix Socket
服务器·c语言·笔记·学习·嵌入式·sylixos
好奇龙猫6 小时前
【人工智能学习-AI-MIT公开课第 19. 架构:GPS、SOAR、包容架构】
人工智能·学习·架构
中屹指纹浏览器6 小时前
2026指纹浏览器底层技术揭秘:Hook内核与特征校验机制的实现
经验分享·笔记
特立独行的猫a6 小时前
告别碎片化笔记:基于n8n-mcp的AI写作助手实战
人工智能·笔记·ai写作·n8n·n8n-mcp
saoys7 小时前
Opencv 学习笔记:绘制动态随机直线(附实时展示)
笔记·opencv·学习