数据库为什么用B+树

来源:互联网 发布:南京软件外包公司 编辑:程序博客网 时间:2024/05/16 06:41
作者:打码酱
链接:https://www.zhihu.com/question/62406977/answer/219108182
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

其实主要原因就是减少读写磁盘的次数。其它答主都已经回答了,我这里画蛇添足(把为什么三个字好好解释一番),较为详细的具体解释一下,不对的地方,还请海涵并敬请赐教。

  1. 磁盘与主存的速度差: 读取DRAM(主存)的速度是读写磁盘速度的大约10万倍(有些答主说几千倍是不严谨滴,可以参考CSAPP 虚拟存储器那一章),并且第一次读写某扇区第一字节的速度比连续读该磁盘其他字节的速度慢约10万倍。了解了这么大的速度差异后,聪明机智的你很自然的就想到,我每次读写磁盘时都尽可能多的读数据,改写了之后不直接回写,必要的时候再写回(也就是写回式),应该能很大减少读写磁盘的次数。 很显然这就是B树所做的事儿。
  2. B树的特点:首先B树是很严格的平衡二叉搜索树(叶子节点深度都相同,相比较而言红黑树那家伙可没这么守规矩), 每个节点中的关键字可以有很多。 由于 1 中所述的原因, B树的节点大小与磁盘页一样大(Linux中一般是4K)。至于为什么要和磁盘也一样大?这是和虚拟存储器系统运行的机制有关,存储器映射是虚拟页(磁盘, linux中一般是4K)映射到物理页(主存,Linux中一般是4K),然后由虚拟存储器系统在背后默默地悄无声息地完成数据移动的工作。 这样B树的每个节点的关键字数就很多了,具体取决于关键字(及其所带的卫星数据)相对于磁盘页的大小,《算法导论》(B树章节)中说一般是50~2000之间。 这么大的分支因子,使得B树树深较小,读写磁盘次数大大减少。由于B树根节点一般常驻内存,很明显,要读取某一结点上的数据所需读写磁盘的次数就等于该节点的深度。并且由于读写数据一般都具有局部性(空间局部性和时间局部性)的原因,使得读写磁盘减少的次数比想象中的还好(你明明只是饿了,叫了份外卖,结果送外卖的还是个美女)。
  3. B树的插入和删除 B树插入和删除的时候,是采用沿途分裂和沿途和并的方式进行的(真的好机智吖),基本上避免了回溯(删除时有一种情况要回溯),也就是和查找时,读写磁盘的次数差不多。
  4. 为什么是B+(B-)树: 用B+树的原因其实还是想让一个节点中包含更多的关键字,B+树把数据域都放到叶子节点上,这样内部节点只剩关键字了,这样一个节点(一个磁盘页)就能包含更多的关键字了,降低树深,减少读写磁盘次数!
  5. MySQL中的B+树: 据我所知,MySQL中MYISAM引擎,InnoDB引擎(其他引擎没了解过,惭愧~~)都是以B+树作为数据结构的,并且在B+树叶子节点层添加了顺序访问的指针,从而加快顺序访问的速度。

综上所述, 选用B+树(另外B树就是B-树, 因为B树英文是 B-Tree由于翻译差异导致出现了 B树和B-树)。 欢迎指正,敬请赐教!

阅读全文
0 0
原创粉丝点击