一点PHP博客分享数据结构多路搜索树算法中的其中两种,B-tree和B+tree类型的最大区别就在于后者是基于前者的基础上做的一个优化,B-tree树会在每个节点或者非节点处存储数据和指针关键字等信息,而B+tree树只会在同层节点处存放信息并且它们之间是互链的。
我们到系统中获取数据最少需要两个步骤,先从磁盘中读出在放到内存中,每次读出的数据为一个磁盘块(单位),这种操作称为一次IO。
B-tree树:
每个节点占用一个磁盘块的空间,一个节点上有两个升序排序的关键字和三个指向子树根节点的指针,指针存储的是子节点所在磁盘块的地址。
两个关键词划分成的三个范围域对应三个指针指向的子树的数据的范围域。
以根节点为例,关键字为17和35,P1指针指向的子树的数据范围为小于17,P2指针指向的子树的数据范围为17~35,P3指针指向的子树的数据范围为大于35。
模拟查找关键字29的过程:
根据根节点找到磁盘块1,读入内存。【磁盘I/O操作第1次】
比较关键字29在区间(17,35),找到磁盘块1的指针P2。
根据P2指针找到磁盘块3,读入内存。【磁盘I/O操作第2次】
比较关键字29在区间(26,30),找到磁盘块3的指针P2。
根据P2指针找到磁盘块8,读入内存。【磁盘I/O操作第3次】
在磁盘块8中的关键字列表中找到关键字29。
分析上面过程,发现需要3次磁盘I/O操作,和3次内存查找操作。由于内存中的关键字是一个有序表结构,可以利用二分法查找提高效率。而3次磁盘I/O操作是影响整个B-Tree查找效率的决定因素。B-Tree相对于AVLTree缩减了节点个数,使每次磁盘I/O取到内存的数据都发挥了作用,从而提高了查询效率。
B+tree树
B+tree树在B-tree树中做了一个优化,因为每个磁盘块的大小都是有限的,如果在每个非节点处都存放数据,那么每次获取到的磁盘块上的索引指针信息以及关键字信息将会很少,这样会增加我们的IO次数以及树结构的深度。
B+tree只在每个非节点处只存放指针以及关键字信息,这样可以最大化的增加每个磁盘块存放的索引信息,可以更加有效的获取出相对应的地址信息从而也降低了树结构的深度,而且叶子顶部节点允许互链减少了重新IO的次数。
我们常用的MYSQL引擎innodb就是按这种方式存放数据,存储引擎在设计时是将根节点常驻内存的,也就是说查找某一键值的行记录时最多只需要1~3次磁盘I/O操作。
InnoDB存储引擎中有页(Page)的概念,页是其磁盘管理的最小单位。InnoDB存储引擎中默认每个页的大小为16KB。在查询数据时如果一个页中的每条数据都能有助于定位数据记录的位置,这将会减少磁盘I/O次数,提高查询效率。
一点PHP每天一点技术分享。