《从根上理解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,当记录中的数据太多的时候,就将多出的数据存放到其他页中,这种现象就是行溢出现象

相关推荐
李帅朋18 小时前
微分基本定义笔记
人工智能·笔记·深度学习·神经网络
传奇开心果编程19 小时前
【Rust入门知识点学与练】第21课:Trait 进阶 Advanced Traits
开发语言·学习·rust
水巷石子20 小时前
备考系统架构设计师第一天
学习·架构·软考·设计·考试
是隼人20 小时前
buuctf-pwn inndy_echo(32位fmt)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
xian_wwq21 小时前
【学习笔记】深度认知系列-第16讲-提示词工程
人工智能·笔记·学习
洛阳纸贵21 小时前
MATLAB-matlab基础知识
学习·算法·matlab
Vcaker21 小时前
Linux学习25-harbor私有仓库部署
linux·运维·学习
留白_1 天前
【tableau入门学习】5、筛选器、参考线和集
学习·tableau
youm20031 天前
认识Redis
redis·笔记·学习
亮工硬件1 天前
1-11 STM32内部FLASH(数据掉电保存)
笔记·stm32·单片机·嵌入式硬件·学习