論:MongoDB的好壞丑
對剛剛接觸 MongoDB 的人來說, MongoDB就是一個NoSQL類型的文檔數據庫. 文檔中包含的鍵值對,構成了MongoDB的數據基本單位。
不過可以肯定的是MongoDB的確是當前***的NoSQL數據庫. 它已被廣泛接受并且適合各種各樣的場合 (盡管不是所有項目都使用它)。
這篇文章中,我將根據過去幾年來我使用MongoDB所得出的經驗,簡短的介紹下MongoDB的好處、壞處和它丑陋的地方。
好處
自 MongoDB 流行以來,它的好處應該多于壞處和丑陋的地方. 如若不是,開發者們也不會接受它. 下面是一些MongoDB好的方面。
靈活的數據模型
當今動態的用戶案例以及不斷變化的應用,擁有一個靈活的數據模型是一種福音。靈活的數據模型意味著沒有預先定義的模式,文檔可以基于任何鍵值持有任何值的集合。
富有表現力的查詢語法
MongoDB的查詢語句是非常具有表現力且易于理解的。許多人會說這不像SQL語句。但是當我們能向前發展,且查詢語句更簡單并具表現力的時候,為什么我們還要堅持類似SQL的查詢語句呢?
容易學習
MongoDB很容易學習,并且能快速上手。基本的安裝、執行不會超過幾個小時。 更強大的設置可能是復雜的,但是我會晚點再談論這方面。
根據上面這些特點想必你應該很容易把它揉進你的項目中。
性能
查詢性能是MongoDB的長處. 它把大多數可操作的數據存儲在內存中. 所有的數據是固化在硬盤中的, 但在查詢過程中, 它不會從硬盤中過去數據(那樣太慢). 它直接從本地內存中獲取數據,因此速度就會更快. 所以,為數據設置正確的索引并且提供足夠的內存便能發揮MongoDB的性能優勢。
可伸縮性和可靠性
MongoDB 具有很高的可伸縮性, 在碎片數據使用方面. 橫向可伸縮性在大多數NoSQL數據庫中是一大亮點. MongoDB 也不例外。
它也是高度可靠的,因為它的副本集數據被異步的復制到更多的節點。
異步驅動
對于所有的現代應用程序而言使用異步的非阻塞IO是提速的關鍵。MongoDB異步驅動程序支持***的語言。
文檔
擁有一個良好的文檔可以讓開發人員的生活變得容易很多,特別是當開發人員面對的是新技術。MongoDB有出色的文檔。
文本搜索
如果你正在建設一個網站, 需要搜索您的所有數據,文本搜索是必不可少的。例如,一個使用具有文本搜索的數據庫的電子商務網站對用戶來說更有利。
服務端腳本
如果你有一些操作需要在服務端而不是應用端執行,在MongoDB中,你可以那么做。把mongo語句放在一個.js文件中,并用mongo命令執行js文件。
文檔 = 對象
文檔數據庫的優點是對象可以在MongoDB中存儲為一個單獨的文檔。 這邊不需要對象關系映射(ORM)。
缺點
我們已經看到了有關MongoDB的各種優點,接下來要說下缺點了。我敢肯定批評家對這部分更感興趣。如果使用不當,MongoDB可能會做壞事。
現今,實際上很少有應用程序需要事務,但是有一些程序還是需要的。不幸的是, MongoDB不支持事務。因此當一個請求中需要修改多個文檔或多個集合時就不要使用MongoDB。由于沒有ACID保證它可能會導致數據損壞。回滾操作必須由你的應用程序來處理。
沒有觸發器
在關系式數據庫中,有觸發器,在很多情況下它是十分有用的。但是在MongoDB中就沒這個了。
存儲
相比其他流行的數據庫MongoDB需要更多的存儲。 在 MongoDB 3.0中引入的WiredTiger解決了這個問題,但是對于大多數應用程序來說使用WiredTiger不甚理想。
磁盤清理
MongoDB不會自動清理磁盤空間。因此如果文檔被修改了或刪除了,磁盤空間不會被釋放。你必須通過手動或重啟來釋放。
丑陋的
有時,丑陋可能比壞更糟糕。使用一項技術之前了解它的不足是很重要的。它不會阻止你使用它,但它可以讓你的活的非常艱難。
層次結構
如果你有一個是遞歸包含孩子數據對象的數據模型 (如, 一個對象擁有與它相同數據類型的孩子對象并且層級很多), MongoDB的文檔結構就會變得非常丑陋。對這些遞歸嵌入的文檔進行索引、搜索和排序將非常困難。
Join(連接)
MongoDB中join兩個文檔是不容易的,雖然MongoDB 3.2支持左外連接 (lookup), 但它尚未成熟。如果你的應用程序需要在一個查詢中實現獲取多個集合中的數據,那可能無法實現。因此你必須使多個查詢,這可能會讓你的代碼看起來有點亂。
索引
雖然MongoDB標榜速度是它的一大亮點,但它依賴于你建立了正確的索引。如果你建立的索引很糟糕或不正確順序的復合索引,那么 MongoDB可能是最慢的數據庫。
如果你有很多的過濾條件和排序字段,你可能會在一個集合上建立很多的索引,當然這是不好的一個做法。
重復數據
你可能會有大量重復的數據,MongoDB不支持關系式。修改這些重復數據可能會比較困難,且由于缺少事務支持,我們還可能會損壞數據。
結論
綜述,只要你恰當的使用,MongoDB是一個優秀的數據庫,否則它會給你帶來麻煩。在不恰當的地方使用它你將會吃到苦頭。
認真的分析以及咨詢專家。正確的使用你絕對會愛上它。
至于壞的和丑陋的部分,你可以一些使用設計模式來解決其中的一些問題,在我的文章解釋了 MongoDB設計模式。
MongoDB的***實踐
下面列出了幾個MongoDB的***實踐:
硬件
- 確保你的數據集能放入內存中
使用壓縮
- 每臺服務器運行單個MongoDB
- 對于寫入數據較多的應用使用固態硬盤
數據模型
- 一條記錄的所有數據都存在一個文檔中
- 避免大尺寸的文檔
- 避免不必要的長字段名
- 去掉不必要的索引
- 刪除其它索引前綴的索引
應用程序
- 只修改變化的字段
- 避免否定式查詢
- 對于復雜的查詢運行explain()(查看執行計劃)
- 在可能的情況下使用覆蓋查詢.
- 在需要的時候使用批量插入.
安裝和配置
- 擁有至少一個從庫和一個仲裁
- 當數據非常重要時應設置參數 write concern 為2
- 有每日的數據轉儲備份。