mysql mongodb b树_为何Mongodb索引用B树,而Mysql用B+树?
引言
很久沒寫文章了,今天回來重操舊業。
今天講的這個主題,是《面試官:談談你對mysql索引的認識》,里頭提到的一個坑。mysql
也就是說,若是面試官問的是,為何Mysql中Innodb的索引結構采起B+樹?這個問題時,給本身留一條后路,不要把B樹噴的一文不值。由于網上有些答案是說,B樹不適合作文件存儲系統的索引結構。若是按照那種答法,本身就給本身挖了一個坑,很難收場。所以,就有了這篇文章的誕生~面試
文末附面試指南!sql
正文
這里的Mysql指的是Innodb的存儲引擎下的索引結構,其余存儲引擎咱們暫時不討論。mongodb
B樹和B+樹
開頭,咱們先回憶一下,B樹和B+樹的結構以及特色,以下所示:
B樹
數據庫
注意一下B樹的兩個明顯特色
樹內的每一個節點都存儲數據數據結構
葉子節點之間無指針相鄰ide
B+樹
性能
注意一下B+樹的兩個明顯特色mysql索引
數據只出如今葉子節點spa
全部葉子節點增長了一個鏈指針
針對上面的B+樹和B樹的特色,咱們作一個總結
(1)B樹的樹內存儲數據,所以查詢單條數據的時候,B樹的查詢效率不固定,最好的狀況是O(1)。咱們能夠認為在作單一數據查詢的時候,使用B樹平均性能更好。可是,因為B樹中各節點之間沒有指針相鄰,所以B樹不適合作一些數據遍歷操做。
(2)B+樹的數據只出如今葉子節點上,所以在查詢單條數據的時候,查詢速度很是穩定。所以,在作單一數據的查詢上,其平均性能并不如B樹。可是,B+樹的葉子節點上有指針進行相連,所以在作數據遍歷的時候,只須要對葉子節點進行遍歷便可,這個特性使得B+樹很是適合作范圍查詢。
所以,咱們能夠作一個推論:沒準是Mysql中數據遍歷操做比較多,因此用B+樹做為索引結構。而Mongodb是作單一查詢比較多,數據遍歷操做比較少,因此用B樹做為索引結構。
那么為何Mysql作數據遍歷操做多?而Mongodb作數據遍歷操做少呢?
由于Mysql是關系型數據庫,而Mongodb是非關系型數據。
那為何關系型數據庫,作數據遍歷操做多?
而非關系型數據庫,作數據遍歷操做少呢?
咱們繼續往下看
關系型VS非關系型
假設,咱們此時有兩個邏輯實體:學生(Student)和班級(Class),這兩個邏輯實體之間是一對多的關系。畢竟一個班級有多個學生,一個學生只能屬于一個班級。
關系型數據庫
咱們在關系型數據庫中,考慮的是用幾張表來表示這兩者之間的實體關系。常見的無外乎是,一對一關系,用一張表就行。一對多關系,用兩張表。多對多關系,用三張表。
那這里,咱們須要用兩張表表示兩者之間邏輯關系,以下所示
那咱們,此時要查
cname為
1班的班級,有多少學生怎么辦?
假設
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的這張表的葉子節點上,一遍又一遍的遍歷!
那在非關系型數據庫中,咱們如何查詢cname為1班的班級,有多少學生?
非關系型數據庫
有人說,你能夠這么設計?也就是弄兩個集合以下所示
而后,執行兩次查詢去得到結果!一次去class集合查,得到id后再去student集合查。
確實,這么設計是能夠的,我沒說不行。只是不符合非關系型數據庫的設計初衷。在MongoDB中,根本不推薦這么設計。雖然,Mongodb中有一個$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那樣的非關系型數據庫,我要用什么數據結構當索引比較合適?”
而后你就能夠回去等通知了!
上面三個套路都是真實存在的!總之,只要面試官想問這個問題,均可以繞到這個問題上去!
總結
其實這篇文章很早之前就想寫,后來一直耽擱著。今天有時間恰好補上,但愿你們有所收獲。
總結
以上是生活随笔為你收集整理的mysql mongodb b树_为何Mongodb索引用B树,而Mysql用B+树?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算feature map大小
- 下一篇: learning rate四种改变方式