Mongo和Mysql中的B树索引

为何Mysql中Innodb的索引结构采起B+树?

回答这个问题时,给本身留一条后路,不要把B树喷的一文不值。由于网上有些答案是说,B树不适合作文件存储系统的索引结构。若是按照那种答法,本身就给本身挖了一个坑,很难收场。所以,就有了这篇文章的诞生~mysql

文末附面试指南!面试

正文

这里的Mysql指的是Innodb的存储引擎下的索引结构,其余存储引擎咱们暂时不讨论。sql

B树和B+树

开头,咱们先回忆一下,B树和B+树的结构以及特色,以下所示:
B树
mongodb

注意一下B树的两个明显特色数据库

  • 树内的每一个节点都存储数据
  • 叶子节点之间无指针相邻

B+树
数据结构

注意一下B+树的两个明显特色性能

  • 数据只出如今叶子节点
  • 全部叶子节点增长了一个链指针

针对上面的B+树和B树的特色,咱们作一个总结
(1)B树的树内存储数据,所以查询单条数据的时候,B树的查询效率不固定,最好的状况是O(1)。咱们能够认为在作单一数据查询的时候,使用B树平均性能更好。可是,因为B树中各节点之间没有指针相邻,所以B树不适合作一些数据遍历操做。mysql索引

(2)B+树的数据只出如今叶子节点上,所以在查询单条数据的时候,查询速度很是稳定。所以,在作单一数据的查询上,其平均性能并不如B树。可是,B+树的叶子节点上有指针进行相连,所以在作数据遍历的时候,只须要对叶子节点进行遍历便可,这个特性使得B+树很是适合作范围查询。spa

所以,咱们能够作一个推论:没准是Mysql中数据遍历操做比较多,因此用B+树做为索引结构。而Mongodb是作单一查询比较多,数据遍历操做比较少,因此用B树做为索引结构。设计

那么为何Mysql作数据遍历操做多?而Mongodb作数据遍历操做少呢?
由于Mysql是关系型数据库,而Mongodb是非关系型数据。

那为何关系型数据库,作数据遍历操做多?而非关系型数据库作数据遍历操做少呢?
咱们继续往下看

关系型VS非关系型

假设,咱们此时有两个逻辑实体:学生(Student)和班级(Class),这两个逻辑实体之间是一对多的关系。毕竟一个班级有多个学生,一个学生只能属于一个班级。
关系型数据库
咱们在关系型数据库中,考虑的是用几张表来表示这两者之间的实体关系。常见的无外乎是,一对一关系,用一张表就行。一对多关系,用两张表。多对多关系,用三张表。
那这里,咱们须要用两张表表示两者之间逻辑关系,以下所示

那咱们,此时要查cname1班的班级,有多少学生怎么办?
假设cname这列,咱们建了索引!
执行SQL,以下所示!

SELECT *
FROM t_student t1, (
        SELECT cid
        FROM t_class
        WHERE cname = '1班'
    ) t2
WHERE t1.cid = t2.cid

而这,就涉及到了数据遍历操做!

由于但凡作这种关联查询,你躲不开join操做的!既然涉及到了join操做,无外乎从一个表中取一个数据,去另外一个表中逐行匹配,若是索引结构是B+树,叶子节点上是有指针的,可以极大的提升这种一行一行的匹配速度!

有的人或许会抬杠说,若是我先执行

SELECT cid
FROM t_class
WHERE cname = '1班'

得到cid后,再去循环执行

SELECT *
FROM t_student
WHERE cid = ...

就能够避开join操做呀?

对此,我想说。你确实避开了join操做,可是你数据遍历操做仍是没避开。你仍是须要在student的这张表的叶子节点上,一遍又一遍的遍历!

那在非关系型数据库中,咱们如何查询cname1班的班级,有多少学生?
非关系型数据库
有人说,你能够这么设计?也就是弄两个集合以下所示

而后勒,执行两次查询去得到结果!

确实,这么设计是能够的,我没说不行。只是不符合非关系型数据库的设计初衷。在MongoDB中,根本不推荐这么设计。虽然,Mongodb中有一个lookup操做,能够作join查询。可是理想状况下,这个lookup操做,能够作join查询。可是理想状况下,这个lookup操做应该不会常用,若是你须要常用它,那么你就使用了错误的数据存储了(数据库):若是你有相关联的数据,应该使用关系型数据库(SQL)。

所以,正规的设计应该以下

假设name这列,咱们建了索引!
我只寻执行一次语句

db.class.find( { name: '1班' } )

这样就能查询出本身想要的结果。

而这,就是一种单一数据查询!毕竟你不须要去逐行匹配,不涉及遍历操做,幸运的状况下,有可能一次IO就可以获得你想要的结果。

所以,因为关系型数据库和非关系型数据的设计方式上的不一样。致使在关系型数据中,遍历操做比较常见,所以采用B+树做为索引,比较合适。而在非关系型数据库中,单一查询比较常见,所以采用B树做为索引,比较合适。

面试套路

目前套路有以下几种

套路一

你简历写了mysql,没写mongodb!
面试官:"说说mysql索引结构?"
我:"巴拉巴拉"
面试官:"知道为何用B+树,不用B树么?"
这个时候正常的面试者就蒙了,会把B树的缺点喷一通!因而乎下一问就是
面试官:"其实一些非关系型数据库,如mongodb用的就是B树,你知道缘由么?"
而后你就回去等通知了!

套路二

你简历写了mysql,也写了mongodb!
这种状况更完美!
面试官:"说说mysql索引结构?"
我:"巴拉巴拉"
面试官:"你简历写了Mongodb,有了解过他的索引结构么?"
我:"巴拉巴拉"
面试官:"为何Mongodb索引用B树,而Mysql用B+树?"
而后你就回去等通知了!

套路三

你简历既没写mysql,没写mongodb! 面试官;"若是你来设计数据库,你会对他的索引用什么数据结构?" 我:"首先不考虑红黑树这类,巴拉巴拉...应该会用B树或者B+树。" 面试官;“若是我要设计一个像Mongodb那样的非关系型数据库,我要用什么数据结构当索引比较合适?” 而后你就能够回去等通知了!

相关文章
相关标签/搜索