树结构系列(四):MongoDb 使用的到底是 B 树,还是 B+ 树?

文章首发于「陈树义」公众号及个人博客 shuyi.tech
文章首发于「陈树义」公众号及个人博客 shuyi.tech,欢迎访问更多有趣有价值的文章。
关于 B 树与 B+ 树,网上有一个比较经典的问题:为什么 MongoDb 使用 B 树,而 MySQL 索引使用 B+ 树?
但实际上 MongoDb 真的用的是 B 树吗?
通过查阅资料,我从 MongoDb 的官网和 WiredTiger 官网找到了答案。MongoDb 官网关于存储引擎(Storage Engine)的描述写道:从 MongoDb 3.2 版本开始,其使用了 WiredTiger 作为其默认的存储引擎。

文档地址:WiredTiger Storage Engine — MongoDB Manual
而从 WiredTiger 官网文档,我们可以知道:WiredTiger 使用的是 B+ 树作为其存储结构。

文档地址:WiredTiger: Tuning page size and compression
那为什么会出现很多资料说 MongoDb 使用 B 树作为存储的数据结构呢?我想可能有两个原因:一个原因可能是 B+ Tree 本身是 B 树的一种优化,所以很多人就直接把 B+ 树说成 B 树了。另一个原因可能是 MongoDb 3.2 之前,确实使用 B 树作为存储的数据结构。
文章首发于「陈树义」公众号及个人博客 shuyi.tech,欢迎访问更多有趣有价值的文章。
对于这两个原因,我没有深入去探寻,有答案的朋友可以留言讨论一下。但我知道,无论是什么原因,都不影响我们对这个问题的讨论。表面上,我们是在讨论 MongoDb 与 MySQL 存储的数据结构,但实际上我们是在讨论 B 树和 B+ 树这两种数据结构的特点。
因此,无论 MongoDb 使用的是 B 树,还是 B+ 树。只要我们弄清楚 B 树与 B+ 树之间的区别,我们就可以在合适的时候,选择合适的数据结构。
B 树与 B+ 树,其比较大的特点是:B 树对于特定记录的查询,其时间复杂度更低。而 B+ 树对于范围查询则更加方便,另外 B+ 树相对于 B 树来说更加扁平。
对于 MongoDb 来说,其是非关系型数据库,较少做联表的范围查询。如果这确实是 MongoDb 非常典型的使用场景,使用 B 树其实可以加快其查询速度。
但实际上 MongoDb 3.2 之后,其使用了 B+ 树作为其数据结构。B+ 树其在范围查询方面更有优势,那有可能是 B+ 树更加扁平,可以让其更加快速地找到数据,加快其查找速度。也有可能是 MongoDb 的范围查询特性使用更加广泛了。
说到这里,你可能有点迷糊,那实际情况到底是什么呢?
其实我自己并没有找到答案。我的思考也是到此为止,我也并没有找到更好的答案。与其腹死胎中,还不如写下来与大家讨论。或许不久之后我就忽然大悟,明白这其中的道理,到时候再来给大家分享。
写到这里,脑袋里蹦出另外一个问题:那为啥 MongoDb 要使用 B+ 树 ?而不使用平衡二叉树?嗯,答案其实很简单——是因为需要使用 B 树能加载大数据量的特性,否则其实现不了这么大量数据的查询和排序。
如果你有其他看法,欢迎留言与我交流。
参考资料
- WiredTiger 存储引擎之一:基础数据结构分析 | MongoDB 中文社区
- 为什么有关MongoDB采用B树索引,以及Mysql B+树做索引? - dabbler0606的回答 - 知乎
- 【原创】为什么 Mongodb 索引用 B 树,而 Mysql 用 B + 树?- 孤独烟 - 博客园
- https://www.cnblogs.com/morethink/p/9251530.html
树结构系列(四):MongoDb 使用的到底是 B 树,还是 B+ 树?的更多相关文章
- 树结构系列(三):B树、B+树
树结构系列(三):B树.B+树 文章首发于「陈树义」公众号及个人博客 shuyi.tech,欢迎访问更多有趣有价值的文章. 文章首发于「陈树义」公众号及个人博客 shuyi.tech 平衡二叉树的查找 ...
- VSTO之旅系列(四):创建Word解决方案
原文:VSTO之旅系列(四):创建Word解决方案 本专题概要 引言 Word对象模型 创建Word外接程序 小结 一.引言 在上一个专题中主要为大家介绍如何自定义我们的Excel 界面的,然而在这个 ...
- [转]C# 互操作性入门系列(四):在C# 中调用COM组件
传送门 C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列(二):使用平台调用调用Win32 函数 C# 互操作性入门系列(三):平台调用中的数据封送处理 ...
- 前端构建大法 Gulp 系列 (四):gulp实战
前端构建大法 Gulp 系列 (一):为什么需要前端构建 前端构建大法 Gulp 系列 (二):为什么选择gulp 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gulp专家 前 ...
- Netty4.x中文教程系列(四) 对象传输
Netty4.x中文教程系列(四) 对象传输 我们在使用netty的过程中肯定会遇到传输对象的情况,Netty4通过ObjectEncoder和ObjectDecoder来支持. 首先我们定义一个U ...
- S5PV210开发系列四_uCGUI的移植
S5PV210开发系列四 uCGUI的移植 象棋小子 1048272975 GUI(图形用户界面)极大地方便了非专业用户的使用,用户无需记忆大量的命令,取而代之的是能够通过窗体.菜单 ...
- WCF编程系列(四)配置文件
WCF编程系列(四)配置文件 .NET应用程序的配置文件 前述示例中Host项目中的App.config以及Client项目中的App.config称为应用程序配置文件,通过该文件配置可控制程序的 ...
- SQL Server 2008空间数据应用系列四:基础空间对象与函数应用
原文:SQL Server 2008空间数据应用系列四:基础空间对象与函数应用 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2008 R2调测. ...
- 系列四TortoiseSvn客户端软件
原文:系列四TortoiseSvn客户端软件 TortoiseSvn介绍 TortoiseSvn 是 Subversion 版本控制系统的一个免费开源客户端,可以超越时间的管理文件和目录.文件保存在中 ...
随机推荐
- NGK项目是一个怎样的项目?区块链里算是有前景的吗?
牛市时,项目被众星捧月,优点被无限放大,缺点无限被掩盖:而当市场开始下行时,之前的赞美则变成了贬低.所以了解项目不能盲目跟风,需要有独立的思考.对于近期引起社区讨论的NGK项目,以它为例,今天就来给大 ...
- 01.Numpy数组的基本应用
数组的创建 数组的访问 数组的合并 数组的分割 数组创建 >>> import numpy as np 创建一维数组 >>> x = np.arange(10) & ...
- css中a元素放长英文字母或者数字自动换行的解决
在做链接分享页面的时候遇到a元素中的下载链接长英文溢出不换行的问题 在给他以及他父元素设置宽度依然没有解决这个问题 最后解决办法给元素加上word-wrap:break-word 解释:使用break ...
- 正则表达式匹配${key}并在Java中使用
1.正则表达式匹配${key} \$\{([a-z]+)\} 能够匹配字符串中以${key}形式的文本(其中key为小写应为字母) .*\$\{([a-z]+)\}.* 可以用来检测文本中是否有${k ...
- SpringBoot整合MyBatis-Plus框架(代码生成器)
MyBatis-Plus的简介 Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发.提高效率而生. 代码生成器 通用的CU ...
- 错误信息:...\output\project.axf: error: l6218e: undefined symbol usart1_confing (referred from main.o).
说明:此文档知识用来记录,顺便给大家作为参考,如有错误的地方请大家多多指正,在下内心定会感激不尽. 前言:关于这个问题,我曾花了一个下午在网上寻找,网上的说法五花八门,我办法试尽,但遍寻无果.由此我认 ...
- SpringCloud(三):SpringCloud快速开发入门
3-1. 搭建和配置一个服务提供者 我们知道,SpringCloud 构建微服务是基于 SpringBoot 开发的.(如果SpringBoot不会的可以先看SpringBoot专栏) 1. 创建一 ...
- CSS过渡约束的计算
CSS过度约束性质 什么是CSS过度约束 当没有开启绝对定位或固定定位时 水平布局必须要满足以下等式 探寻能够设置成auto的CSS属性 等式不成立(过度约束)时的几种情况 当margin与width ...
- 只需2分钟!PC端的报表即可转换成手机报表
转: 只需2分钟!PC端的报表即可转换成手机报表 手机制作报表,这个大家不知有没有尝试过,虽然我们平时都用电脑做,但是电脑要是不在身边了,手机就可以用来应应急.但其实小编并没有在手机上制作报表的实践经 ...
- 【Android笔记】Thread类中关于join()方法的源码分析
1.join()方法的作用: 例如有一个线程对象为Thread1,在main()方法中调用Thread1.join()方法可使得当前线程(即主线程)阻塞,而执行Thread1线程. 2.源码分析(以上 ...