关于MySQLl数据存储,你了解多少?

作者:微信小助手

发布时间:2023-02-06T10:46:46

前言

大家都知道 MySQL 的数据都是保存在磁盘的,那具体是保存在哪个文件呢?MySQL 存储的行为是由存储引擎实现的,MySQL 支持多种存储引擎,不同的存储引擎保存的文件自然也不同。InnoDB 是我们常用的存储引擎,也是 MySQL 默认的存储引擎。本文主要以 InnoDB 存储引擎展开讨论。

InnoDB简介

InnoDB是一个将表中的数据存储到磁盘上的存储引擎。而真正处理数据的过程是发生在内存中的,所以需要把磁盘中的数据加载到内存中,如果是处理写入或修改请求的话,还需要把内存中的内容刷新到磁盘上。而我们知道读写磁盘的速度非常慢,和内存读写差了几个数量级。所以当我们想从表中获取某些记录时,InnoDB存储引擎需要一条一条的把记录从磁盘上读出来么?想要了解这个问题,我们首先需要了解InnoDB的存储结构是怎样的。
InnoDB采取的方式是:将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位innodb_page_size选项指定了MySQL实例的所有InnoDB表空间的页面大小。这个值是在创建实例时设置的,之后保持不变。有效值为64KB,32KB,16KB(默认值 ),8kB和4kB。也就是在一般情况下,一次最少从磁盘中读取16KB的内容到内存中,一次最少把内存中的16KB内容刷新到磁盘中。

InnoDB行格式

我们平时是以记录为单位来向表中插入数据的,这些记录在磁盘上的存放方式也被称为行格式或者记录格式。一行记录可以以不同的格式存在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值列表和记录头信息
1:变长字段长度列表
mysql中支持一些变长数据类型(比如VARCHAR(M)、TEXT等),它们存储数据占用的存储空间不是固定的,而是会随着存储内容的变化而变化。在Compact行格式中,把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位,从而形成一个变长字段长度列表,各变长字段数据占用的字节数按照列的顺序逆序存放
  • 变长字段长度列表中只存储值为 非NULL 的列内容占用的长度,值为 NULL 的列的长度是不储存的 。

  • 并不是所有记录都有这个 变长字段长度列表 部分,比方说表中所有的列都不是变长的数据类型的话,这一部分就不需要有

2:NULL值列表
NULL值列表:Compact格式会把所有可以为NULL的列统一管理起来,存在一个NULL值列表,如果表中没有允许为NULL的列,则NULL值列表也不复存在了。
为什么要有NULL值列表?
表中的某些列可能存储NULL值,如果把这些NULL值都放到记录的真实数据中存储会很浪费空间,所以Compact行格式把这些值为NULL的列统一管理起来,存储到NULL值列表中,它的处理过程是这样的:
  • 首先统计表中允许存储NULL的列有哪些。

  • 根据列的实际值,用0或者1填充NULL值列表,1代表该列的值为空,0代表该列的值不为空。

  • 如果表中没有允许存储 NULL 的列,则 NULL值列表 也不存在了。

3:记录头信息

名称
大小(单位:bit)
描述
预留位1
1
未使用
预留位2
1
未使用
delete_mask
1
标记改记录是否被删除
min_rec_mask
1
B+树非叶子节点中最小记录都会添加该标记
n_owned
4
当前记录拥有的记录数