(1)简述
    数据页在磁盘文件中的物理存储结构,大家应该都知道数据页之间是组成双向链表的,然后数据页内部的数据行是组成单向链表的,而且数据行是根据主键从小到大排序的。然后每个数据页里会有一个页目录,里面根据数据行的主键存放,同时数据行是被分散存储到不同的槽位里,所以实际每个数据页的目录里,就是这个页里 每个主键跟所在槽位的映射关系 。
    注意::每个槽位里都有一组数据行的全部字段信息。
    76.jpg

    (2)槽位与数据行,根据槽位与主键映射关系二分查找数据
    假设要根据主键查找一条数据,而且此时数据库里那个表没几条数据,这个表就一个数据页,那么就会先到数据页的页目录里根据主键进行二分查找,然后根据二分查找在目录里迅速定位到主键对应的数据是在哪个槽位里,然后到那个槽位遍历每一行数据,就能快速找到那个主键对应的数据。每个槽位里都有一组数据行,在里面遍历查找就可以。 只有有顺序的数据结构才能够使用二分查找。 主键二分查找定位到槽位后,遍历槽位里的数据行

    (3)根据非主键的其他字段查找数据
    假设要是根据非主键的其他字段查找数据呢?
    此时没有办法使用主键的页目录进行二分查找,只能进入到数据页里,根据单向链表依次遍历查找数据,这样性能就很差了。

    (4)假设有很多数据页呢,如何查找?
    一个表里往往都是大量数据,可能有多达成百上千个数据页,这些数据页就存放在物理磁盘文件里,所以此时是如何查询数据的?
    一个表里所有数据页都是由双向链表组成,直接从第一个数据页开始遍历所有数据页,从第一个数据页开始,把第一个数据页从磁盘上读取到内存buffer pool的缓存页里来,然后就在第一个数据页对应的缓存页里。
    按照上述办法查找,假设根据主键查找,可以在数据页的页目录里二分查找,假设根据其他字段查找,只能根据数据页内部的单向链表来遍历查找。假设第一个数据页没找到所需数据呢?
    那就只能根据数据页的双向链表去找下一个数据页,然后读取到buffer pool的缓存页里,然后按一样的方法在一个缓存页内部查找那条数据。如果还是找不到,就依次类推,循环往复,直到找到为止。 这就造成全表扫描了。

    77.jpg

    知识点
    槽位里存的是数据行主键id的集合,类似于List<数据行>,而所谓的页目录也就是类似于 List>>的数据结构罢了;
    每个数据页都有一个页目录,每个页目录里存放的是 主键与槽位,槽位与主键是一对多的关系。查询时如果没有主键,就需要遍历每个数据页的单向链表的行数据进行查询了,这样效率低。