葉仁鵬
摘要:隨著大數(shù)據(jù)的發(fā)展,原有的數(shù)據(jù)存儲(chǔ)方式已經(jīng)很能滿足業(yè)務(wù)需求,很多數(shù)據(jù)的存儲(chǔ)使用了NoSQL(非關(guān)系型數(shù)據(jù)庫(kù))。例如MongoDB、Redis就是如今很好的兩種NoSQL代表。但傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù)的應(yīng)用還是占據(jù)了很大的比重,很多項(xiàng)目的數(shù)據(jù)庫(kù)還是選用Oracle、MySQL、SQL Server、DB2等。目前很多實(shí)際項(xiàng)目中使用關(guān)系型數(shù)據(jù)庫(kù)結(jié)合NoSQL作為數(shù)據(jù)存儲(chǔ)方式,如何選擇數(shù)據(jù)庫(kù)需要根據(jù)具體項(xiàng)目業(yè)務(wù)要求而定。通過(guò)MongoDB與MySQL作為兩種數(shù)據(jù)庫(kù)的代表,分析具體應(yīng)用場(chǎng)景與數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)原理。
關(guān)鍵詞:NoSQL;關(guān)系型數(shù)據(jù)庫(kù);MongoDB;MySQL;數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)
中圖分類號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2017)32-0005-02
1 概述
處在互聯(lián)網(wǎng)科技高速發(fā)展的今天,信息大爆炸時(shí)期。當(dāng)數(shù)據(jù)量過(guò)大,就需要一種新的數(shù)據(jù)存儲(chǔ)方式,這時(shí)候的關(guān)系型數(shù)據(jù)庫(kù)就顯得有些力不從心,這時(shí)可以使用NoSQL—非關(guān)系型數(shù)據(jù)庫(kù)。
關(guān)系型數(shù)據(jù)庫(kù)中的MySQL在市場(chǎng)中的占有率僅次于Oracle,并且呈上升的趨勢(shì)。MySQL數(shù)據(jù)庫(kù)在在系統(tǒng)的應(yīng)用中,和其他關(guān)系型數(shù)據(jù)庫(kù)(Relational DBMS)有著類似的SQL語(yǔ)句。同時(shí)MySQL在系統(tǒng)中數(shù)據(jù)的查詢也是比較快。通過(guò)創(chuàng)建MySQL的索引查找數(shù)據(jù),其本質(zhì)就是查詢B+樹上存儲(chǔ)的值。查詢效率也是很高的,但是在某些方面也會(huì)顯得短板明顯。
信息過(guò)剩時(shí)代有時(shí)關(guān)系型數(shù)據(jù)庫(kù)并不能很好地解決這些問(wèn)題,技術(shù)發(fā)展將會(huì)考慮使用與之對(duì)立的非關(guān)系型數(shù)據(jù)庫(kù)來(lái)彌補(bǔ)其中的不足。MongoDB是非關(guān)系型數(shù)據(jù)庫(kù)中的一種,其市場(chǎng)占有率已然到了前五。常用的非關(guān)系型數(shù)據(jù)庫(kù)也有Redis、Cassandra、HBase等。
MongoDB在某些方面可以彌補(bǔ)一些關(guān)系型數(shù)據(jù)庫(kù)的短板。MongoDB屬于NoSQL數(shù)據(jù)的一種,NoSQL可以為Web應(yīng)用數(shù)據(jù)的存儲(chǔ)提供關(guān)系型數(shù)據(jù)庫(kù)無(wú)法滿足的可擴(kuò)展、高性能的解決方案。同時(shí)NoSQL支持的數(shù)據(jù)結(jié)構(gòu)比較松散,內(nèi)部數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)使用類似JSON的數(shù)據(jù)存儲(chǔ)格式BSON(BinaryJSON),因此可以很好的彌補(bǔ)關(guān)系型數(shù)據(jù)庫(kù)的不足,存儲(chǔ)復(fù)雜類型數(shù)據(jù)。
MongoDB中數(shù)據(jù)索引使用B-Tree數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)。它并不是傳統(tǒng)的關(guān)系性數(shù)據(jù)庫(kù),而是以JSON格式作為存儲(chǔ)的NoSQL,目的就是高性能,高可用,易擴(kuò)展。
2 應(yīng)用場(chǎng)景
2.1 MongoDB
MongoDB作為NoSQL數(shù)據(jù)庫(kù)家族一員,具有NoSQL數(shù)據(jù)庫(kù)的特性和應(yīng)用價(jià)值。MongoDB內(nèi)部結(jié)構(gòu)使用了BSON存儲(chǔ)數(shù)據(jù),BSON同時(shí)也作為網(wǎng)絡(luò)數(shù)據(jù)交換的類型。BSON是schema-free類型,所以在MongoDB中文檔對(duì)應(yīng)也有此特征。MongoDB中一個(gè)文檔Document也類似于關(guān)系數(shù)據(jù)庫(kù)中的一條記錄(Record),但這Document的使用的數(shù)據(jù)類型、存儲(chǔ)方式更豐富,例如多個(gè)Document可以相互嵌套使用。
同時(shí)MongoDB擁有高可用、易擴(kuò)展性,使得以MongoDB為代表的NoSQL數(shù)據(jù)庫(kù)被廣泛應(yīng)用在游戲、物流、電商、內(nèi)容管理、社交、物聯(lián)網(wǎng)、視頻直播等。
2.2 MySQL
MySQL不同于MongoDB的文檔類型數(shù)據(jù)存儲(chǔ)格式,MySQL使用索引存儲(chǔ)數(shù)據(jù)。MySQL數(shù)據(jù)庫(kù)支持多種存儲(chǔ)引擎,不同存儲(chǔ)引擎對(duì)索引的支持也不相同。如全文索引、B-Tree索引、B+Tree索引和哈希索引等等。InnoDB與MyISAM存儲(chǔ)引擎在應(yīng)用中使用最為廣泛。其索引內(nèi)部數(shù)據(jù)結(jié)構(gòu)使用B-Tree和B+Tree。
MySQL是符合三范式的標(biāo)準(zhǔn)關(guān)系型數(shù)據(jù)庫(kù),支持事物。在傳統(tǒng)應(yīng)用領(lǐng)域有著得天獨(dú)厚的優(yōu)勢(shì)以及應(yīng)用的成熟度。最常見的應(yīng)用在Web網(wǎng)站、日志系統(tǒng)、數(shù)據(jù)倉(cāng)庫(kù)、嵌入式系統(tǒng)等。
3 內(nèi)部結(jié)構(gòu)
3.1 MongoDB內(nèi)部數(shù)據(jù)結(jié)構(gòu)
3.1.1 BSON(BinaryJSON)
在MongoDB中數(shù)據(jù)是以文檔Document的形式展現(xiàn),廣泛被應(yīng)用在服務(wù)器和客戶端的交互中。
BSON是一個(gè)輕量級(jí)且類似于JSON的二進(jìn)制數(shù)據(jù)存儲(chǔ)格式。MongoDB中的數(shù)據(jù)以BSON格式存儲(chǔ)在磁盤。
BSON數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)主要擁有以下幾個(gè)優(yōu)點(diǎn):(1)更快的遍歷速度;(2)操作簡(jiǎn)易;(3)數(shù)據(jù)字段、類型易于擴(kuò)展。
3.1.2 內(nèi)部結(jié)構(gòu)
一個(gè)集合命名空間中擁有多個(gè)數(shù)據(jù)域(extent),集合命名空間里存儲(chǔ)集合元數(shù)據(jù),比如集合名稱,第一個(gè)數(shù)據(jù)域和最后一個(gè)數(shù)據(jù)域的位置等等。而一個(gè)數(shù)據(jù)域由若干條文檔(document)組成,每個(gè)數(shù)據(jù)域都有一個(gè)頭部,記錄著第一條文檔和最后一條文檔的為知,以及該數(shù)據(jù)域的一些元數(shù)據(jù)。extent之間和document之間通過(guò)雙向鏈表連接。
索引的存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)是B-Tree,索引命名空間存儲(chǔ)著對(duì)B-Tree的根節(jié)點(diǎn)的指針。
3.2 MySQL內(nèi)部數(shù)據(jù)結(jié)構(gòu)
3.2.1 索引
從Oracle官網(wǎng)(MySQL官方)了解到,索引(Index)的使用目的就是為了更高效獲取數(shù)據(jù)。同時(shí)索引也是一種數(shù)據(jù)存儲(chǔ)的結(jié)構(gòu)。目前大多數(shù)文件系統(tǒng)和數(shù)據(jù)庫(kù)系統(tǒng)采用B-Tree或其變種B+Tree作為索引結(jié)構(gòu)。
特殊的查找算法也只能應(yīng)用于特定的數(shù)據(jù)結(jié)構(gòu)。二分查找算法要求被檢索數(shù)據(jù)是有序排列,但是二叉樹查找算法僅僅應(yīng)用于二叉查找樹結(jié)構(gòu),數(shù)據(jù)的組織結(jié)構(gòu)不可能完全滿足各種數(shù)據(jù)結(jié)構(gòu)。數(shù)據(jù)庫(kù)系統(tǒng)在存儲(chǔ)數(shù)據(jù)之外同時(shí)還維護(hù)著滿足特定查找算法的數(shù)據(jù)結(jié)構(gòu),為了能在這些數(shù)據(jù)結(jié)構(gòu)上實(shí)現(xiàn)高級(jí)快速的查找算法,數(shù)據(jù)結(jié)構(gòu)以某種最優(yōu)的方式引用數(shù)據(jù)。
3.2.2 B-Tree數(shù)據(jù)結(jié)構(gòu)endprint
B-Tree是一種多路搜索樹。 B- Tree從根結(jié)點(diǎn)開始搜索,二分查找結(jié)點(diǎn)的關(guān)鍵詞序列。命中則結(jié)束查找,否則查找關(guān)鍵詞所屬子結(jié)點(diǎn);重復(fù)上述操作,直到所對(duì)應(yīng)的子節(jié)點(diǎn)指針為空,或遍歷找到葉子結(jié)點(diǎn)。
由于B-Tree數(shù)據(jù)存儲(chǔ)特性,所以在B-Tree中按key檢索數(shù)據(jù)的查找算法很直觀。B-Tree上查找算法的偽代碼如下:
BT_Search(btNode, btKey){
if(btNode ==null){
returnnull;}
foreach(btNode. btKey){
if(btNode.btKey[i]> btKey) {
returnBT_Search(point[i]-> btNode, btNode.btKey [i]);
}if(btNode.btKey[i]== btKey){
return btNode.data[i];
}}returnBT_Search(point[i+1]-> btNode);
}data =BT_Search(btRoot, targetKey);
3.2.3 B+Tree數(shù)據(jù)結(jié)構(gòu)
B+ Tree是 B- Tree的變體,也是一種多路搜索數(shù)據(jù)結(jié)構(gòu)。B+ Tree搜索與 B- Tree搜索類似, B+ Tree由于數(shù)據(jù)全部存儲(chǔ)在葉子節(jié)點(diǎn),所以只會(huì)在葉子節(jié)點(diǎn)命中查找(B- Tree屬于可以存儲(chǔ)在非葉子節(jié)點(diǎn)),B+Tree數(shù)據(jù)結(jié)構(gòu)查找等價(jià)于對(duì)關(guān)鍵詞的全集做二分查找。
B+Tree中并非所有節(jié)點(diǎn)具有相同的域,所以葉子節(jié)點(diǎn)與非葉子節(jié)點(diǎn)大小一般不同。這與B-Tree數(shù)據(jù)結(jié)構(gòu)有很大的差別。B-Tree中雖然不同節(jié)點(diǎn)存放的key和指針數(shù)量可能不一致,但每個(gè)節(jié)點(diǎn)的域和上限是一致的,所以B-Tree遍歷中為每個(gè)節(jié)點(diǎn)申請(qǐng)的空間大小相同。
3.2.4 索引內(nèi)部實(shí)現(xiàn)
MySQL索引屬于存儲(chǔ)引擎級(jí)別。由于不同數(shù)據(jù)存儲(chǔ)引擎對(duì)索引的實(shí)現(xiàn)方式也不相同,在實(shí)際工作中最常用的數(shù)據(jù)存儲(chǔ)引擎就是MyISAM和InnoDB。
B+Tree索引結(jié)構(gòu)使用在MyISAM數(shù)據(jù)存儲(chǔ)引擎中,葉子節(jié)點(diǎn)的data域存放的是數(shù)據(jù)記錄的地址。
InnoDB數(shù)據(jù)存儲(chǔ)引擎使用B+Tree索引結(jié)構(gòu),但具體實(shí)現(xiàn)方式與MyISAM存儲(chǔ)引擎完全不同。索引文件和數(shù)據(jù)文件在MyISAM存儲(chǔ)引擎中是相互分離的,索引文件僅僅保存數(shù)據(jù)記錄的地址。然而在InnoDB存儲(chǔ)引擎中,表數(shù)據(jù)文件就是B+Tree的一個(gè)索引結(jié)構(gòu),完整的數(shù)據(jù)記錄保存在樹的葉子節(jié)點(diǎn)data域中。索引的key是數(shù)據(jù)表的主鍵,因此InnoDB存儲(chǔ)引擎中主索引就是數(shù)據(jù)文件本身。
4 總結(jié)
本文通過(guò)分析以MongoDB為代表的NoSQL與MySQL代表的關(guān)系型數(shù)據(jù)庫(kù)的對(duì)比中學(xué)習(xí)到了很多日常工作中很少留意的數(shù)據(jù)存儲(chǔ)知識(shí)點(diǎn)。
在實(shí)際的開發(fā)工作中選取數(shù)據(jù)庫(kù)不能執(zhí)著地選取某一種,必須要根據(jù)實(shí)際的業(yè)務(wù)需求選取數(shù)據(jù)庫(kù),也可能是兩者結(jié)合使用。實(shí)際開發(fā)工作一切都需要以業(yè)務(wù)和需求作為驅(qū)動(dòng)選取開發(fā)工具、語(yǔ)言、框架以及數(shù)據(jù)庫(kù)。
同時(shí)總結(jié)MongoDB數(shù)據(jù)存儲(chǔ)的松散性和MySQL內(nèi)部數(shù)據(jù)存儲(chǔ)結(jié)構(gòu),學(xué)習(xí)到了B-Tree與B+Tree之間的差別。了解數(shù)據(jù)庫(kù)內(nèi)部具體數(shù)據(jù)結(jié)構(gòu)對(duì)今后的開發(fā)工作很有幫助。
參考文獻(xiàn):
[1] 姜承堯.MySQL技術(shù)內(nèi)幕-InnoDB存儲(chǔ)引擎[M].機(jī)械工業(yè)出版社,2011.
[2] 簡(jiǎn)朝陽(yáng).MySQL性能調(diào)優(yōu)與性能設(shè)計(jì)[M].電子工業(yè)出版社,2009.
[3] 霍多羅夫.MongoDB權(quán)威指南[M].2版.人民郵電出版社,2014.
[4] 吉瑛.基于MongoDB的團(tuán)隊(duì)協(xié)作數(shù)據(jù)存儲(chǔ)方案研究與實(shí)現(xiàn)[D].中國(guó)科學(xué)院大學(xué),2015.
[5] Thomas H Cormen.Introduction to Algorithms, Third Edition[M].機(jī)械工業(yè)出版社,2013.endprint