1、数据页
假设有一张数据库表:
emp_id(主键) | emp_age(非主键) | emp_name(非主键) |
---|---|---|
1 | 21 | tom |
2 | 22 | jerry |
3 | 23 | bob |
4 | 24 | harry |
5 | 25 | lily |
…… | …… | …… |
对于 InnoDB 存储引擎来说,最小的存储单位就是:页。那么存放原始数据的页就称为数据页。
一个页默认的大小是:16KB。如果我们假设一条记录所占空间的字节数是 1KB,那么这个数据页大致能够存储 16 条记录。那么如果这个数据库表总共有 100 万条记录,那么肯定是需要很多数据页来存放这些数据。
2、数据页内部
①主键排序
数据页内部对主键进行了排序,所以当我们在一个数据页内部根据主键查找记录时,会根据二分法进行查找。找到主键就能够很快找到这条记录。
②数据页编号
为了在众多数据页中,定位每一个数据页,数据页需要有编号。所以这个编号也相当于是这个页的地址。
3、数据页如何便于查找
①排序
根据主键值对所有数据页进行排序。
②双向链表
把所有数据页组成环状双向链表。
好处是:假设搜索主键值大于 30 的记录,那么找到主键值为 30 的记录之后,后面所有的记录就都可以快速找到和返回了。
③扫描全表
就目前的数据存储方式来说,如果要找到某一个主键值所在的数据页,需要一页一页的查找,这无疑是非常缓慢的。所以肯定需要做进一步优化。
4、数据页设定目录
为了能够快速到数据页中找到记录,我们专门给数据页设定目录。
①第一层目录
[1]设置
选取每一个数据页中最小的主键值 最小主键值 + 当前数据页的页码 = 目录页中的一条记录 主键值 + 页码 组成的记录放在一起组成了目录页 不管是数据页还是目录页都是页,默认大小都是 16KB 估算目录页能够存储多少条记录?
主键值占 8 字节
页码占 8 字节
16 KB / 16 B = 1024 条
[2]搜索
现在我们在 4 号目录页中有如下三个区间:
- 区间 1:[1,11)
- 区间 2:[11,21)
- 区间 3:[21, ...)
情景一:搜索主键值为 11 的记录
select emp_id,emp_name,emp_age from t_emp where emp_id=11
- 11 落在了区间 2:[11,21)
- 根据目录页中的 11->2 这条记录,得知想要的数据在页码为 2 的数据页
- 进入页码为 2 的数据页
- 在数据页内部根据主键做二分法查找
情景二:搜索主键值为 15 的记录
select emp_id,emp_name,emp_age from t_emp where emp_id=15
- 15 落在了区间 2:[11,21)
- 根据目录页中的 11->2 这条记录,得知想要的数据在页码为 2 的数据页
- 进入页码为 2 的数据页
- 在数据页内部根据主键做二分法查找
②第二层目录
[1]设置
为了更进一步方便查找,命中我们要找的目录页,我们可以进一步给目录再设置目录。
[2]搜索
用户搜索的主键值是:60。现在 13 号目录页中包含的区间:
- [1,51)
- [51,150)
- [150,...)
所以 60 会落在 [51,150) 区间,所以继续查