• B-tree B+tree适合文件系统索引和MySQL索引


    B-树

    B-树,这里的 B 表示 balance( 平衡的意思),B-树是一种多路自平衡的搜索树 
    它类似普通的平衡二叉树,不同的一点是B-树允许每个节点有更多的子节点。下图是 B-树的简化图.

    图片描述

    B-树有如下特点:

    1. 所有键值分布在整颗树中;

    2. 任何一个关键字出现且只出现在一个结点中;

    3. 搜索有可能在非叶子结点结束;

    4. 在关键字全集内做一次查找,性能逼近二分查找;

    B+ 树

    B+树是B-树的变体,也是一种多路搜索树, 它与 B- 树的不同之处在于:

    1. 所有关键字存储在叶子节点出现,内部节点(非叶子节点并不存储真正的 data)

    2. 为所有叶子结点增加了一个链指针

    简化 B+树 如下图

    图片描述

    为什么使用B-/B+ Tree

    红黑树等数据结构也可以用来实现索引,但是文件系统及数据库系统普遍采用B-/+Tree作为索引结构。MySQL 是基于磁盘的数据库系统,索引往往以索引文件的形式存储的磁盘上,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。为什么使用B-/+Tree,还跟磁盘存取原理有关。

    局部性原理与磁盘预读

    由于磁盘的存取速度与内存之间鸿沟,为了提高效率,要尽量减少磁盘I/O.磁盘往往不是严格按需读取,而是每次都会预读,磁盘读取完需要的数据,会顺序向后读一定长度的数据放入内存。而这样做的理论依据是计算机科学中著名的局部性原理:

    当一个数据被用到时,其附近的数据也通常会马上被使用
    程序运行期间所需要的数据通常比较集中

    由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率.预读的长度一般为页(page)的整倍数。

    MySQL(默认使用InnoDB引擎),将记录按照页的方式进行管理,每页大小默认为16K(这个值可以修改).linux 默认页大小为4K

    B-/+Tree索引的性能分析

    来自张洋的博客:

    实际实现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+树

    1. B+树更适合外部存储,由于内节点无 data 域,一个结点可以存储更多的内结点,每个节点能索引的范围更大更精确,也意味着 B+树单次磁盘IO的信息量大于B-树,I/O效率更高。

    2. Mysql是一种关系型数据库,区间访问是常见的一种情况,B+树叶节点增加的链指针,加强了区间访问性,可使用在范围区间查询等,而B-树每个节点 key 和 data 在一起,则无法区间查找。

     

    B+树的优势所在

    为什么说B+树比B~树更适合实际应用中操作系统的文件索引和数据库索引?

    1、B+树的磁盘读写代价更低

         磁盘是可以块存储的,也就是同一个磁道上同一盘块中的所有数据都可以一次全部读取(详见《 外部存储器—磁盘 》 )。而B+树的内部结点并没有指向关键字具体信息的指针(比如文件内容的具体地址 , 比如说不包含B~树结点中的FileHardAddress[filenum]部分) 。因此其内部结点相对B~树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。这样,一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。

    举个例子,假设磁盘中的一个盘块容纳16bytes,而一个关键字2bytes,一个关键字具体信息指针2bytes。一棵9阶B~树(一个结点最多8个关键字)的内部结点需要2个盘快。而B+树内部结点只需要1个盘快。当需要把内部结点读入内存中的时候,B~树就比B+数多一次盘块查找时间(在磁盘中就是盘片旋转的时间)。

    2、B+树的查询效率更加稳定。 

    由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。

    所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

    参考文献

    [1] 姜承尧 著;MySQL技术内幕-InnoDB存储引擎;机械工业出版社,2013
    [2] MySQL索引背后的数据结构及算法原理 http://blog.codinglabs.org/articles/theo...
    [3] 从 MongoDB 及 Mysql 谈B/B+树 http://blog.csdn.net/wwh578867817/articl...

  • 相关阅读:
    剖析 GSM 加密机制以及位置更新的过程
    利用ASK/OOK 发射模块,实现信号重放
    使用RTL-SDR打开车门
    复现 360 Unicorn Team 黑科技之 HackNFC
    如何搭建并使用便携式 4G/LTE 伪基站研究移动安全
    如何利用 LTE/4G 伪基站+GSM 中间人攻击攻破所有短信验证
    黑客炼金术士 Seeker:可以攻破 4G 摸到你短信,还要为朝阳群众提供谍战工具
    如何使用HackRF做一个简单的IMSI捕获器
    招中高级web开发工程师
    ionic 动画和返回按钮
  • 原文地址:https://www.cnblogs.com/linghu-java/p/9600693.html
Copyright © 2020-2023  润新知