再說一次,MongoDB不是「萬能藥」,請別亂用!

程序員的成長之路

互聯網/程序員/技術/資料共享 

關注

閱讀本文大概需要 3 分鐘。

作者:挨踢直男

來源:http://suo.im/6xYQqy

mongodb是一種非關係數據庫,最常見的作用是在某些領域作爲關係數據庫的替代品,相較於關係數據庫它在性能上更有優勢,因爲不對事務以及數據完整性有硬性要求,所以在寫入數據時效率更高。

同時,mongdb的數據存儲結構也比較靈活,只要是一個json結構就可以存儲,相較於關係數據庫的表結構定義,更加快捷方便。因爲這些優勢,mongodb迅速崛起,不斷蠶食關係數據庫從上個世紀就開始積累的市場份額。

關係數據庫存儲數據很規則,必須是表格的形式,且表格的結構需要事先定義好,每個字段的數據類型、長度需要明確,這樣做的好處是表內的一切都井井有條、很清晰,壞處就是很繁瑣。

而mongodb則相反,它對集合的結構沒有統一的要求,任何結構的文檔數據都可以寫入同一個集合,在一個集合裏,既可以寫入用戶數據,也可以寫入訂單數據,mongodb本身不做任何限制,一切約束全靠程序員自身。

mongodb的這種隨意性是把雙刃劍,能帶來高效,也能造成災難。

尤其當項目涉及的開發人員越多,需求變化越頻繁,mongodb存儲的數據就越容易變成一個屎坑,你無法完全知道某一個集合中的文檔哪些字段是有用的,哪些字段是沒用的,你的程序不得不去配合這些未知的數據,從而造成不必要的繁瑣,以及帶來更多的BUG。

曾經經歷過一個項目,數據庫採用的是mongodb,在我接手時這個項目已經開發運營了三年。

那時,我需要理清楚某一個功能運行邏輯,最好的方法自然是先弄清楚功能相關聯的數據結構,於是我找到了那個功能依賴的mongodb集合,查看集合文檔的結構。

瞭解了文檔結構之後,我修改了程序,完成了任務。

然而修改後的功能總過會在某種情況下觸發一個BUG,經過排查後發現,我之前看到的數據結構並不全面,在集合中某一批文檔中還有別的字段被程序所依賴,找到問題後我修好了BUG。

然而在之後某些情況下程序仍舊會出現BUG,排查後找到的原因也是類似之前,總之這種狀態周而復始了好久才徹底修完了BUG。

這就是之前的程序員對mongodb對數據結構約束性不強這以特性濫用的結果。如果是關係數據庫,查看錶結構就能清楚所有的數據字段,很多BUG也就可以提前避免。

要寫出健壯且易於理解的程序,數據的存取必須是有模式的,比如關係數據庫的表結構。然而關係數據庫太過於死板,只能存儲二維的表數據結構,雖然現代的關係數據庫對json和xml做了很好的支持,但是並沒有被廣泛使用,大多數時候只是使用基本的表功能。

要兼顧靈活性和健壯性兩種優點,那麼我們只能引入外部模式。

有兩種結構化數據協議很流行,一種是google開發的protobuf協議,一種是facebook開發的apache thrift協議。這兩種技術功能很強大,應用範圍也很廣,要講清楚需要花費非常巨大的篇幅,讀者可自行去網上了解。

這兩種協議有一個核心的功能就是數據結構的描述,以可以直接寫入mongodb的JSON以及php語言爲例,有一個php數組,裏面是需要存到數據庫裏的數據,我們將這個數組轉換成JSON ,然後存入mongodb,這一步一般是mongodb提供的驅動庫完成,這種方式我們很難約束數組的內容,自然的也難以約束轉化成存入mongodb中JSON的內容,從而導致最終的失控。

使用這兩種技術之後,一切變得可控了,數據協議會生成對應語言的類結構,然後通過他們內置的庫序列化成JSON並存入mongodb。

反過來,程序讀取是mongodb中的json,反序列化成語言的類結構供程序使用,字段的語義說明則都由協議定義接管。

總而言之,mongodb不建議像關係數據庫那樣獨立使用,必須引入外部的模式定義,才能發揮作用同時避免副作用。


別忘記點個在看,咱們下篇見

每天進步一點點
慢一點才能更快

<END>

推薦閱讀:

再見,Navicat!

說實話,去一家小公司從 0 到 1 搭建後端架構,真難~

5T技術資源大放送!包括但不限於:C/C++,Linux,Python,Java,PHP,人工智能,單片機,樹莓派,等等。在公衆號內回覆「2048」,即可免費獲取!!

微信掃描二維碼,關注我的公衆號

朕已閱