任明飛 李學(xué)軍 崔蒙蒙 楊雙龍 孫小奇
摘要:隨著社會的發(fā)展和軟件技術(shù)的不斷進(jìn)步,互聯(lián)網(wǎng)的數(shù)據(jù)量也呈現(xiàn)出爆炸型增長,此外數(shù)據(jù)的類型也變得更加多樣,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫在對海量級的數(shù)據(jù)和多種類型的非結(jié)構(gòu)化數(shù)據(jù)的處理上已經(jīng)無法滿足開發(fā)人員的需求,NoSQL即非關(guān)系型數(shù)據(jù)庫憑借本身的優(yōu)勢得到了迅速發(fā)展,其中MongoDB就是一個基于分布式,文件存儲的NoSQL數(shù)據(jù)庫。該項(xiàng)目通過基于MongoDB的非關(guān)系型數(shù)據(jù)庫的設(shè)計與開發(fā),展示了非關(guān)系型數(shù)據(jù)庫和傳統(tǒng)的關(guān)系型數(shù)據(jù)庫的區(qū)別以及MongoDB的主要技術(shù)和使用方式。
關(guān)鍵詞:關(guān)系型數(shù)據(jù)庫;非關(guān)系型數(shù)據(jù)庫;MongoDB;分布式;文件存儲
中圖分類號:TP311
文獻(xiàn)標(biāo)識碼:A
文章編號:1009-3044(2019)34-0001-02
1 MongoDB概述
MongoDB是一個基于分布式,文件存儲的非關(guān)系型數(shù)據(jù)庫,其特點(diǎn)是高性能、易部署、易使用,存儲數(shù)據(jù)方便。 不同于傳統(tǒng)關(guān)系型數(shù)據(jù)庫將數(shù)據(jù)以表的形式進(jìn)行存儲,在MongoDB中數(shù)據(jù)是以文檔的形式進(jìn)行存儲。文檔為BSON格式,其內(nèi)部可以包含多種類型的文件、數(shù)據(jù)也可以內(nèi)嵌別的文檔,模式十分白由。MongoDB也被稱作非關(guān)系型數(shù)據(jù)庫當(dāng)中最像關(guān)系數(shù)據(jù)庫的,是一個介于關(guān)系數(shù)據(jù)庫和非關(guān)系數(shù)據(jù)庫之間的產(chǎn)品,其功能也是眾多非關(guān)系數(shù)據(jù)庫當(dāng)中最豐富的。
MongoDB在存儲上的高拓展性使得其在面對海量級數(shù)據(jù)時比其他的數(shù)據(jù)庫更加具備優(yōu)勢,其數(shù)據(jù)模型自由可變,存儲內(nèi)容可按照需求隨意拓展,所以也適用于一些新應(yīng)用,需求容易改變,數(shù)據(jù)模型無法確定,或者想快速迭代開發(fā)的產(chǎn)品。由于其高效的實(shí)時插入、更新與查詢性能,并具備網(wǎng)站實(shí)時數(shù)據(jù)存儲所需的復(fù)制及高度伸縮性。因此適用于常見的游戲場景、物流場景和物聯(lián)網(wǎng)場景等。
MongoDB作為一個非關(guān)系型數(shù)據(jù)庫也有一些局限性。MongoDB事務(wù)僅支持限于本機(jī)的單文檔事務(wù),某些需要參與遠(yuǎn)程事務(wù),或者需要跨表,跨文檔原子性更新的高事務(wù)性應(yīng)用不建議使用,另外MongoDB目前并不支持jom操作,需要復(fù)雜查詢的應(yīng)用也不建議使用。
2 MongoDB文檔模式設(shè)計
MongoDB的文檔數(shù)據(jù)以BSON(JSON格式的一種拓展)格式存儲,可以存儲列表、key-value以及層次結(jié)構(gòu)更加復(fù)雜的文檔。由于文檔存儲的靈活性和復(fù)雜性導(dǎo)致開發(fā)者在自由組織文檔結(jié)構(gòu)的同時必然會面對應(yīng)用層查詢困難的問題,因此基于Mon-goDB的非關(guān)系型數(shù)據(jù)庫在設(shè)計階段對文檔模式的設(shè)計尤為重要。
2.1 數(shù)據(jù)對象分析
本次開發(fā)的實(shí)例項(xiàng)目為旅游類內(nèi)容管理網(wǎng)站項(xiàng)目,主要涉及的數(shù)據(jù)對象有景點(diǎn)數(shù)據(jù)對象,評論數(shù)據(jù)對象以及旅游攻略數(shù)據(jù)對象。
景點(diǎn)數(shù)據(jù)對象包含景點(diǎn)的圖文介紹,基本信息,位置信息,評論等。旅游攻略數(shù)據(jù)對象包含旅游攻略的發(fā)布者信息,內(nèi)容信息,點(diǎn)贊評論或者轉(zhuǎn)發(fā)信息等。評論數(shù)據(jù)對象包含評論者信息,內(nèi)容信息和點(diǎn)贊信息等。
結(jié)合實(shí)際應(yīng)用場景分析,每個景點(diǎn)都有各自的基本信息以及游客們的評論信息,一個景點(diǎn)可以有多條評論,因此景點(diǎn)數(shù)據(jù)對象和評論數(shù)據(jù)對象之間是一對多的關(guān)系,其他同理可得數(shù)據(jù)對象關(guān)系如圖1所示。
2.2 關(guān)系模型和文檔模型對比
結(jié)合項(xiàng)目中主要的數(shù)據(jù)對象進(jìn)行分析。從數(shù)據(jù)存儲的角度來講:
關(guān)系型數(shù)據(jù)庫在設(shè)計時必須滿足范式的要求,即關(guān)系型數(shù)據(jù)庫在定義表結(jié)構(gòu)時要求每一個單元格的數(shù)據(jù)必須為不可再分割的原子項(xiàng)。使用關(guān)系型數(shù)據(jù)庫對旅游攻略數(shù)據(jù)對象進(jìn)行存儲至少需要建立四張表。分別是文章表、評論表、點(diǎn)贊表、附件表,其中評論表、點(diǎn)贊表和附件表都持有文章表主鍵。形成主外鍵關(guān)系。顯然,數(shù)據(jù)更加復(fù)雜的景點(diǎn)數(shù)據(jù)對象以及數(shù)量龐大的評論數(shù)據(jù)對象都不是一張表就可以實(shí)現(xiàn)存儲的。并且這些數(shù)據(jù)模型各自之間還存在對應(yīng)關(guān)系,也需要使用外鍵進(jìn)行關(guān)聯(lián)。關(guān)系型數(shù)據(jù)庫光是在數(shù)據(jù)的存儲上就十分困難。
集合就是MongoDB文檔組,其文檔下的屬性可以是一個數(shù)據(jù)項(xiàng)、一個對象或者是一個數(shù)組。在使用MongoDB處理旅游攻略數(shù)據(jù)對象時,只需要一個旅游攻略數(shù)據(jù)對象的文檔集合就可以,文檔內(nèi)部包括,文章內(nèi)容屬性,文章發(fā)表時間屬性,文件狀態(tài)屬性,評論數(shù)組屬性,點(diǎn)贊數(shù)組屬性,文章附件數(shù)組屬性等其他信息。對于其他數(shù)據(jù)對象可以采取相同操作,文檔包含的都是以bson格式存儲的不同數(shù)據(jù)對象,由于bson數(shù)據(jù)便于解析,而且可以存儲多種類型的數(shù)據(jù)內(nèi)容,使得MongoDB的存儲效率極高。
從應(yīng)用層面來講:對需求進(jìn)行提升,需要在文章列表中就展示文章內(nèi)容、評論、附件和點(diǎn)贊信息。使用關(guān)系型數(shù)據(jù)庫就需要先從文章表中查詢出文章列表,再根據(jù)每一個文章的主鍵到其他表中獲取信息。如果列表要求顯示10條記錄,就需要執(zhí)行11次的sql語句。而在這樣的需求下,mongoDB仍然是只需要執(zhí)行一次查詢就可以獲取到全部數(shù)據(jù)。
2.3 文檔模式設(shè)計
MongoDB可以將模式設(shè)計劃分為內(nèi)嵌模式(Embedded)和引用模式(References)。
內(nèi)嵌模式適合數(shù)據(jù)對象之間的關(guān)系是一對一或一對多的。但其局限性在于MongoDB的文檔最大16M,面對大數(shù)組性能欠佳。在開發(fā)過程中,如果數(shù)據(jù)對象模型數(shù)量不多,關(guān)系結(jié)構(gòu)不復(fù)雜。這種情況下選擇內(nèi)嵌模式,可能一種對象只需要對應(yīng)一個集合即可。由于內(nèi)嵌模式的局限性。內(nèi)嵌的數(shù)組過大時,例如一個明星的博客可能有幾十萬或者幾百萬的回復(fù),這個時候如果把回復(fù)內(nèi)容放到一個數(shù)組里,可能會超出16M的限制。這個時候就應(yīng)該考慮使用引用方式。
引用模式適合多對多的關(guān)系,并且兩個對象都是主要對象。它的局限性在于查詢和寫入數(shù)據(jù)需要多次查詢、寫入,并且不支持跨表事務(wù)性。實(shí)現(xiàn)方式是不同的數(shù)據(jù)對象建立兩個集合,通過在集合中存儲其他對象的ID值實(shí)現(xiàn)關(guān)聯(lián),這種方式和關(guān)系型數(shù)據(jù)庫十分相似,從查詢操上講,可能需要兩次以上才能把需要的數(shù)據(jù)取回來。另外現(xiàn)階段MongoDB并不支持跨表的事務(wù)性,所以對于強(qiáng)事務(wù)的應(yīng)用場景應(yīng)當(dāng)慎用引用模式。
開發(fā)過程中完全依靠數(shù)據(jù)對象關(guān)系并不能完美解決選擇內(nèi)嵌還是引用的問題,在這些時候就需要了解MongoDB的文檔模式設(shè)計的設(shè)計原則:MongoDB的設(shè)計是為應(yīng)用程序服務(wù),而并非為了存儲的優(yōu)化。設(shè)計MongoDB的目的是為了實(shí)現(xiàn)應(yīng)用程序的最佳性能。這些和關(guān)系型數(shù)據(jù)庫設(shè)計的原則有很大不同,為了達(dá)到性能的優(yōu)化可能需要去做一些反范式的內(nèi)容。因此MongoDB文檔設(shè)計模式的選擇除了考慮數(shù)據(jù)本身的特點(diǎn)之外還應(yīng)當(dāng)考慮應(yīng)用層面對數(shù)據(jù)的操作。
3 MongoDB文檔模式實(shí)現(xiàn)
通過上文的分析,對項(xiàng)目中的數(shù)據(jù)對象進(jìn)行文檔設(shè)計和實(shí)現(xiàn),景點(diǎn)數(shù)據(jù)對象由于自身結(jié)構(gòu)復(fù)雜,內(nèi)容圖片以及附加信息過多,自身數(shù)據(jù)大小遠(yuǎn)大于評論數(shù)據(jù)對象和旅游攻略數(shù)據(jù)對象,因此在景點(diǎn)數(shù)據(jù)對象和其他兩個數(shù)據(jù)對象之間的模式選擇引用模式,兩種數(shù)據(jù)之間的聯(lián)系則通過數(shù)據(jù)對象中的標(biāo)識ID進(jìn)行聯(lián)系。旅游攻略數(shù)據(jù)對象和評論數(shù)據(jù)對象之間選擇的是內(nèi)嵌模式。由于采用引用模式的文檔模型在邏輯上和關(guān)系型數(shù)據(jù)庫十分相似,本文不再贅述,主要分析使用內(nèi)嵌模式的旅游攻略數(shù)據(jù)對象的文檔模式實(shí)現(xiàn)。
對數(shù)據(jù)文檔模式的設(shè)計和實(shí)現(xiàn)時應(yīng)當(dāng)結(jié)合數(shù)據(jù)自身特點(diǎn)和其在應(yīng)用層面的操作共同考慮。分析實(shí)際應(yīng)用場景中旅游攻略展示的效果除了文章本身的內(nèi)容,還應(yīng)當(dāng)包含點(diǎn)贊列表。點(diǎn)贊用戶的頭像、昵稱;以及評論列表,評論內(nèi)容,評論用戶的頭像、呢稱等。結(jié)合上文,對旅游攻略數(shù)據(jù)對象和評論點(diǎn)贊數(shù)據(jù)對象之間采取的是內(nèi)嵌模式。故而我們在文檔設(shè)計模式上首先構(gòu)建了旅游攻略數(shù)據(jù)對象,在旅游攻略數(shù)據(jù)對象內(nèi)部嵌套了多個包含評論內(nèi)容,用戶以及圖片文字等信息的評論數(shù)據(jù)對象。
對以上文檔模型進(jìn)行分析,該文檔設(shè)計模式中在景點(diǎn)對象內(nèi)嵌了所有的點(diǎn)贊對象和評論對象,結(jié)合需求分析同時也需要在用戶對象中內(nèi)嵌相應(yīng)的評論和點(diǎn)贊對象,在MongoDB這種文檔型數(shù)據(jù)庫選擇這種設(shè)計是沒有必要的,反而造成了大量的數(shù)據(jù)冗余。另一個問題是在上述的設(shè)計里存儲用戶評論內(nèi)容的圖片或者頭像等URL也占據(jù)了大量的空間,實(shí)際情況是,評論用戶數(shù)據(jù)的URL相對來說是全局穩(wěn)定的,基本不會發(fā)生變化。
根據(jù)以上幾個問題,我們重新優(yōu)化了文檔模型的設(shè)計,在對象內(nèi)部嵌套comment_obj_id與praise_obj_idj兩個字段,用以存儲兩個對象的id。文檔數(shù)據(jù)內(nèi)部的URL、username信息全部移除,因?yàn)閷π枨筮M(jìn)行分析可以發(fā)現(xiàn),業(yè)務(wù)抽象上來說URL、username這類信息實(shí)際上是非常穩(wěn)定的,不會發(fā)生特別大的頻繁變化。并且這兩類信息實(shí)際上都應(yīng)該是跟uid綁定的,每個uid含有指定的URL.username。是最簡單的keV-value模型。所以,這類信息可以通過一層緩存加速讀取查詢。
對比可以發(fā)現(xiàn),優(yōu)化后的結(jié)構(gòu)要比優(yōu)化前小了幾個數(shù)量級。雖然兩者都滿足MongoDB文檔模式設(shè)計的要求規(guī)范,但是后者在存儲空間占用以及查詢的性能上都遠(yuǎn)優(yōu)于前者。
4 總結(jié)
通過本次MongoDB數(shù)據(jù)庫的設(shè)計與開發(fā),體現(xiàn)了MongoDB在數(shù)據(jù)存儲,檢索上的強(qiáng)大優(yōu)勢,以及MongoDB在復(fù)雜數(shù)據(jù)以及海量數(shù)據(jù)存儲方面遠(yuǎn)超傳統(tǒng)關(guān)系型數(shù)據(jù)庫的優(yōu)異性能。MongoDB的文檔模型設(shè)計自由,但絕對不是等同于關(guān)系型數(shù)據(jù)庫的粗暴聚合,并且當(dāng)前的MongoDB還存在一定的局限性,因此在設(shè)計階段,還需要結(jié)合實(shí)際需求和業(yè)務(wù),進(jìn)行合理的設(shè)計。
參考文獻(xiàn):
[1] Peter Bakkum(美).MongoDB實(shí)戰(zhàn)[M].徐雷,譯.華中科技大學(xué)出版社,2017.
[2] KristinaChodorow(美)等.MongoDB權(quán)威指南[M].程顯峰,譯.人民郵電出版社,2011.
[3]王光磊.MongoDB數(shù)據(jù)庫的應(yīng)用研究和方案優(yōu)化[J].中國科技信息,2011.
【通聯(lián)編輯:代影】
收稿日期:2019-08-28
作者簡介:任明飛(1996-),男,河南焦作人,河南科技大學(xué)本科在讀,研究方向?yàn)榉顷P(guān)系型數(shù)據(jù)庫、數(shù)據(jù)庫分布式部署。