(1)回顾:
刚开始建表,就是一个数据页,这个数据页属于聚簇索引的一部分,而且还是空的,此时如果插入数据,就直接在这个数据页里插入就可以了,也没必要弄索引页,然后初始的数据页其实就是
一个根页,每个数据页内部默认有一个基于主键的页目录,所以此时根据主键搜索都是可以的,直接在唯一一个数据页里根据页目录找就行了。
然后表中数据越来越多,此时数据页满了,你就会建一个新的数据页,然后把根页里面的数据都拷贝过去,同时再建一个新的数据页,根据主键值的大小进行挪动,让两个新的数据页根据主键值
排序,第二个数据页的主键值都大于第一个数据页的主键值。
那此时根页呢?此时根页升级为索引页,这个根页里存放的是两个数据页的页号和他们里面最小的主键值,所以根页成为了索引页,引用两个数据页。接着不停的在表里添加数据,然后数据页
不停的页分裂,分裂出越来越多的数据页,此时唯一的索引页,也就是根页里存放的数据页索引条目越来越多,连索引页都放不下,此时就让一个索引页分裂成两个索引页,然后根页继续往上一层级
引用了两个索引页。
接着依次类推,数据页越来越多,根页指向的索引页也会不停分裂出更多索引页,当下层的索引页数量太多的时候,会导致根页指向的索引页太多,根页再次往上提上去一个层级。这其实就是增删
改的时候,整个聚簇索引维护的一个过程,二级索引也是类似的一个原理。
(2)二级索引:
比如name字段有一个索引,刚开始插入数据,一方面聚簇索引的唯一的数据页插入,一方面在name字段的索引B+树唯一的数据页里插入。
后续数据越来越多,name字段的索引B+树唯一的数据页分裂,整个分裂的过程跟上面说的一样,所以插入数据的时候,本身就会自动维护各个索引的B+树,另外补充一点,name字段的索引B+树
的索引页中,其实除了存放页号和最小name字段值以外,每个索引页里还存放最小name字段值对应的主键值。
这是因为有时候会出现多个索引页指向的下层页号的最小name字段值是一样的,此时必须根据主键判断。比如插入一个新的name字段值,需要根据name字段B+树索引的根页面开始,去逐层寻找
和定位自己这个新的name字段值应该插入叶子节点的那个数据页里去。此时万一遇到一层里不同的索引页指向不同的下层页号,但是name字段值一样,此时就得根据主键值比较一样。新的name字段值肯定
是插入到主键值较大的那个数据页里去。
知识点:如果只是查询name和id则不需要回表
知识点:假设有六个数据页,插入的name为最小值时,这时出现页分裂,岂不是出现五个分页都要移动,?所以索引不能太多,会影响增删改性能。