NoSQL 的全稱是 Not Only SQL,也可以理解非關係型的資料庫,是一種新型的革命式的資料庫設計方式,不過它不是為了取代傳統的關係型資料庫而被設計的,它們分別代表了不同的資料庫設計思路。
MongoDB:
- 它是一個內存資料庫,數據都是放在內存裡面的。
- 對數據的操作大部分都在內存中,但MongoDB並不是單純的內存資料庫。
- -MongoDB是由C++語言進行編寫的,是一個基於分布式文件存儲的開源資料庫系統。
- 在高負載的情況下,天劍更多的節點,可以保證伺服器的性能。
- MongoDB旨為WEB應用提供可擴展的高性能數據存儲解決方案。
MongoDB將數據存儲為一個文檔,將數據機構由鍵值(key=>value)對組成。MongoDB文檔類似於JSON對象。欄位值可以包含其他文檔,數組及文檔數組。
MongoDB的存儲特點
在傳統的關係型資料庫中,數據是以表單為媒介進行存儲的,每個表單均擁有縱向的列和橫向的列。
由此可見,相比較MySQL,MongoDB以一種直觀文檔的方式來完成數據的存儲。它很像JavaScript中定義的JSON格式,不過數據在存儲的時候MongoDB資料庫為文檔增加了序列化操作,最終存進磁碟的其實是叫做BSON的格式,即Binary-JSON。
在資料庫存放的數據中,有一種特殊的鍵值叫做主鍵,它用於唯一的標識表中的某一條記錄。也就是說,一個表不能有多個主鍵,並且主鍵不能為空值。
無論是MongoDB還是MySQL,都存在著主鍵的定義
對於MongoDB來說,其主鍵名叫『_id』,如果用戶不主動為其分配一個主鍵的話,MongoDB會自動為其生成一個隨機分配的值。
在MySQL中,主鍵的指定是MySQL插入數據時指明PRIMARY KEY來定義的。當沒有指定主鍵的時候,另一種工具 --索引,相當於替代了主鍵的功能。索引可以為空,也可以有重複,另外有一種不允許重複的索引叫唯一索引。如果既沒有指定主鍵也沒有指定索引的話,MySQL會自動為數據創建一個。
- 資料庫的平均插入速率:MongoDB不指定_id插入> MySQL不指定主鍵插入>MySQL指定主鍵插入>MongoDB指定_id插入。
- 在MongoDB中,指定索引插入比不指定慢很多,這是因為,MongoDB里每一條數據的_id值都是唯一的。當不指定_id插入數據的時候,其_id是系統進行自動計算生成的。MongoDB通過計算機特徵值、時間、進程ID與隨機數來確保生成的_id是唯一的。而在指定_id插入時,MongoDB每插一條數據,都需要檢查此_id可不可用,當資料庫中數據條數太多的時候,這一步的查詢開銷會拖慢整個資料庫的插入速度。
- MongoDB會充分使用系統內存作為緩存,這是一種非常優秀的特徵。我們測試 機的內存有64G,在插入時,MongoDB會儘可能地在內存快寫不進去數據之後,再將數據持久化保存到硬碟上。這也是在不指定_id插入的時候,MongoDB的效率遙遙領先的原因。但在指定_id插入時,當數據量一大內存裝不下時,MongoDB就需要將磁碟中的信息讀取到內存中來查重,這樣一來插入效率反而慢了。
- MySQL不愧是一種非常穩定的資料庫,無論在指定主鍵還是在不指定主鍵插入的情況下,其效率都差不了太多。
MongoDB的應用場景
在另一方面,對於開發者來說,如果是因為業務需求或者是項目初始化階段,而是導致數據具體格式無法明確定義的話,MongoDB的這一鮮明特性就脫穎而出了。相比傳統的關係型資料庫,它非常容易被擴展,這也為寫代碼帶來了極大的方便。
不過MongoDB對數據之間事務關係支持比較弱,如果業務這一方面要求比較高的話,MongoDB還是並不適合此類的應用。
非關係型資料庫(NoSQL),屬於文檔型資料庫 。先解釋一下文檔的資料庫,即可以存放xml、json、bson類型系那個的數據。這些數據具備自述性(self-describing),呈現分層的樹狀數據結構。數據結構由鍵值(key=>value)對組成。
存儲方式: 虛擬內存+持久化
持久化方式:
MongoDB的所有數據實際上是存放在硬碟的,所有要操作的數據通過mmap的方式映射到內存某個區域內。
然後,MongoDB就在這塊區域裡面進行數據修改,避免了零碎的硬碟操作。
至於mmap上的內容flush到硬碟就是作業系統的事情了,所以,如果,MongoDB在內存中修改了數據後,mmap數據flush到硬碟之前,系統宕機了,數據就會丟失。
主要特點
- MongoDB的提供了一個面向文檔存儲,操作起來比較容易和簡單。
- 可以在MongoDB記錄中設置任何屬性的索引(如:FirstName="Sameer",Address="8 Gandhi Road")來實現更快的排序。
- 可以通過本地或者網絡創建的數據鏡像,這使得MongoDB有更強的擴展性。
- 如果負載的增加(需要更多的存儲空間和更強的處理能力),它可以分布在計算機網絡中的其他節點上就是所謂的分片。
- MongoDB支持豐富的查詢表達式。查詢指令使用JSON形式的標記,可輕易查詢文檔中內嵌的對象及數組。
- MongoDB使用update()命令可以實現替換完成的文檔(數據)或者一些指定的數據欄位。
- MongoDB中的Map/reduce主要是用來對數據進行批量處理和聚合操作。
- Map 和 Reduce。Map 函數調用 emit(key,value) 遍歷集合中所有的記錄,將 key 與 value 傳給 Reduce 函數進行處理。
- Map函數和Reduce函數是使用JavaSript編寫的,並可以通過db.runCommand或mapreduce命令來執行MapReduce操作。
- GridFS是MongoDB中的一個內置功能,可以用於存放大量小文件。
- MongoDB允許在服務端執行腳本,可以用JavaScript編寫某個函數,直接在服務端執行,也可以把函數的定義存儲在服務端,下次直接調用即可。
- MongoDB支持各種程式語言:RUBY,PYTHON,JAVA,C++,PHP,C# 等多種語言。
1.它裡面自帶了一個名叫GridFS的分布式文件系統,這就為MongoDB的部署提供了很大的便利。而像MySQL這種比較早的資料庫,雖然市面上有很多不同的分表部署方案,但這種終究不如MongoDB直接官方支持來的便捷實在。
2.另外MongoDB內部還自建了對map-reduce運算框架的支持,雖然這種支持從功能上看還算是比較簡單的,相當於MySQL里GroupBy功能的擴展版,怒過也為數據的統計帶來了方便。
3.MongoDB在啟動後會將資料庫中的數據以文件映射的方式加載到內存中。如果內存資源相當豐富的話,這將極大地提高資料庫的查詢速度,畢竟內存對I/O效率比磁碟高多了。
MongoDB以BSON結構(二進位)進行存儲,對海量數據存儲有著明顯的優勢。
監控
- MongoDB提供了網絡和系統監控工具Munin,它作為一個插件應用於MongoDB中。
- Gangila是MongoDB高性能的系統監視工具,它作為一個插件應用於MongoDB。
- 基於圖形介面的開源工具Cacti,用於查看CPU負載,網絡帶寬利用率,它也提供了一個應用於監控MongoDB的插件。
- 查詢語句:是獨特的MongoDB的查詢方式。
- 適合場景:事件的記錄,內容管理或博客平台等等。
- 架構特點:可以通過副本集,以及分片來實現高可用。
- 數據處理: 數據是存儲在硬碟上的,只不過需要經常讀取的數據會被加載到內存,將數據存儲在物理內存中,從而達到高速讀寫。
- 成熟度與廣泛度:新興資料庫,成熟度較低,No SQL資料庫中最為接近關係型資料庫,比較完善的DB之一,適用人群不斷在增長。
MongoDB優點:
- 性能優越:快速!在適量級的內存的MongoDB的性能是非常迅速的,它將熱數據存儲在物理內存中,使得熱數據的讀寫變得十分快。
- 高擴展:第三方支持豐富(這是與其他的No SQL相比,MongoDB也具有的優勢)
- 自身的Failover機制!
- 弱一致性(最終一致),更能保證用戶的訪問速度
- 文檔結構的存儲方式,能夠更便捷的獲取數據:json的存儲格式
- 支持大容量的存儲,內置GridFS
- 內置Sharding
MongoDB 缺點:
主要是無事務機制
MongoDB 不支持事務操作(最主要的缺點)
MongoDB 占用空間過大
MongoDB 沒有如 MySQL 那樣成熟的維護工具,這對於開發和IT運營都是個值得注意的地方
Redis:
它就是一個不折不扣的內存資料庫。
持久化方式:
Redis 所有數據都是放在內存中的,持久化是使用 RDB 方式或者 aof 方式。
MySQL:
無論數據還是索引都存放在硬碟中。到要使用的時候才交換到內存中。能夠處理遠超過內存總量的數據。
關係型資料庫。
在不同的引擎上有不同 的存儲方式。
查詢語句是使用傳統的 SQL 語句,擁有較為成熟的體系,成熟度很高。
開源資料庫的份額在不斷增加,MySQL 的份額頁在持續增長。
缺點就是在海量數據處理的時候效率會顯著變慢。
數據量和性能的比較:
當物理內存夠用的時候,Redis > MongoDB > MySQL
當物理內存不夠用的時候,Redis 和 MongoDB 都會使用虛擬內存。
實際上如果Redis要開始虛擬內存,那很明顯要麼加內存條,要麼你就該換個資料庫了。
但是,MongoDB 不一樣,只要,業務上能保證,冷熱數據的讀寫比,使得熱數據在物理內存中,mmap 的交換較少。
MongoDB 還是能夠保證性能。有人使用 MongoDB 存儲了上T的數據。
MySQL,MySQL根本就不需要擔心數據量跟內存下的關係。不過,內存的量跟熱數據的關係會極大地影響性能表現。
當物理內存和虛擬內存都不夠用的時候,估計除了 MySQL 你沒什麼好選擇了。
其實,從數據存儲原理來看,我更傾向於將 MongoDB 歸類為硬碟資料庫,但是使用了 mmap 作為加速的手段而已。
簡說mmap:
mmap系統調用並不是完全為了用於共享內存而設計的。它本身提供了不同於一般對普通文件的訪問方式,進程可以像讀寫內存一樣對普通文件進行操作。
mmap 系統調用使得進程之間通過映射同一個普通文件實現共享內存。普通文件被映射到進程地址空間後,進程可以像訪問普通內存一樣對文件進行訪問,不必再調用。 read(),write()等操作。mmap 並不分配空間, 只是將文件映射到調用進程的地址空間裡, 然後你就可以用 memcpy 等操作寫文件, 而不用 write() 了.寫完後用 msync() 同步一下, 你所寫的內容就保存到文件里了. 不過這種方式沒辦法增加文件的長度, 因為要映射的長度在調用 mmap() 的時候就決定了。
MongoDB 與 MySQL 的適用場景:
MongoDB 的適用場景為:數據不是特別重要(例如通知,推送這些),數據表結構變化較為頻繁,數據量特別大,數據的並發性特別高,數據結構比較特別(例如地圖的位置坐標),這些情況下用 MongoDB , 其他情況就還是用 MySQL ,這樣組合使用就可以達到最大的效率。
1.如果需要將 MongoDB 作為後端 db 來代替MySQL使用,即這裡 MySQL 與 MongoDB 屬於平行級別,那麼,這樣的使用可能有以下幾種情況的考量:
1)MongoDB 所負責部分以文檔形式存儲,能夠有較好的代碼親和性,json 格式的直接寫入方便(如日誌之類)
。
2)從 data models 設計階段就將原子性考慮於其中,無需事務之類的輔助。開發用如 nodejs 之類的語言來進行開發,對開發比較方便。
3)MongoDB 本身的 failover 機制,無需使用如 MHA 之類的方式實現。
2.將 MongoDB 作為類似 Redis,memcache 來做緩存db,為 MySQL 提供服務,或是後端日誌收集分析。 考慮到 MongoDB 屬於 No SQL 型資料庫,SQL 語句與數據結構不如 MySQL 那麼親和 ,也會有很多時候將 MongoDB 做為輔助MySQL 而使用的類 Redis memcache 之類的緩存db來使用。 亦或是僅作日誌收集分析。
MongoDB 有一個最大的缺點,就是它占用的空間很大,因為它屬於典型空間換時間原則的類型。那麼它的磁碟空間比普通資料庫會浪費一些,而且到目前為止它還沒有實現在線壓縮功能,在 MongoDB 中頻繁的進行數據增刪改時,如果記錄變了,例如數據大小發生了變化,這時候容易產生一些數據碎片,出現碎片引發的結果,一個是索引會出現性能問題。
另外一個就是在一定的時間後,所占空間會莫明其妙地增大,所以要定期把資料庫做修復,定期重新做索引,這樣會提升MongoDB 的穩定性和效率。
1.MySQL 來自女兒的名字; MongoDB 來自 humongous
2.MySQL 使用 Table/Row/Column; MongoDB 使用 Collection/Document
3.MySQL 需要指定 table 的 schema; MongoDB的 collection 的每個 document 的 schema 可以自由修改
4.MySQL 支持 join; MongoDB 沒有 join
5.MySQL 使用 SQL 語言; MongoDB 使用類似 JavaScript 的函數
命令對比
MongoDB 與 MySQL 命令對比 傳統的關係數據庫一般由資料庫(database)、表(table)、記錄(record)三個層次概念組成,MongoDB 是由資料庫(database)、集合(collection)、文檔對象(document)三個層次組成。MongoDB對於關係型資料庫里的表,但是集合中沒有列、行和關係概念,這體現了模式自由的特點。
MongoDB (文檔型資料庫):提供可擴展的高性能數據存儲
1、基於分布式文件存儲
2、高負載情況下添加更多節點,可以保證伺服器性能
3、將數據存儲為一個文檔
MongoDB 與 MySQL 的比較
1、穩定性
2、索引,索引放在內存中,能夠提升隨機讀寫的性能。如果索引不能完全放在內存,一旦出現隨機讀寫比較高的時候,就會頻繁地進行磁碟交換,MongoDB 的性能就會急劇下降
3、占用的空間很大,因為它屬於典型空間換時間原則的類型。那麼它的磁碟空間比普通資料庫會浪費一些,而且到目前為止它還沒有實現在線壓縮功能,
在 MongoDB 中頻繁的進行數據增刪改時,如果記錄變了,例如數據大小發生了變化,這時候容易產生一些數據碎片,出現碎片引發的結果,
一個是索引會出現性能問題,
另外一個就是在一定的時間後,所占空間會莫明其妙地增大,所以要定期把資料庫做修復,定期重新做索引,這樣會提升MongoDB 的穩定性和效率。
在最新的版本里,它已經在實現在線壓縮,估計應該在2.0版左右,應該能夠實現在線壓縮,可以在後台執行現在repair DataBase 的一些操作。如果那樣,就解決了目前困擾我們的大問題。
4、MongoDB 對數據間的事務關係支持比較弱
5、運維不方便
MongoDB 相對於 MySQL 的優勢
- 適合那些對資料庫具體數據格式不明確或者資料庫數據格式經常變化的需求模型,而且對開發者十分友好。
- 自帶一個分布式文件系統,可以很方便地部署到伺服器機群上。
- MongoDB 里有一個Shard的概念,就是方便為了伺服器分片使用的。每增加一台Shard,MongoDB 的插入性能也會以接近倍數的方式增長,磁碟容量也很可以很方便地擴充。
- 自帶了對map-reduce運算框架的支持,這也很方便進行數據的統計。類似於group by
- MongoDB 與 MySQL 命令對比 傳統的關係數據庫一般由資料庫(database)、表(table)、記錄(record)三個層次概念組成,
- MongoDB 是由資料庫(database)、集合(collection)、文檔對象(document)三個層次組成。
- MongoDB 對於關係型資料庫里的表,但是集合中沒有列、行和關係概念,這體現了模式自由的特點。