InnoDB页结构示意图
InnoDB将数据划分为若干页,以页作为磁盘和内存之间交互的基本单位,InnoDB中页的大小一般为16kb(可以修改)。也就是说一般情况下,一次最少从磁盘中读取16kb的内容到内存中。一次最少把16kb的内容刷新到磁盘中。页内的物理地址是连续的。
InnoDB行格式类型(Compact格式)
Compact行格式示意图:
创建表
CREATE TABLE record_format_demo(
c1 VARCHAR(10) DEFAULT NULL,
c2 VARCHAR(10) NOT NULL,
c3 CHAR(10) DEFAULT NULL,
c4 VARCHAR(10) DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=ASCII ROW_FORMAT=COMPACT
插入记录:
INSERT INTO record_format_demo(c1,c2,c3,c4)VALUES('aaaa','bbb','cc','d'),('eeee','fff',NULL,NULL)
1、Compact格式中的变长字段长度列表:
mysql支持变长的数据类型,varchar(m)、varbinary(m)、text、blob类型等,这些变长的数据类型占用的存储空间分为两部分:
1.真正的数据内容
2.申明占用的字节数
如果不保存真实数据占用字节数,那么mysql服务器无法判断出真实数据有多长,导致无法准确取数据 。在compact行格式中,把所有边长类型的长度存放在行记录的开头部位形成一个列表,按照列的逆序存放。
我们在创建表时列1、列2、列4为变长字段,而c3列为定长字段。所以,InnoDB将会按照如下方式存储:
需要注意的是,变长字段长度列表中只存储非NULL值的占用的长度,值为NULL的长度是不存储的。也就是说对于第二条记录中,c4(即使是边长字段)列的的值为NULL,所以第二列的变长字段长度列表只会存储c1和c2列的长度。
(c3列的长度为什么不存储?因为c3列是定长字段)
2、NULL值列表
2.1 表中的某列可能存储NULL值,如果把这些NULL值都做真实存储的话就会很占用空间,所以compact行格式把这些NULL值的列统一管理起来,存储在NULL值列表中。
1)首先统计那些列可以为NULL值
表中有允许存储NULL的列时,则将每个允许存储NULL的列对应一个二进制位,二进制位按照列的顺序逆序排列。表record_format_demo有3个允许位NULL的列,所以这3个列和二进制对应的关系:
2)根据列的实际值,用0或者1填充NULL值列表
二进制位的值为1时,代表该列值位null
二进制位的值位时,代表该列的值不为null
NULL值列表必须用整数个字节数表示,如果使用的二进制的个数不是整数个字节,则在字节的高位补0
NULL值只占用标志位空间,不占用真实的数据空间
3)如果表中没有允许存储NULL的列时,则不分配NULL值列表
2.2 record_format_demo的两条记录的NULL值列表就如下:
2.3 record_format_demo两条记录的在填充了NULL列表后的示意图如下:
其他
后面学习InnoDB行存储格式(compact)中额外信息中的记录头信息