第四章:从一条记录说起-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,当记录中的数据太多的时候,就将多出的数据存放到其他页中,这种现象就是行溢出现象