B tree 与B+Tree的区别以及原理和应用场景

B-tree的由来?

为什么非得是树呢,而不是直接是数组。Memory locality & the magic of B-Trees!:
说了很清楚,就是因为在申请内存的时候,不知道要申请多大的内存,所以没办法申请很大的一块内存,所以就变成了一个数组被打断为好几段,然后每段用链表连接起来,这其实就是树的基本模型。

B-tree和B+tree的区别是什么?

  • B-tree中非叶子节点可以存值;但是B+tree非叶子节点不可以存值,只能存key,值只存在叶子节点中。
  • B-tree中叶子节点没有用指针连接起来;而B+tree中的叶子节点用指针连接起来,所以B+tree的查询很快,当定位到叶子节点后,只需要遍历叶子节点即可。B+树相比于B树能够更加方便的遍历。
  • B+树简单的说就是变成了一个索引一样的东西。 B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),B+树的性能相当于是给叶子节点做一次二分查找。
  • B+树的查找算法:当B+树进行查找的时候,你首先一定需要记住,就是B+树的非叶子节点中并不储存节点,只存一个键值方便后续的操作,所以非叶子节点就是索引部分,所有的叶子节点是在同一层上,包含了全部的关键值和对应数据所在的地址指针。这样其实,进行 B+树的查找的时候,只需要在叶子节点中进行查找就可以了。

各自的应用场景有什么不同?

mysql的MyISAM和InnoDB两个存储引擎的索引实现方式:

  • MyISAM引擎使用B+ Tree作为索引结构,叶节点存放的是数据记录的地址。
  • MyISAM引擎的辅助索引(二级索引)和主索引在结构上没有区别,只是辅助索引的key可以重复,叶节点上存放的也是数据记录的地址。
  • MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。
  • InnoDB中表数据本身就是按B+ Tree组织的一个索引结构,叶节点存放的就不是数据记录的地址,而是完整的数据记录。所以InnoDB这种存储方式,又称为聚集索引,使得按主键的搜索十分高效,但二级索引搜索需要检索两遍索引:首先二级索引获得主键,然后用主键到主索引中检索到数据记录。
  • 因为主键是InnoDB表记录的”逻辑地址“,所以InnoDB要求表必须有主键,MyISAM可以没有。

自己的一点想法

看了很多的文章,心中一直在问自己一个问题,既然B+树那么好,那么B树存在的意义什么呢?因为innodb存储引擎和MyISAM存储都是使用的B+树。我自己的理解是:B树适合那种访问之后能够把相应的数据一起返回的数据结构。

那么,什么样子的才是访问到key之后把相应的value数据一起就返回的呢?上面也提到了因为B+树非叶子节点不存储value,所以占得空间小,所以相同的内存大小,B+树存储的节点更多,这说明了能够放在内存中的非叶子节点就更多。那么,B树存在的意义又是什么呢?

我觉得B树存在的意义是当都在内存中的时候,若是能够根据key直接把value得到然后返回,不用去磁盘查找, 明显要快很多,因为B+树的数据(value)是存在叶子节点中的,而叶子节点是存在于磁盘中的。也就是说当数据很小的时候,使用B数把数据跟key一起存放在非叶子节点中,可以更快的加速查找。

参考文献