(1)前序
    数据页之间组成了双向链表,数据页内部的数据行组成了单向链表,每个数据页内根据主键做了一个页目录,一般来说,在没有索引的情况下,所有的数据查询其实在物理层面都是全表扫描,依次扫描每个数据页内部的每个数据行。这种情况速度慢到惊人,所以一般肯定不能让查询走全表扫描,因此正常数据库中的查询,必须要运用到索引来加速查询的执行。

    (2)页分裂
    正常情况下,往表里插入一些数据,都会进入到一个数据页里去,在数据页内部会组成一个单向链表,里面是一行行的数据,刚开始第一行是个起始行,它的行类型是2,就是最小的行,然后有个指针指向了下一行数据,每个行数据都有自己每个字段的值,然后每一行通过一个指针不停的指向下一行数据,普通的数据行类型都是0,最后一行是类型3,代表最大的一行。不停的往表里面插入数据,数据越来越多数据页满了会在申请一个数据页往里添加数据。
    78.jpg
    此时会遇到一个问题,索引运作的核心基础就是要求后一个数据页的主键值都大于前面一个数据页的主键值,如果你的主键值是自增的,这是可以保证的,因为新插入后一个数据页的主键值一定大于前一个数据页的主键值。 但是有时候自定义主键并不是自增长的,所以可能出现后一个数据页的主键值里,有的主键值小于前一个数据页的主键值的。比如在第一个数据页里有一条数据的主键是10,第二个数据页里有一个主键值是8,那这样肯定是有问题的。
    79.jpg80.jpg
    此时就会出现一个过程,页分裂,如果主键值是自定义的,那么在新增一个数据页时,实际上会把前一个数据页里主键值较大的,移到新的数据页里来,然后把新插入的主键值较小的数据移到上一个数据页里去,保证数据页里的主键值一定比上一个数据页里的主键值大。
    比如:第一个数据页有 1,5,6三条数据,第二个数页 2,3,4三条数据,明显第二个数据页里的数据的主键值比第一个数据页里的5和6两个主键值都小,所以是不行的,此时就会出现页分裂行为,把新数据页里的两条数据移到上一个数据页里,上一个数据页里移到两条到新数据页里去,变成 第一个数据页1,2,3 第二个数据页 4,5,6。
    81.jpg
    (3)总结
    页分裂过程的核心目标:保证下一个数据页里的主键都比上一个数据页里的主键值大。
    有新的数据页产生,或者新的数据页产生并且发生挪动都是页分裂

    问题
    那如果连续的三个数据页都已经满了,这个时候我要往第二个数据页里面写一条数据(符合下一个数据页的主键都比当前数据页的主键值都大的情况?),这个时候应该不是简单的两个数据页之间的互相挪动吧?
    解答
    可能多个数据页会发生挪动,所以一般建议主键用自增,否则页分裂效率很低。