為什麼你應該永遠不要再使用MongoDB
Sven Slootweg (joepie91)是一名黑客,同時也是CrytoCC的建立者,現在提供Node.js程式碼評審服務。近日,他在個人部落格上發表了一篇博文《為什麼你應該永遠、永遠、永遠不要再使用MongoDB》。在文中,他列舉了如下理由:
- 丟失資料(見1、2);
- 預設忽略錯誤,假設每次寫入都是成功的,在32位系統上,這可能會導致資料無聲無息地丟失;
- 即使是在MongoDB宣傳的適用場景下,其效能依然不高(見3、4);
- 幾乎在所有的應用場景下,開發者都會被迫養成使用隱式模式的壞習慣(見4);
- 存在鎖問題(見4);
- 對安全問題響應很慢(見5);
- 不符合ACID(見6);
- 擴充套件和維護困難;
- JSON儲存也不是MongoDB獨有的功能,PostgreSQL、CouchDB也支援(見7、8)。
joepie91認為,MongoDB不僅存在諸多問題,而且並無突出之處。如果專案涉及使用者賬戶或者兩條記錄之間存在某種關係,那麼就應該使用關係型資料庫,而不是文件儲存;如果專案在使用Mongoose,那麼也應該使用關係型資料庫,因為Mongoose只是使用文件儲存模擬了有模式的關係型資料庫。因此,大多數情況實際上需要的都是一個關係型資料庫。在這些情況下,PostgreSQL是個不錯的可選方案。開發者可以使用查詢構建器或ORM來簡化使用過程,比如,在Node.js中,可以選用Knex、Bookshelf、Sequelize或Waterline。即使真得需要一個文件儲存,那麼也有比MongoDB更好的選項。另外,他也不認為MongoDB適合於建立原型,因為如果生產環境使用不同的資料庫,則還需要重寫所有的程式碼。總之,MongoDB並沒有什麼適用場景。它在技術上比不上其它可選方案,並沒有提供真正有用的獨有的特性,而且開發人員也無法確保資料一致性和安全。最後,joepie91指出,流行度並不等同於質量,只能說明產品有一個不錯的市場團隊:
永遠不要因為“其他人那樣做”就使用一個資料庫,對於一個特定的資料庫,要自己研究它的優點和不足。
joepie91的觀點在Hack News上得到了廣泛的贊同。網友karmakaze也認為,有了PostgreSQL 9.4,就沒有任何理由要使用MongoDB了(JSONB比BSON更合用),另外還可以使用CouchDB。對於MongoDB的具體限制,網友giaour建議閱讀aphyr的系列文章Call Me Maybe,並指出,雖然存在已知的變通方案,但那大大降低了MongoDB的開發體驗。網友Animats認為,如果站點的流量比維基小,那麼使用某種關係型資料庫就可以了。網友PebblesHD有類似的觀點:
作為一個規模較小的部署……,只安裝一個基本的MySQL有什麼問題嗎?在我們的內部維基上,我們每天的訪問量已經超過了2萬次……
但是也有一些不同的聲音。例如,網友threeseed就表示,MongoDB仍然是最容易安裝和使用的資料庫之一。對此,joepie91回覆如下:
以錯誤的方式做事,想不容易都難——MongoDB恰好就是那麼做的。它不需要設定身份驗證或表模式,因此才看上去“易於安裝”。但實際上,為了節省10分鐘,你正在浪費幾個小時的時間。因為稍後,你將會遇到入侵(沒有身份驗證)或資料破壞……
Shodan的報導也佐證了joepie91的這一說法,網際網路上有將近3萬個MongoDB例項沒有啟用任何的身份驗證。這個問題隨處可見,而且已經存在多年。
網友toyg則評論說:
我最近首次使用了MongoDB,是在一個內部專案裡。我認為,沒有模式確實顯著了提升了開發速度……現在專案已經成熟,回過頭來,我可以看到為什麼關係型資料庫會更合適,但如果我從開始就使用RDBMS,那麼我可能無法這麼快地完成遷移。雖然切換到真正的RDBMS意味著要修改三兩個類,但變化不大。所以,我不同意MongoDB不適合原型開發的說法。
joepie91對“修改三兩個類,但變化不大”的說法提出了質疑,因為根據自己從事程式碼審查的經驗,遷移到不同的資料庫通常需要大量的工作。至於切換速度,joepie91指出,在一個有回滾機制的系統中,可能會更快。
然而,在有些情況下,開發者並沒有其它選擇。例如,有網友就提出,Meteor就使用而且只能使用MongoDB。而由於同Hadoop的合作伙伴關係,MongoDB同Hadoop有很好的整合,因此,它在大資料分析領域非常流行。
另外,來自SourceGear的軟體開發人員Eric Sink在讀過的joepie91文章之後表示:
(他所列舉的內容)部分(也許全部)確有其事。事實上,現在,就假設他所寫的都是正確的。我這裡不是要說作者是錯的。更確切地說,我這裡想指出的是,這種博文只能讓我瞭解很少有關MongoDB的知識,但卻讓我感受到了寫這篇博文的人的許多情感。
他覺得,不能因為那些問題就徹底地否定MongoDB,畢竟:
MongoDB是頂級的NoSQL供應商。每天,成千上萬的企業用它為數以百萬計的使用者提供服務。像所有有大量使用者的新生軟體一樣,它有漏洞和缺陷。但它正穩步改善。任何有關技術缺陷的討論,如果無助於解決問題,那麼很大程度上只能是一種情緒的宣洩。
本文最初發表在infoq,文章內容屬作者個人觀點,不代表本站立場。
相關文章
- 為什麼你永遠不應該在CSS中使用px來設定字型大小CSS
- 為什麼你應該使用一個PHP框架PHP框架
- 轉享:為什麼你應該使用Play框架?框架
- [譯] 為什麼你應該開始使用 KotlinKotlin
- iOS提示框,為什麼你應該使用 MBProgressHUD?iOS
- 為什麼你應該學 Python ?Python
- [譯] 為什麼你應該停止使用 Git rebase 命令Git
- 什麼場景應該用MongoDB ?MongoDB
- 為什麼你應該嘗試 “全棧”全棧
- 為什麼你應該嘗試“全棧”全棧
- 為什麼你應該為開源做設計
- 永遠不要對一個外行聊你的專業
- 為什麼你應該學習程式設計程式設計
- [譯]為什麼你應該在相等比較中使用 Object.is()Object
- 為什麼你不應該辭職去做遊戲應用遊戲
- 為什麼RPG遊戲永遠不會過時?遊戲
- 什麼是MongoDB?Python爬蟲為什麼使用MongoDB?MongoDBPython爬蟲
- 什麼時候你不應該使用微服務微服務
- 為什麼你應該先成為全棧工程師全棧工程師
- Python 集合是什麼,為什麼應該使用以及如何使用?Python
- 記住:永遠不要在 MySQL 中使用 UTF-8MySql
- 記住,永遠不要在MySQL中使用“utf8”MySql
- 為什麼學校應該使用自由軟體
- 程式設計師永遠不應該相信"抽象“程式設計師抽象
- 為什麼你應該成為六西格瑪黑帶大師
- 為什麼你應該在你下個 Ruby APP 中使用 Neo4jAPP
- 為什麼專案開發永遠缺乏合理的時間?
- 為什麼說你不要獨自程式設計程式設計
- 為什麼你應該參與到開源專案中
- 什麼時候該用MongoDB?MongoDB
- 記住,永遠不要在 MySQL 中使用 “utf8” 編碼MySql
- 為什麼 Python 開發人員應該使用 PipenvPython
- 為什麼應該在 Linux 上使用命名管道Linux
- 為什麼每個Android開發者都應該使用AnkoAndroid
- 再見了Antirez永遠的Redis之神Redis
- 為什麼開發者應該摒棄敏捷?敏捷
- 作為一個Java 程式設計師 你應該會什麼Java程式設計師
- 應該使用什麼 CI/CD 工具?