B-树,这里的 B 表示 balance( 平衡的意思),B-树是一种多路自平衡的搜索树
它相似普通的平衡二叉树,不一样的一点是B-树容许每一个节点有更多的子节点。下图是 B-树的简化图.html
B-树有以下特色:mysql
全部键值分布在整颗树中;linux
任何一个关键字出现且只出如今一个结点中;git
搜索有可能在非叶子结点结束;github
在关键字全集内作一次查找,性能逼近二分查找;算法
B+树是B-树的变体,也是一种多路搜索树, 它与 B- 树的不一样之处在于:sql
全部关键字存储在叶子节点出现,内部节点(非叶子节点并不存储真正的 data)数据库
为全部叶子结点增长了一个链指针数据结构
简化 B+树 以下图性能
红黑树等数据结构也能够用来实现索引,可是文件系统及数据库系统广泛采用B-/+Tree做为索引结构。MySQL 是基于磁盘的数据库系统,索引每每以索引文件的形式存储的磁盘上,索引查找过程当中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,索引的结构组织要尽可能减小查找过程当中磁盘I/O的存取次数。为何使用B-/+Tree,还跟磁盘存取原理有关。
因为磁盘的存取速度与内存之间鸿沟,为了提升效率,要尽可能减小磁盘I/O.磁盘每每不是严格按需读取,而是每次都会预读,磁盘读取完须要的数据,会顺序向后读必定长度的数据放入内存。而这样作的理论依据是计算机科学中著名的局部性原理:
当一个数据被用到时,其附近的数据也一般会立刻被使用 程序运行期间所须要的数据一般比较集中
因为磁盘顺序读取的效率很高(不须要寻道时间,只需不多的旋转时间),所以对于具备局部性的程序来讲,预读能够提升I/O效率.预读的长度通常为页(page)的整倍数。
MySQL(默认使用InnoDB引擎),将记录按照页的方式进行管理,每页大小默认为16K(这个值能够修改).linux 默认页大小为4K
实际实现B-Tree还须要使用以下技巧:
每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个结点只需一次I/O。
假设 B-Tree 的高度为 h,B-Tree中一次检索最多须要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)O(h)=O(logdN)。通常实际应用中,出度d是很是大的数字,一般超过100,所以h很是小(一般不超过3)。
而红黑树这种结构,h明显要深的多。因为逻辑上很近的节点(父子)物理上可能很远,没法利用局部性,因此红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差不少。
B+树更适合外部存储,因为内节点无 data 域,一个结点能够存储更多的内结点,每一个节点能索引的范围更大更精确,也意味着 B+树单次磁盘IO的信息量大于B-树,I/O效率更高。
Mysql是一种关系型数据库,区间访问是常见的一种状况,B+树叶节点增长的链指针,增强了区间访问性,可以使用在范围区间查询等,而B-树每一个节点 key 和 data 在一块儿,则没法区间查找。
个人博客: http://ygmyth.github.io
[1] 姜承尧 著;MySQL技术内幕-InnoDB存储引擎;机械工业出版社,2013
[2] MySQL索引背后的数据结构及算法原理 http://blog.codinglabs.org/articles/theo...
[3] 从 MongoDB 及 Mysql 谈B/B+树 http://blog.csdn.net/wwh578867817/articl...