一、数据页
平时执行CRUD的时候,都会从磁盘加载数据页到Buffer Pool的缓存页,更新缓存页后,由异步线程刷回磁盘的数据页,MySQL进行数据操作的最小单位是数据页。每个数据页默认16kb,数据页由多个部分组成,如图
在数据页还未写入数据时,是没有数据行的,只有空闲空间,写入就会占用空闲空间,直到空闲空间耗尽,数据页满了自然会开辟新的数据页来存储数据。数据页之间通过双向链表来链接。在文件头中存放了如当前页号、页类型、所属表空间、上一页号、下一页号等等。
数据页内部会存储一行一行的数据,每一行数据都会按照主键大小进行排序存储,同时每一行数据都有指针指向下一行数据,组成单向链表
为了提升查找效率,利用二分查找的特性,在数据页目录部分存储主键ID和行位置
这样就可以通过数据页目录走二分查找,快速定位到数据页的数据行。但如果数据页成千上万个也会出现效率问题,此时就出现了索引。
二、页分裂
索引的核心基础要求后一个数据页的主键值都大于前面一个数据页的主键值,如果你的主键是自增的,可以保证这一点,但有时候主键并不是自增的,就会出现后一个数据页的主键值小于前一个数据页主键值的情况,为了保证索引的核心基础,就有一个交换行数据的过程,这个过程叫做页分裂。
三、主键索引
以主键为例,创建一个主键索引,这个主键索引就是主键目录,它会维护数据页的最小主键值与对应的页号。有了主键目录后
1.二分查找主键目录,找到对应的数据页
2.进入数据页,二分查找数据页目录,知道对应的行数据
如果有大量数据页,意味着主键目录要存储大量的数据页号和最小主键值,仅仅靠二分查找也会吃力,所以InnoDB实际上是把主键目录数据存储在多个数据页中,我们把这个数据页称为索引页
三、索引页
索引页,就是存储索引信息的数据页,在数据页的文件头部,有页类型来进行区分。索引页存储最小主键值与索引页号。
把大量的索引信息分散在多个索引页中,再将多个索引页组成B+树结构,方便二分查找,结构如下图(非真正的B+只是便于理解)
1.根据主键id二分查找索引页
2.找到对应的索引页,再二分查找数据页
3.进入数据页,二分查找数据页目录,找到对应的行数据