Mysql数据究竟是如何存储的
Mysql行列式
开篇
笔者这几日在学习mysql是这么运行的这本书,感觉书中的内容受益匪浅,想整理成自己的话分享给大家,平时大家工作和生活中可能没有时间去专心投入读取一本书,而mysql是这么运行的这本书需要投入大量的时间的学习,靠碎片化的时间是无法读懂书中的内容的,这本书每一章节的耦合度很高,有兴趣的同学可以去支持一下小孩子老师。下面我会用通俗易懂的白话方式讲述这本书的内容。
Mysql是这么存储数据的?
准备工作
Mysql服务器存储数据其实是交给存储引擎的,而MySQL的存储引擎的又有很多种,例如InnoDB、MyISAM、Memory等等很多种,下面我将以InnoDB存储引擎介绍一下InnoDB存储引擎是如何存储数据的。
InnoDB如何存储数据的
InnoDB是根据数据页(16kb)存储数据的,InnoDB存储引擎会在以数据页的当时将数据在内存种处理,然后在刷入磁盘。那数据页究竟长什么样子。欧克我们下面看一下数据页哪些组成的
名称 | 中文名 | 占用空间大小 | 描述 |
---|---|---|---|
FileHeader | 文件头部 | 38字节 | 页的一些通用信息 |
PageHeader | 页面头部 | 56字节 | 数据页占有的一些信息 |
Infimun+supremun | 最小记录和最大记录 | 26字节 | 两个虚拟的行记录 |
UserRecordes | 用户记录 | 不确定 | 实际存储的行记录内容 |
FreeSpace | 空闲空间 | 不确定 | 页中尚未使用的空间 |
PageDirecttory | 页面目录 | 不确定 | 页中的某些记录的相对位置 |
FileTailer | 文件尾部 | 8字节 | 检验页是否完整 |
这里不需要我们都记住,混个眼熟就欧克了,我们存储数据发生的空间在UserRecordes(用户记录),看名字不难发现用户记录,肯定是我们自己插入的数据。
首先我们准备一个表名为ROW_FORMAT
插入三条数据,
create table ROW_FORMAT(
c1 int,
c2 varchar(50) NOT NULL,
c3 varchar(50),
c4 char(50),
primary key(c1)
)CHARSET=ascii ROW_FORMAT=COMPACT;
INSERT INTO
`ROW_FORMAT`(`c1`,`c2`,`c3`,`c4`)
VALUES
(1001,'aaa','ab','aac'),
(1002,'bba','bbb','bbc'),
(1003,'cca','ccb','ccc');
万事俱备只欠东风,现在我们准备万全,什么你不知道ROW_FORMAT
什么意思,这是我们的本章的重点,我们现在已经知道存储操作是InnoDB存储引擎帮我们做的,而InnoDB存储引擎是以数据页存储的,数据页真正存储数据的地方是在UserRecordes中,那么他是如何存储的呢,这就是row_formatd的作用’‘行格式‘’——数据以什么方式存储是行格式说的算的。
行格式有哪几种呢,它们都是这么定义存储的内容的呢,它们之间的区别呢。欧克这些问题我们一个一个的解决。
行格式用哪些?
在InnoDB存储引擎中常见的行格式有四种,分别是 Compact 、 Redundant 、Dynamic 和 Compressed 行格式。
Compact行格式是如何存储内容的?
我们看一张图:
变长列列表、空字符列表、头信息是什么?干什么用的?
好我们思考一个问题,如果InnoDB存储引擎插入多条变长数据它应该如何告诉内存真实内容存放的位置。
这下你理解变长列列表的作用了吧,我们看第一行数据是如何存储在Compact行格式里
INSERT INTO `ROW_FORMAT`(`c1`,`c2`,`c3`,`c4`) VALUES(1001,'aaa','aab','aac')
博主你这画的啥啊什么标注都没有,这都这么来的啊
变长列列表里面存放的是边长列表的长度的逆序列表,注意是逆序。
空字符列表是一字节八位00000000:注意得是因为空列表只存储除主键和NOTNULL修饰的列
头信息如上图所示一共占40位
除此之外我们InnoDB引擎还为我们DB_ROW_ID、DB_TRX_ID、DB_ROLL_PTR这些默认字段
头信息
预留位1和预留位2没有任何使用,我们跳过。
delete_mask是我们InnoDB引擎在删除数据的时候吧这行数据标记为1就表示它需要被垃圾链路回收。
min_rec_mask是数据页索引的非叶子节点页也就是存储目录记录的页区分在那个开始的。(博主你在讲什么啊,讲到索引的时候你就明白了)
heap_no是数据页为了优化查询设计出每个区最后一个行格式存储这一个区域有多少条数据。
record_type就不再赘述了上图都有。
我们Compact行格式是通过next_record 头信息的指定下一个行格式的位置,形成一个单链表。
总结
compact行格式是里面有四部分组成分别是边长列列表、空字符列表、头信息、真实内容。
其他行列式不同
COMPACT行格式
具体组成如图:
Redundant行格式
具体组成如图:
Dynamic和Compressed行格式
这两种行格式类似于 COMPACT行格式 ,只不过在处理行溢出数据时有点儿分歧,它们不会在记录的真实
数据处存储字符串的前768个字节,而是把所有的字节都存储到其他页面中,只在记录的真实数据处存
储其他页面的地址。
另外, Compressed 行格式会采用压缩算法对页面进行压缩。