本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.htmlhtml
维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种树状数据结构,它可以存储数据、对其进行排序并容许以O(log n)的时间复杂度运行进行查找、顺序读取、插入和删除的数据结构。B树,归纳来讲是一个节点能够拥有多于2个子节点的二叉查找树。与自平衡二叉查找树不一样,B-树为系统最优化大块数据的读和写操做。B-tree算法减小定位记录时所经历的中间过程,从而加快存取速度。广泛运用在数据库和文件系统。”node
B 树能够看做是对2-3查找树的一种扩展,即他容许每一个节点有M-1个子节点。mysql
下图是一个M=4 阶的B树:算法
能够看到B树是2-3树的一种扩展,他容许一个节点有多于2个的元素。sql
B树的插入及平衡化操做和2-3树很类似,这里就不介绍了。下面是往B树中依次插入数据库
6 10 4 14 5 11 15 3 2 12 1 7 8 8 6 3 6 21 5 15 15 6 32 23 45 65 7 8 6 5 4缓存
的演示动画:数据结构
B+树是对B树的一种变形树,它与B树的差别在于:dom
以下图,是一个B+树:优化
下图是B+树的插入动画:
B和B+树的区别在于,B+树的非叶子结点只包含导航信息,不包含实际的值,全部的叶子结点和相连的节点使用链表相连,便于区间查找和遍历。
B+ 树的优势在于:
可是B树也有优势,其优势在于,因为B树的每个节点都包含key和value,所以常常访问的元素可能离根节点更近,所以访问也更迅速。下面是B 树和B+树的区别图:
对B树和B+树的分析和对前面讲解的2-3树的分析相似,
对于一颗节点为N度为M的子树,查找和插入须要logM-1N ~ logM/2N次比较。这个很好证实,对于度为M的B树,每个节点的子节点个数为M/2 到 M-1之间,因此树的高度在logM-1N至logM/2N之间。
这种效率是很高的,对于N=62*1000000000个节点,若是度为1024,则logM/2N <=4,即在620亿个元素中,若是这棵树的度为1024,则只须要小于4次便可定位到该节点,而后再采用二分查找便可找到要找的值。
B树和B+普遍应用于文件存储系统以及数据库系统中,在讲解应用以前,咱们看一下常见的存储结构:
咱们计算机的主存基本都是随机访问存储器(Random-Access Memory,RAM),他分为两类:静态随机访问存储器(SRAM)和动态随机访问存储器(DRAM)。SRAM比DRAM快,可是也贵的多,通常做为CPU的高速缓存,DRAM一般做为内存。这类存储器他们的结构和存储原理比较复杂,基本是使用电信号来保存信息的,不存在机器操做,因此访问速度很是快,具体的访问原理能够查看CSAPP,另外,他们是易失的,即若是断电,保存DRAM和SRAM保存的信息就会丢失。
咱们使用的更多的是使用磁盘,磁盘可以保存大量的数据,从GB一直到TB级,可是 他的读取速度比较慢,由于涉及到机器操做,读取速度为毫秒级,从DRAM读速度比从磁盘度快10万倍,从SRAM读速度比从磁盘读快100万倍。下面来看下磁盘的结构:
如上图,磁盘由盘片构成,每一个盘片有两面,又称为盘面(Surface),这些盘面覆盖有磁性材料。盘片中央有一个能够旋转的主轴(spindle),他使得盘片以固定的旋转速率旋转,一般是5400转每分钟(Revolution Per Minute,RPM)或者是7200RPM。磁盘包含一个多多个这样的盘片并封装在一个密封的容器内。上图左,展现了一个典型的磁盘表面结构。每一个表面是由一组成为磁道(track)的同心圆组成的,每一个磁道被划分为了一组扇区(sector).每一个扇区包含相等数量的数据位,一般是(512)子节。扇区之间由一些间隔(gap)隔开,不存储数据。
以上是磁盘的物理结构,如今来看下磁盘的读写操做:
如上图,磁盘用读/写头来读写存储在磁性表面的位,而读写头链接到一个传动臂的一端。经过沿着半径轴先后移动传动臂,驱动器能够将读写头定位到任何磁道上,这称之为寻道操做。一旦定位到磁道后,盘片转动,磁道上的每一个位通过磁头时,读写磁头就能够感知到位的值,也能够修改值。对磁盘的访问时间分为 寻道时间,旋转时间,以及传送时间。
因为存储介质的特性,磁盘自己存取就比主存慢不少,再加上机械运动耗费,所以为了提升效率,要尽可能减小磁盘I/O,减小读写操做。为了达到这个目的,磁盘每每不是严格按需读取,而是每次都会预读,即便只须要一个字节,磁盘也会从这个位置开始,顺序向后读取必定长度的数据放入内存。这样作的理论依据是计算机科学中著名的局部性原理:
当一个数据被用到时,其附近的数据也一般会立刻被使用。
程序运行期间所须要的数据一般比较集中。
因为磁盘顺序读取的效率很高(不须要寻道时间,只需不多的旋转时间),所以对于具备局部性的程序来讲,预读能够提升I/O效率。
预读的长度通常为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操做系统每每将主存和磁盘存储区分割为连续的大小相等的块,每一个存储块称为一页(在许多操做系统中,页得大小一般为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,而后异常返回,程序继续运行。
文件系统及数据库系统的设计者利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每一个节点只须要一次I/O就能够彻底载入。为了达到这个目的,在实际实现B-Tree还须要使用以下技巧:
每次新建一个节点的同时,直接申请一个页的空间( 512或者1024),这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。如,将B树的度M设置为1024,这样在前面的例子中,600亿个元素中只须要小于4次查找便可定位到某一存储位置。
同时在B+树中,内节点只存储导航用到的key,并不存储具体值,这样内节点个数较少,可以所有读取到主存中,外接点存储key及值,而且顺序排列,具备良好的空间局部性。因此B及B+树比较适合与文件系统的数据结构。下面是一颗B树,用来进行内容存储。
另外B/B+树也常常用作数据库的索引,这方面推荐您直接看张洋的MySQL索引背后的数据结构及算法原理 这篇文章,这篇文章对MySQL中的如何使用B+树进行索引有比较详细的介绍,推荐阅读。
在前面两篇文章介绍了平衡查找树中的2-3树,红黑树以后,本文介绍了文件系统和数据库系统中经常使用的B/B+ 树,他经过对每一个节点存储个数的扩展,使得对连续的数据可以进行较快的定位和访问,可以有效减小查找时间,提升存储的空间局部性从而减小IO操做。他普遍用于文件系统及数据库中,如:
但愿本文对您了解B/B+ 树有所帮助。