想用MongoDB取代MySQL可以嗎?


首先我們要了解什麼是MySQL和MongoDB

MySQL與MongoDB都是開源的常用資料庫。MySQL是傳統的關係型資料庫,MongoDB則是非關係型資料庫,也叫文檔型資料庫,是一種NoSQL的資料庫。它們各有各的優點,關鍵是看用在什麼地方。所以我們所熟知的那些SQL(全稱Structured Query Language)語句就不適用於MongoDB了,因為SQL語句是關係型資料庫的標準語言。

與關係型資料庫相比,MongoDB的優點:

1. 弱一致性(最終一致),更能保證用戶的訪問速度: 舉例來說,在傳統的關係型資料庫中,一個COUNT類型的操作會鎖定數據集,這樣可以保證得到「當前」情況下的精確值。這在某些情況下,數據是不斷更新和增長的,這種「精確」的保證幾乎沒有任何意義,反而會產生很大的延遲。在某些情況下MongoDB會鎖住資料庫。如果此時正有數百個請求,則它們會堆積起來,造成許多問題。我們使用了下面的優化方式來避免鎖定: 每次更新前,我們會先查詢記錄。查詢操作會將對象放入內存,於是更新則會儘可能的迅速。在主/從部署方案中,從節點可以使用「-pretouch」參數運行,這也可以得到相同的效果。 使用多個mongod進程。我們根據訪問模式將資料庫拆分成多個進程。

2.文檔結構的存儲方式,能夠更便捷的獲取數據。 對於一個層級式的數據結構來說,如果要將這樣的數據使用扁平式的,表狀的結構來保存數據,這無論是在查詢還是獲取數據時都十分困難。

3.內置GridFS,支持大容量的存儲。GridFS是一個出色的分散式文件系統,可以支持海量的數據存儲。內置了GridFS了MongoDB,能夠滿足對大數據集的快速範圍查詢。

4.內置Sharding。 提供基於Range的Auto Sharding機制:一個collection可按照記錄的範圍,分成若干個段,切分到不同的Shard上。 Shards可以和複製結合,配合Replica sets能夠實現Sharding+fail-over,不同的Shard之間可以負載均衡。查詢是對 客戶端是透明的。客戶端執行查詢,統計,MapReduce等操作,這些會被MongoDB自動路由到後端的數據節點。這讓我們關注於自己的業務,適當的 時候可以無痛的升級。MongoDB的Sharding設計能力最大可支持約20 petabytes,足以支撐一般應用。 這可以保證MongoDB運行在便宜的PC伺服器集群上。PC集群擴充起來非常方便並且成本很低,避免了「sharding」操作的複雜性和成本。

5.官方支持,安全有保障。 開源文檔資料庫MongoDB背後有商業公司10gen為其提供供商業培訓和支持。而且MongoDB社區非常活躍,很多開發框架都迅速提供了對MongDB的支持。不少知名大公司和網站也在生產環境中使用MongoDB,越來越多的創新型企業轉而使用MongoDB作為和Django,RoR來搭配的技術方案。

6.性能優越: 在使用場合下,千萬級別的文檔對象,近10G的數據,對有索引的ID的查詢不會比mysql慢,而對非索引欄位的查詢,則是全面勝出。 mysql實際無法勝任大數據量下任意欄位的查詢,而mongodb的查詢性能超高。寫入性能同樣很令人滿意。

與關係型資料庫相比,MongoDB的缺點:

1. mongodb不支持事務操作。事務要求嚴格的系統(如果銀行系統)肯定不能用它。

2. mongodb佔用空間過大。 關於其原因,在官方的FAQ中,提到有如下幾個方面:

A. 空間的預分配:為避免形成過多的硬碟碎片,mongodb每次空間不足時都會申請生成一大塊的硬碟空間,而且申請的量從64M、128M、256M那 樣的指數遞增,直到2G為單個文件的最大體積。隨著數據量的增加,你可以在其數據目錄里看到這些整塊生成容量不斷遞增的文件。

