
大家都知道 MySQL 的数据都是保存在磁盘的,那具体是保存在哪个文件呢?MySQL 存储的行为是由存储引擎实现的,MySQL 支持多种存储引擎,不同的存储引擎保存的文件自然也不同。InnoDB 是我们常用的存储引擎,也是 MySQL 默认的存储引擎。本文主要以 InnoDB 存储引擎展开讨论。
InnoDB是一个将表中的数据存储到磁盘上的存储引擎。而真正处理数据的过程是发生在内存中的,所以需要把磁盘中的数据加载到内存中,如果是处理写入或修改请求的话,还需要把内存中的内容刷新到磁盘上。而我们知道读写磁盘的速度非常慢,和内存读写差了几个数量级。所以当我们想从表中获取某些记录时,InnoDB存储引擎需要一条一条的把记录从磁盘上读出来么?想要了解这个问题,我们首先需要了解InnoDB的存储结构是怎样的。
InnoDB采取的方式是:将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位innodb_page_size选项指定了MySQL实例的所有InnoDB表空间的页面大小。这个值是在创建实例时设置的,之后保持不变。有效值为64KB,32KB,16KB(默认值 ),8kB和4kB。也就是在一般情况下,一次最少从磁盘中读取16KB的内容到内存中,一次最少把内存中的16KB内容刷新到磁盘中。
我们平时是以记录为单位来向表中插入数据的,这些记录在磁盘上的存放方式也被称为行格式或者记录格式。一行记录可以以不同的格式存在InnoDB中,行格式分别是compact、redundant、dynamic和compressed行格式。可以在创建或修改的语句中指定行格式:
CREATE TABLE 表名 (列的信息) ROW_FORMAT=行格式名称;
ALTER TABLE 表名 ROW_FORMAT=行格式名称;
show table status like '<数据表名>';
mysql5.0之前默认的行格式是redundant,mysql5.0之后的默认行格式为compact , 5.7之后的默认行格式为dynamic
compact格式
记录的额外信息:分别是变长字段长度列表、NULL值列表和记录头信息
mysql中支持一些变长数据类型(比如VARCHAR(M)、TEXT等),它们存储数据占用的存储空间不是固定的,而是会随着存储内容的变化而变化。在Compact行格式中,把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位,从而形成一个变长字段长度列表,各变长字段数据占用的字节数按照列的顺序逆序存放
NULL值列表:Compact格式会把所有可以为NULL的列统一管理起来,存在一个NULL值列表,如果表中没有允许为NULL的列,则NULL值列表也不复存在了。
表中的某些列可能存储NULL值,如果把这些NULL值都放到记录的真实数据中存储会很浪费空间,所以Compact行格式把这些值为NULL的列统一管理起来,存储到NULL值列表中,它的处理过程是这样的: