這篇文章給大家介紹Mongodb中使用B樹索引的原因是什么,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
B樹和B+樹
開頭,我們先回憶一下,B樹和B+樹的結(jié)構(gòu)以及特點(diǎn)。
樹內(nèi)的每個(gè)節(jié)點(diǎn)都存儲數(shù)據(jù);
葉子節(jié)點(diǎn)之間無指針相鄰。
注意一下B樹的兩個(gè)明顯特點(diǎn):
數(shù)據(jù)只出現(xiàn)在葉子節(jié)點(diǎn);
所有葉子節(jié)點(diǎn)增加了一個(gè)鏈指針。
針對上面的B+樹和B樹的特點(diǎn),我們做一個(gè)總結(jié):
(1)B樹的樹內(nèi)存儲數(shù)據(jù),因此查詢單條數(shù)據(jù)的時(shí)候,B樹的查詢效率不固定,好的情況是O(1)。我們可以認(rèn)為在做單一數(shù)據(jù)查詢的時(shí)候,使用B樹平均性能更好。但是,由于B樹中各節(jié)點(diǎn)之間沒有指針相鄰,因此B樹不適合做一些數(shù)據(jù)遍歷操作。
(2) B+樹的數(shù)據(jù)只出現(xiàn)在葉子節(jié)點(diǎn)上,因此在查詢單條數(shù)據(jù)的時(shí)候,查詢速度非常穩(wěn)定。因此,在做單一數(shù)據(jù)的查詢上,其平均性能并不如B樹。但是,B+樹的葉子節(jié)點(diǎn)上有指針進(jìn)行相連,因此在做數(shù)據(jù)遍歷的時(shí)候,只需要對葉子節(jié)點(diǎn)進(jìn)行遍歷即可,這個(gè)特性使得B+樹非常適合做范圍查詢。
因此,我們可以做一個(gè)推論:沒準(zhǔn)是Mysql中數(shù)據(jù)遍歷操作比較多,所以用B+樹作為索引結(jié)構(gòu)。而Mongodb是做單一查詢比較多,數(shù)據(jù)遍歷操作比較少,所以用B樹作為索引結(jié)構(gòu)。
那么為什么Mysql做數(shù)據(jù)遍歷操作多?而Mongodb做數(shù)據(jù)遍歷操作少呢?
因?yàn)镸ysql是關(guān)系型數(shù)據(jù)庫,而Mongodb是非關(guān)系型數(shù)據(jù)。
那為什么關(guān)系型數(shù)據(jù)庫,做數(shù)據(jù)遍歷操作多?
而非關(guān)系型數(shù)據(jù)庫,做數(shù)據(jù)遍歷操作少呢?
關(guān)系型VS非關(guān)系型
假設(shè),我們此時(shí)有兩個(gè)邏輯實(shí)體:學(xué)生(Student)和班級(Class),這兩個(gè)邏輯實(shí)體之間是一對多的關(guān)系。畢竟一個(gè)班級有多個(gè)學(xué)生,一個(gè)學(xué)生只能屬于一個(gè)班級。
關(guān)系型數(shù)據(jù)庫
我們在關(guān)系型數(shù)據(jù)庫中,考慮的是用幾張表來表示這二者之間的實(shí)體關(guān)系。常見的無外乎是,一對一關(guān)系,用一張表就行。一對多關(guān)系,用兩張表。多對多關(guān)系,用三張表。
那我們,此時(shí)要查 cname 為 1班 的班級,有多少學(xué)生怎么辦?
假設(shè) cname 這列,我們建了索引!
執(zhí)行SQL,如下所示!
SELECT *
FROM t_student t1, (
SELECT cid
FROM t_class
WHERE cname = '1班'
) t2
WHERE t1.cid = t2.cid
而這,就涉及到了數(shù)據(jù)遍歷操作!
因?yàn)榈沧鲞@種關(guān)聯(lián)查詢,你躲不開join操作的!既然涉及到了join操作,無外乎從一個(gè)表中取一個(gè)數(shù)據(jù),去另一個(gè)表中逐行匹配,如果索引結(jié)構(gòu)是B+樹,葉子節(jié)點(diǎn)上是有指針的,能夠極大的提高這種一行一行的匹配速度!
有的人或許會抬杠說,如果我先執(zhí)行:
SELECT cid
FROM t_class
WHERE cname = '1班'
獲得cid后,再去循環(huán)執(zhí)行:
SELECT *
FROM t_student
WHERE cid = ...
就可以避開join操作呀?
對此,我想說。你確實(shí)避開了join操作,但是你數(shù)據(jù)遍歷操作還是沒避開。你還是需要在student的這張表的葉子節(jié)點(diǎn)上,一遍又一遍的遍歷!
那在非關(guān)系型數(shù)據(jù)庫中,我們?nèi)绾尾樵?cname 為 1班 的班級,有多少學(xué)生?
非關(guān)系型數(shù)據(jù)庫
執(zhí)行兩次查詢?nèi)カ@得結(jié)果!一次去class集合查,獲得id后再去student集合查。
確實(shí),這么設(shè)計(jì)是可以的,我沒說不行。只是不符合非關(guān)系型數(shù)據(jù)庫的設(shè)計(jì)初衷。在MongoDB中,根本不推薦這么設(shè)計(jì)。雖然,Mongodb中有一個(gè)$lookup操作,可以做join查詢。但是理想情況下,這個(gè)$lookup操作應(yīng)該不會經(jīng)常使用,如果你需要經(jīng)常使用它,那么你就使用了錯(cuò)誤的數(shù)據(jù)存儲了(數(shù)據(jù)庫):如果你有相關(guān)聯(lián)的數(shù)據(jù),應(yīng)該使用關(guān)系型數(shù)據(jù)庫(SQL)。
假設(shè) name 這列,我們建了索引!
我只需執(zhí)行一次語句:
db.class.find( { name: '1班' } )
這樣就能查詢出自己想要的結(jié)果。
而這,就是一種單一數(shù)據(jù)查詢!畢竟你不需要去逐行匹配,不涉及遍歷操作,幸運(yùn)的情況下,有可能一次IO就能夠得到你想要的結(jié)果。
因此,由于關(guān)系型數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)的設(shè)計(jì)方式上的不同。導(dǎo)致在關(guān)系型數(shù)據(jù)中,遍歷操作比較常見,因此采用B+樹作為索引,比較合適。而在非關(guān)系型數(shù)據(jù)庫中,單一查詢比較常見,因此采用B樹作為索引,比較合適。
目前面試套路有如下幾種:
套路一
你簡歷寫了mysql,沒寫mongodb!
面試官:"說說mysql索引結(jié)構(gòu)?"
我:"巴拉巴拉"
面試官:"知道為什么用B+樹,不用B樹么?"
這個(gè)時(shí)候正常的面試者就蒙了,會把B樹的缺點(diǎn)噴一通!于是乎下一問就是。
面試官:"其實(shí)一些非關(guān)系型數(shù)據(jù)庫,如mongodb用的就是B樹,你知道原因么?"
然后你就回去等通知了!
套路二
你簡歷寫了mysql,也寫了mongodb!
這種情況更完美!
面試官:"說說mysql索引結(jié)構(gòu)?"
我:"巴拉巴拉"
面試官:"你簡歷寫了Mongodb,有了解過他的索引結(jié)構(gòu)么?"
我:"巴拉巴拉"
面試官:"為什么Mongodb索引用B樹,而Mysql用B+樹?"
然后你就回去等通知了!
套路三
你簡歷既沒寫mysql,沒寫mongodb!
面試官;"如果你來設(shè)計(jì)數(shù)據(jù)庫,你會對他的索引用什么數(shù)據(jù)結(jié)構(gòu)?"
我:"首先不考慮紅黑樹這類,巴拉巴拉…應(yīng)該會用B樹或者B+樹。"
面試官;“如果我要設(shè)計(jì)一個(gè)像Mongodb那樣的非關(guān)系型數(shù)據(jù)庫,我要用什么數(shù)據(jù)結(jié)構(gòu)當(dāng)索引比較合適?”
關(guān)于Mongodb中使用B樹索引的原因是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
分享名稱:Mongodb中使用B樹索引的原因是什么-創(chuàng)新互聯(lián)
網(wǎng)頁鏈接:http://chinadenli.net/article12/ehjgc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站建設(shè)、用戶體驗(yàn)、App開發(fā)、企業(yè)網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容