B. 欄位名所佔用的空間:為了保持每個記錄內的結構信息用於查詢,mongodb需要把每個欄位的key-value都以BSON的形式存儲,如果 value域相對於key域並不大,比如存放數值型的數據,則數據的overhead是最大的。一種減少空間佔用的方法是把欄位名盡量取短一些,這樣佔用 空間就小了,但這就要求在易讀性與空間佔用上作為權衡了。

C. 刪除記錄不釋放空間:這很容易理解,為避免記錄刪除後的數據的大規模挪動,原記錄空間不刪除,只標記「已刪除」即可,以後還可以重複利用。

D. 可以定期運行db.repairDatabase()來整理記錄,但這個過程會比較緩慢。

如果有以下的需求,建議使用MongoDB

你期望一個更高的寫負載

默認情況下,對比事務安全,MongoDB更關注高的插入速度。如果你需要載入大量低價值的業務數據,那麼MongoDB將很適合你的用例。但是必須避免在要求高事務安全的情景下使用MongoDB,比如一個1000萬美元的交易。

不可靠環境保證高可用性

設置副本集(主-從伺服器設置)不僅方便而且很快,此外,使用MongoDB還可以快速、安全及自動化的實現節點(或數據中心)故障轉移。

未來會有一個很大的規模

資料庫擴展是非常有挑戰性的,當單表格大小達到5-10GB時,MySQL表格性能會毫無疑問的降低。如果你需要分片並且分割你的資料庫,MongoDB將很容易實現這一點。

使用基於位置的數據查詢

MongoDB支持二維空間索引,因此可以快速及精確的從指定位置獲取數據。

非結構化數據的爆發增長

給RDBMS增加列在有些情況下可能鎖定整個資料庫,或者增加負載從而導致性能下降,這個問題通常發生在表格大於1GB(更是下文提到BillRun系統中的痛點——單表格動輒幾GB)的情況下。鑒於MongoDB的弱數據結構模式,添加1個新欄位不會對舊錶格有任何影響,整個過程會非常快速;因此,在應用程序發生改變時,你不需要專門的1個DBA去修改資料庫模式。

缺少專業的資料庫管理員

如果你沒有專業的DBA,同時你也不需要結構化你的數據及做join查詢,MongoDB將會是你的首選。MongoDB非常適合類的持久化,類可以被序列化成JSON並儲存在MongoDB。


先給出結論:不可以取代!

能提出這樣的問題,肯定是對Mongodb不是很了解,來看看MongoDB是什麼,能做什麼,不能做什麼吧。

MongoDB

mongoDB是一個介於關係資料庫和非關係資料庫之間的產品,是非關係資料庫當中功能最豐富,最像關係資料庫的。他支持的數據結構非常鬆散,是類似json的bson格式,因此可以存儲比較複雜的數據類型。Mongo最大的特點是他支持的查詢語言非常強大,其語法有點類似於面向對象的查詢語言,幾乎可以實現類似關係資料庫單表查詢的絕大部分功能,而且還支持對數據建立索引。

特點:它的特點是高性能、易部署、易使用,存儲數據非常方便。主要功能特性有:

  1. 面向集合存儲,易存儲對象類型的數據。
  2. 模式自由。
  3. 支持動態查詢。
  4. 支持完全索引,包含內部對象。
  5. 支持查詢。
  6. 支持複製和故障恢復。
  7. 使用高效的二進位數據存儲,包括大型對象(如視頻等)。
  8. 自動處理碎片,以支持雲計算層次的擴展性。
  9. 支持RUBY,PYTHON,JAVA,C++,PHP,C#等多種語言。
  10. 文件存儲格式為BSON(一種JSON的擴展)。
  11. 可通過網路訪問。

