《MySQL 是怎样运行的》学习笔记
初识MySQL
服务器处理客户端请求

服务器将负责运营线程池系统。该系统会向每个客户端连接提供一个专门的线程。允许动态调整线程数量。
2. 解析优化
- 缓存机制。自MySQL 5.7.20版本起不再推荐采用该功能,并于MySQL 8.0版本中完全移除 *
3. 存储引擎
最常用的就是InnoDB和MyISAM
字符集
一个字符在utf8编码下通常占用1到4个字节, mysql中采用的是阉割后的utf8mb3编码方案,每个字符占用1至3个字节
字符集的选择会影响char,varchar类型存储空间大小的具体表现。
具体来说,在大多数数据库系统中,默认情况下,
char 类型字段占据的空间由其存储的字符数量决定,
而非固定的字节数目(即每个 char 占据一个或多个字节)。
InnoDB记录存储结构
页
页是磁盘和内存之间交互的基本单位 ,页的大小一般为 16 KB
每次至少从硬盘介质加载16KB的数据块至内存缓冲区,并定期将内存缓冲区中的数据更新至硬盘介质
行格式
- Compact
默认格式
为什么变长字段和null要逆序?

变长字段长度列表
1. VARCHAR、TEXT等称为变长字段
将所有变长字段的真实数据占用的字节长度依次放置于记录的起始位置,并依照字段排列顺序反向存放各变长字段数据占用的字节数的数量
如果该可变字段的最大容量超出255 字节且真实存储的 字节数超出127 字节,则需 使用 2 个 字节;否则仅 使用 1 个 字节
在读数据中遇到变长字段长度列表时先查看表结构信息。当某个变长字段的最大存储字节数超过255时,默认将第一个二进制位用作标志位:即若第一个二进制位为0,则表示该字节完整地代表一个字段长度;若为1,则表示仅占半个字段长度。
当某些数据块占用的空间超过16KB时,在无法将该记录完整地保留在一个页面的情况下
3. 变长字段长度列表中只存储值为 非NULL 的列 内容占用的长度
4. 表中所有的列都不是变长的数据类型的话,就没有变长字段长度列表

NULL值列表
将每个允许存储NULL的数据字段与一个独立的一位二进制数相对应,并以从右到左的方式依次安排这些二进制位;每一位的具体取值规则如下:当某个二进制位设为1时,则表示对应的字段值不存在;反之,则表示字段有具体数据
2. 规定为NULL值列表需采用整数个字节的位表示方式,在二进制位数量非整数个字节时,则需在相应字节的高位进行填充
3.值为NULL的列 ,在记录的真实数据处就不再冗余存储 ,从而节省存储空间

记录头信息
**

**
固定的5个字节组成
记录的真实数据
隐式字段:这些字段会被增添到每一条记录中,并非所有情况下都会包含它们。其中 row_id 通常是可选的字段,在无需自定义主键和唯一约束时会包含这一项。

CHAR(M)列的存储格式
当一列采用的是固定长度型定长字符集时,在生成变长字段长度列表的过程中,该列占用的字节数不会被计算进去。相反地,在选择动态宽度型变长字符集时,在生成变长字段长度列表的过程中,则会将该列占用的字节数纳入计算范围。
2. char是固定长度的,当内容未填满时,会在其右边填充空格
3. char字段具有固定长度特性,并未受到存储片段化的影响;然而varchar字段在增删改查的过程中不可避免地会存在数据存储片段化现象,在进行频繁增删操作时更容易产生这种情况。因此必须定期清除这些残留片段以保持系统性能
4. 读取数据时,char用trim()去掉多余的空格 ,varchar直接读出数据
- Redundant
MySQL5.0之前用的一种行格式,兼容旧数据

字段长度偏移列表
将该条记录中全部字段的长度信息按照逆序存储到字段长度偏移列表
2. 偏移 意味着两个相邻数值的差值来计算各个列值的长度
基于每个记录的实际数据长度确定该字段所需的偏移量大小,默认设置为1个或2个字节
记录头信息
其值等于1时表示使用单字节存储;而其值等于0时表示采用双字节存储
相对compact,还多了n_field属性
NULL的处理
Redundant行格式并没有NULL值列表
在字段长度偏移列表中各字段对应的偏移量的第一个比特位具体来说作为判断是否为NULL的关键依据被明确标记出来这一标记点被称为NULL比特位这一概念在数据库处理中具有重要意义当解析某条记录中的某个字段时首先需要查看该字段对应的偏移量中的NULL比特位值如果是1则表明该字段的值属于null状态反之则表示存在有效数据
这也说明了为何在真实数据超过127的情况下,默认使用两个字节来表示某一列的偏移量变化原因在于,在这种情况下第一个比特位已经被预先设置了特殊含义
CHAR(M)列的存储格式
无论该列所采用的字符集为何,所占真实数据空间即为其字符所需的最小字节数与M的乘积
- Dynamic、Compressed
与COMPACT行格式相仿的是这两种行格式,在处理溢出数据时,在真实记录位置仅存儲该字符串的前768个字符;而另一种则是将所有这些字节数量分散存儲于不同的页面上,并仅存儲对应其他页面上的位置信息。
另外,Compressed行格式会采用压缩算法对页面进行压缩
行溢出数据及VARCHAR(M)最多能存储的数据
MySQL单条记录的最大存储容量受到限制,在非BLOB或TEXT类型的列中(不包括隐藏列和记录头信息),其累计使用的字节数目不得超过65535个字节。
以下是按照要求对原文进行的同义改写


在什么情况下会发生行溢出?MySQL要求每个页至少存储两行记录。因此,我们可以推导出最大单页字节数n的计算公式为:132 + 2×(27 + n) < 16384(其中括号内的内容解释如下:132表示每个页的header空间;27表示每行记录的header空间;而16384则代表一页的最大容量为16KB)。
