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

相关推荐
DIY机器人工房1 小时前
嵌入式面试题:看你学习了自动控制原理这门课,讲一下欠驱动系统?
stm32·单片机·学习·嵌入式·自动控制原理
郑州光合科技余经理2 小时前
开发指南:海外版外卖跑腿系统源码解析与定制
java·开发语言·mysql·spring cloud·uni-app·php·深度优先
laplace01232 小时前
happy-llm笔记
笔记
IUGEI3 小时前
【后端开发笔记】JVM底层原理-垃圾回收篇
java·jvm·笔记·后端
q***47183 小时前
MySQL 篇 - Java 连接 MySQL 数据库并实现数据交互
java·数据库·mysql
杨云龙UP3 小时前
【MySQL逻辑备份】基于mysqldump的MySQL 8.0全量逻辑备份脚本
linux·运维·数据库·sql·mysql·mssql
百***35943 小时前
Linux(CentOS)安装 MySQL
linux·mysql·centos
摇滚侠3 小时前
Vue 项目实战《尚医通》,完成订单详情静态的搭建,笔记47
vue.js·笔记
('-')3 小时前
《从根上理解MySQL是怎样运行的》第五章学习笔记
笔记·学习·mysql