本篇文章是从小林coding的一些简单汇总,
SHOW VARIABLES LIKE 'datadir';
查看数据的文件放在那里
每创建一次数据库就会有一个新的文件夹创建,以数据库名字命名。
结果:
opt 当前数据库的默认字符集和字符校验规则
ibd 表数据
frm 表结构
在数据库中的文件夹中可以看到,每个表的.ibd .frm文件,分别是表的数据文件和表结构文件。 mysql8.0中将frm合并到了ibd文件中,也没有了opt
表空间结构
行 row
数据库中记录按行来存储,每行记录根据不同的行格式,有不同的存储结构
页 Page。
16KB为1页,InoDB的读取都是按数据页作为单位的。所以读取一行记录的时候,会把整页都读取进去。意味着数据库每次读写都是以 16KB 为单位的,一次最少从磁盘中读取 16K 的内容到内存中,一次最少把内存中的 16K 内容刷新到磁盘中。
页有很多种,索引页,数据页,undo日志页等等。
区 Extent
以区为单位分配物理空间,这样子链表中双向链表链接的页物理上也就挨着了。
段 Segment
表空间是由各个段(segment)组成的,段是由多个区(extent)组成的。段一般分为数据段、索引段和回滚段等。
数据页的结构详解请添加图片描述
一个 InnoDB 数据页的存储空间大致被划分成了 7 个部分
我们的行数据都是存储在 User’Records中
在一开始生成页的时候,其实并没有 User Records 这个部分,每当我们插入一条记录,都会从 Free Space 部分,也就是尚未使用的存储空间中申请一个记录大小的空间划分到 User Records 部分。Free Space用完这个数据页就用完了。
索引的数据结构
索引的数据结构类似于页,但是没有那7部分,索引记录的是该索引页的最小主键id和页号
索引页,非叶子节点存放的是索引和页号;叶子节点存放的是索引和数据。
- id :对应页中记录的最小记录 id 值;
- 页号:地址是指向对应页的指针;
估算最多存放多少行
- 非叶子节点内指向其他页的数量为 x
- 叶子节点内能容纳的数据行数为 y
- B+ 数的层数为 z
最多容纳: X^(z-1) * y
计算过程:
- 一个数据页(索引页)16K,期中userRecords最多容纳15K。我们计算索引页,按照主键8B,页号固定为4B,一条索引占据12B,一个索引页最多存储1280个索引。
- 叶子节点按照按一条行数据 1k 来算,那一页就能存下 15 条,Y = 15*1024/1000 ≈15。
按照公式,3层B+树刚好24576000。 如果一行数据大于1K那么支持的数据量只会更小。
总结
- 数据都是放在数据页中的,但是数据页之间不一定连续, 所以才会有区,尽量是数据页之间连续。
- 数据页16K不是完全放置数据的
- 索引中,叶子节点和非叶子节点构造一样,只是存储的内容不一样,一个是(页内最小主键id和页号),另外一个是行数据
- 索引的结构不影响单表最大行数据,层数才是最影响的。