mongodb数据库淘汰_MongoDB 等 NoSQL 与关系型数据库相比,有什么优缺点及适用场景?...
利益相關:MongoDB 員工,開發 MongoDB 數據庫 5 年。十年前,當 Dwight 和我開始這個后來成為 MongoDB 的項目的時候,我們絕對沒有想到它今天的樣子。我們只有一個信念:讓開發者更高效。MongoDB 誕生于在龐大復雜的業務部署中使用關系型數據庫給我們帶來的沮喪。我們著手建造一個我們自己想用的數據庫。這樣,每當開發者想寫一個應用時,他們可以專注于應用本身,而不用圍著數據庫轉。
Eliot Horowitz,
2017年10月19日,MongoDB 納斯達克上市當天,CTO Eliot 在公司博客寫下這些話。從 MongoDB 紐約總部,穿過時代廣場,到納斯達克咫尺之遙。而這一天,距離
「讓開發者更高效」概括了 MongoDB 相較于關系型數據庫帶來的全部價值。這要放在最近十年整個行業的大背景下理解。
軟件行業的工資水平是出了名得高。這意味著軟件開發的成本中,人力成本已經超越了硬件成本,成為成本里的大頭。曾經長周期、瀑布式的開發流程被強調快速迭代的開發流程所替代。所有這些,加上你經常聽說的熱詞,比如敏捷開發,微服務,DevOps,都指向「讓開發者更高效」。
這一背景下,基于關系表的關系型的數據模式也被靈活的非關系型數據模式替代。
文檔模型更自然
文檔模型與面向對象的數據表達方式更相似更自然。與關系型數據庫中表結構不同,文檔中可以嵌入數組和子文檔,就像程序中的數組和成員變量一樣。這是關系型數據庫三范式不允許的。但實際中我們經常看到一對多和一對一的數據。比如,一篇博客文章的 Tag 列表作為文章的一部分非常直觀,而把 Tag 與文章的從屬關系單獨放一張表里就不那么自然。再比如,一個訂單下面的收貨地址,包括省、市、區、街道和門牌,作為一個子文檔,與訂單的信用卡地址很容易區分開。更方便的是,嵌入的數組和子文檔之上可以直接建立索引,比如我可以很快找到所有 Tag 包含 MongoDB 的文章。
其實,我挺喜歡關系型數據庫那些理論的,SQL 語言可以很精確地形式化,賞心悅目。然而,三范式強調的「數據沒有任何冗余」并不是今天程序員們最關心的問題。他們用著方便不方便才是更重要的問題。
性能
三范式所帶來的性能損失也是一個問題。為了滿足一個查詢,多個表的數據都要參與 Join,每一個表都對應著磁盤的一次讀取。這和數據放在一個地方,一次讀完,當然完全不同。更簡單的數據訪問模式也讓開發者更容易理解數據庫的性能表現,尤其是當涉及到索引時。例如,關系型數據庫中一個查詢太慢了,它 Join 了 6 張表,到底我應該給哪個表的哪一列加什么樣的索引呢?
靈活
關系型數據庫最常見的運維問題是給已有數據加一個新的可選的屬性,從數據表到應用數據層都要改。盡管有些工具可以把它自動化,這仍然是一個復雜的工作,尤其是更新產品線上數據庫的時候。MongoDB 沒有 Schema(模式、數據模型),就不需要改動數據庫,只需要在應用層做必要的改動。
自定義屬性也是一個問題,電子商務網站的產品除了價格,ID等,每類產品有許多自定義屬性,比如 LCD 和 LED 顯示器的產品特性就不一樣。數據這種特性被稱為「多態」(polymorphism)。關系型數據庫里,產品這個表應該怎么設計?最簡單的方案,是把每個可能的屬性都變成單獨一列,當然這個方案不能擴展。更極端一點,一個通訊錄允許用戶隨意添加新的聯系方式,你有 Facebook,他有 Twitter。一種方案是在程序里把所有自定義屬性序列化,比如用 JSON 放到一列里。另一種方案,叫做
MongoDB 的靈活還體現在非結構化和半結構化的數據上。MongoDB 提供全文索引,也支持地理位置查詢和索引。例如一位用戶想知道方圓五公里哪里有公共衛生間,這是「地理范圍查詢」。然后他搜索最近的單車。摩拜單車正是使用 MongoDB 完成這樣的「距離排序查詢」。強烈建議使用地理位置索引加速查詢,因為我能理解這位用戶的心情。
可擴展性
數據一臺機器放不下了,就需要 sharding(分片)把它放到好幾臺機器上去。分片是 MongoDB 多年以來的原生功能,與 MongoDB 其他功能高效整合。例如,分片集群中一個復雜的聚合查詢會自動地根據 Shard Key(片鍵)分配到多個結點上運行,盡可能將計算任務下推到數據結點上,最后在一個結點上聚合所有結點的結果。分片還可以在各個結點間自動遷移數據,均衡其數據量。為了升級數據庫容量,相較于關系型數據庫分庫分表需要同時改動應用和數據庫,分片的運維也簡單很多,能夠做到對應用透明。
我們希望即使機器硬件有問題,數據也不要丟,服務不受影響。分片后機器更多,任一機器出問題的概率也就更高。Replication 復制解決了這個問題。它把同一份數據實時地復制到多個結點,自動地在其中切換。MongoDB 的商業客戶中,不論規模大小,使用復制集已經成了一個標準,因為數據丟失的代價遠大于冗余機器的成本。
事務
事務是2018年夏天要推出的 MongoDB 4.0 版本最大的新功能。事務是一直以來用戶要求最強烈的功能之一,盡管通過 Schema 的設計,可以把關系型數據庫里多個表的多條記錄,放在一個文檔里,能解決一部分對事務的需求。4.0 中,用戶可以在一個復制集內,交互式地在多個集合里插入修改多個文檔,整個事務滿足 ACID,滿足 Snapshot Isolation(快照隔離)一致性要求。過去半年,這是我們組的主要工作。明年 MongoDB 4.2 計劃加入對分片集群事務的支持。
有時候相關數據放在一個文檔里不方便,JOIN 不可避免。MongoDB 提供了
十年積累
從 MongoDB 開發者的角度看,MongoDB 站在幾十年數據庫理論巨人的肩膀上,也積累了自己的理論創新。例如復制功能中 Raft 協議每個細節的改動都經過仔細考量,確保不會影響正確性。可是更重要也更困難的是工程問題。幾年前「距離排序查詢」的性能問題反饋比較多。有用戶建議地理位置索引使用 R-Tree 代替 GeoHash。然而我的兩個實習生工程上的優化就可以
龐大系統的工程問題的解決最終是日拱一卒帶來的,就像 Oracle 的質量是一個個 Hotfix 積累的結果。十年過去,MongoDB 早已成熟。這不僅是 Bug 不斷被修復,系統的設計、測試和流程也都更加完善。5 年前引入 Raft 時,復制功能全部都有單元測試,JavaScript 集成測試數量也翻了一番。
想起 3 年前有人發文章批評 7 年前的版本,怎么說呢……哎,不說了,要被人批評不謙虛了。數據庫升級了解一下,
什么時候不用 MongoDB
十年間,從最初幾年證明文檔數據模型的價值,到分布式系統架構日臻成熟,再到 4.0 支持事務,今天的 MongoDB 可以勝任關系型數據庫的所有應用場景。MongoDB 也不再是一個創業公司,今天已經全球超過 1000 名員工,包括中國分公司。
那什么時候用 MongoDB 不合適呢?
一次,我在一個 pet project 里需要地鐵列車時刻表,官方提供的是一個滿足行業標準的 SQL 格式的數據。站點、路線、班次、調度安排按照三范式分成了好幾張表,但是數據量很小。我花了一晚上把數據導入到了 MongoDB 里,按照訪問模式設計了文檔結構,最終運行得很好。可如果再來一次,我可能會選擇使用關系型數據庫。因為如果源數據格式是 SQL 數據,沒法控制;數據量小;數據間交叉引用關系復雜;查詢模式豐富;應用又不需要高性能;不擔心機器故障等高可用性問題,那么繼續沿用關系型數據庫也是一個務實的選擇。我的 pet project 最終只有我一個用戶,然后塵封在 BitBucket 的代碼庫里。早知如此,用關系型數據庫里也沒什么不可以 ˉ\_(ツ)_/ˉ
這個 pet project 教給我的,也是我最后想說的:一個項目的好壞很少取決于你用哪個工具。不管用 Vim 還是 Emacs 都能成為很厲害的程序員,但是他們不是因為 Vim 或者 Emacs 才這么厲害的。他們理解工具能帶來什么,并用其創造價值。希望 MongoDB 能成為你工具箱里一個稱手的工具,當下次需要的時候,多快好省地解決問題,讓你更多地關心應用本身。現在就開始學習 MongoDB 吧?怎樣學 MongoDB??www.zhihu.com
特別感謝 @Rob Guo 提出多處修改意見。
References
總結
以上是生活随笔為你收集整理的mongodb数据库淘汰_MongoDB 等 NoSQL 与关系型数据库相比,有什么优缺点及适用场景?...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ac9560不支持承载_Win10不支持
- 下一篇: xlsxwriter写行合并_使用xls