使用原理所謂「面向集合」(Collection-Oriented),意思是數據被分組存儲在數據集中,被稱為一個集合(Collection)。每個集合在資料庫中都有一個唯一的標識名,並且可以包含無限數目的文檔。集合的概念類似關係型資料庫(RDBMS)里的表(table),不同的是它不需要定義任何模式(schema)。Nytro MegaRAID技術中的快閃記憶體高速緩存演算法,能夠快速識別資料庫內大數據集中的熱數據,提供一致的性能改進。模式自由(schema-free),意味著對於存儲在mongodb資料庫中的文件,我們不需要知道它的任何結構定義。如果需要的話,你完全可以把不同結構的文件存儲在同一個資料庫里。存儲在集合中的文檔,被存儲為鍵-值對的形式。鍵用於唯一標識一個文檔,為字元串類型,而值則可以是各種複雜的文件類型。我們稱這種存儲形式為BSON(Binary Serialized Document Format)。MongoDB已經在多個站點部署,其主要場景如下:1)網站實時數據處理。它非常適合實時的插入、更新與查詢,並具備網站實時數據存儲所需的複製及高度伸縮性。2)緩存。由於性能很高,它適合作為信息基礎設施的緩存層。在系統重啟之後,由它搭建的持久化緩存層可以避免下層的數據源過載。3)高伸縮性的場景。非常適合由數十或數百台伺服器組成的資料庫,它的路線圖中已經包含對MapReduce引擎的內置支持。

不適用的場景如下:

1)要求高度事務性的系統。

2)傳統的商業智能應用。

3)複雜的跨文檔(表)級聯查詢。

結論

從MongoDB不適用場景就可以看出其不可能替代MySQL.


這個問題其實就好像問關係型資料庫可以取代非關係型資料庫一樣。

要說完全取代,肯定是不可能的。

但是某些小項目中,你可以選擇使用mongodb而不用mysql。至少我經常這麼干。

當然,在一些特殊的大型項目裡面,你也可以完全拋棄關係型資料庫,mongodb會是你一個很好的選擇,什麼樣的項目?怎麼使用呢?我最後來告訴大家。

Mongodb確實非常好用,它的特點是高性能、易部署、易使用,存儲數據非常方便。

我們在使用的時候,不用再去考慮資料庫的設計,欄位等等。

我們可以輕鬆的建立好實體,然後CRUD。

當然,它還能夠支持查詢和索引,這樣就讓我們在使用中更加的方便,只要不是複雜的表關係邏輯,我們都可以使用mongodb來完成。

但是缺點就就是上面說的,如果非常複雜的邏輯關係,那用mongodb就有點力不從心了。

因為mongodb在複雜的關係邏輯處理和事務控制方面就比較弱了。

曾經,我研究過一段時間領域驅動設計,也就是DDD。

當DDD和CQRS(命令與查詢職責分離)結合使用的時候(當然,很多時候說DDD都是結合了CQRS的),你就會發現,你是不是使用關係型資料庫已經不太重要了。

先說說底層,如果你使用DDD+CQRS,你可以有兩個資料庫,一個Command庫,一個Query庫,也就是讀庫和寫庫。

當DDD+CQRS使用時,寫庫裡面寫入的只是一個個對象的操作命令,所以可以簡單的說,一個命令就是一條記錄,而且寫庫裡面只有Insert。當然,最後的時候,寫庫裡面會有海量的數據,當數據量過大時,就會用到快照,這個就不說了。

這個時候我們就會發現,一個只有insert的單表庫,用關係型資料庫貌似沒啥意義。我用mongodb,redis都可以完成。

那我們再看看讀庫,讀庫其實是將所有的命令執行後的最終結果呈現出來,那讀庫應該是關係型的,因為我們的業務邏輯肯定是有關係的。

但是我們仔細體會後會發現,DDD的聚合,聚合根,實體對象,值對象這些概念,將本來複雜的關係整理得非常明晰(有興趣的可以去看看DDD,這些概念有點抽象,這裡就不介紹了)。

你會發現,我不使用關係型資料庫,我就是用一個緩存,或者mongodb就可以進行存儲了,因為我的查詢都是通過聚合根來實現的,我的命令也都是通過聚合根來完成的,聚合根是什麼?其實也就是一個實體類,整個聚合也就是一個複雜關係的實體類,聚合與聚合之間其實不會有聯繫,這個也就是DDD裡面的關於邊界的劃分。

那在實現這一的項目時,我就可以寫庫用Redis,讀庫用Mongodb,MySQL?可以不用了。


推薦閱讀:

中國有沒有類似SETI@home的組織?
除了 Hadoop 還有哪些分散式計算平台?優勢各自是什麼?

TAG:MySQL | MongoDB | 資料庫 | NoSQL | 分散式計算 |