MongoDB介紹

雨客發表於2016-04-08

MongoDB 是一個開源的,高效能,無模式(或者說是模式自由),使用 C++ 語言編寫的面向文件的資料庫。正因為 MongoDB 是面向文件的,所以它可以管理類似 JSON 的文件集合。又因為資料可以被巢狀到複雜的體系中並保持可以查詢可索引,這樣一來,應用程式便可以以一種更加自然的方式來為資料建模。

官方網站:http://www.mongodb.org/

MongoDB介紹

所謂“面向集合”(Collenction-Orented),意思是資料被分組儲存在資料集中,被稱為一個集合(Collenction)。每個集合在資料庫中都有一個唯一的標識名,並且可以包含無限數目的文件。集合的概念類似關係型資料庫(RDBMS)裡的表(table),不同的是它不需要定義任何模式(schema)。

模式自由(schema-free),意味著對於儲存在mongodb資料庫中的檔案,我們不需要知道它的任何結構定義。如果需要的話,你完全可以把不同結構的檔案儲存在同一個資料庫裡。

儲存在集合中的文件,被儲存為鍵-值對的形式。鍵用於唯一標識一個文件,為字串型別,而值則可以是各中複雜的檔案型別。我們稱這種儲存形式為BSON(Binary Serialized dOcument Format)。

MongoDB 把資料儲存在檔案中(預設路徑為:/data/db),為提高效率使用記憶體對映檔案進行管理。MongoDB的主要目標是在鍵/值儲存方式(提供了高效能和高度伸縮性)以及傳統的 RDBMS 系統(豐富的功能)架起一座橋樑,集兩者的優勢於一身。

根據官方網站的描述,Mongo 適合用於以下場景:

  • 網站資料:Mongo非常適合實時的插入,更新與查詢,並具備網站實時資料儲存所需的複製及高度伸縮性。
  • 快取:由於效能很高,Mongo也適合作為資訊基礎設施的快取層。在系統重啟之後,由Mongo搭建的持久化快取層可以避免下層的資料來源過載。
  • 大尺寸,低價值的資料:使用傳統的關係型資料庫儲存一些資料時可能會比較昂貴,在此之前,很多時候程式設計師往往會選擇傳統的檔案進行儲存。
  • 高伸縮性的場景:Mongo非常適合由數十或數百臺伺服器組成的資料庫。Mongo的路線圖中已經包含對MapReduce引擎的內建支援。
  • 用於物件及JSON資料的儲存:Mongo的BSON資料格式非常適合文件化格式的儲存及查詢。

自然,MongoDB 的使用也會有一些限制,例如它不適合:

  • 高度事務性的系統:例如銀行或會計系統。傳統的關係型資料庫目前還是更適用於需要大量原子性複雜事務的應用程式。
  • 傳統的商業智慧應用:針對特定問題的BI資料庫會對產生高度優化的查詢方式。對於此類應用,資料倉儲可能是更合適的選擇。
  • 需要SQL的問題

MongoDB的安裝

mongodb的官網就有下載,根據系統windows還是linux還是別的下載32位還是64位的,然後解壓安裝。

如果你使用的時mac系統,你可以通過 brewhome 來安裝:

$ brew install mongodb

MongoDB的管理

解壓完之後進入bin目錄,裡面都是一些可執行檔案,mongo,mongod,mongodump,mongoexport等。

1).啟動和停止MongoDB

通過執行mongod來啟動MongoDB伺服器:

$ mongod

mongod有很多的配置啟動選項的,可以通過mongod --help來檢視,其中有一些主要的選項:

  • --dbpath:指定資料目錄,預設是/data/db/。每個mongod程式都需要獨立的目錄,啟動mongod時就會在資料目錄中建立mongod.lock檔案,防止其他mongod程式使用該資料目錄。
  • --port:指定伺服器監聽的埠,預設是27017
  • --fork:以守護程式的方式執行MongoDB。
  • --logpath:指定日誌輸出路徑,如果不指定則會在終端輸出。每次啟動都會覆蓋原來的日誌,如果不想覆蓋就要用--logappend選項。
  • --config:指定配置檔案,載入命令列未指定的各種選項。我們可以講我們需要用到的選項寫在某個檔案中,然後通過該選項來指定這個檔案就不必每次啟動mongod時都要寫。

2).資料備份

a. 資料檔案備份

最簡單的備份就是資料檔案的備份,就是直接賦值data/db這個目錄,因為我們前面已經指定了資料目錄就是data/db,那麼MongoDB多有的資料都在這裡,但是有個問題就是最新的資料還在快取中,沒用同步到磁碟,可以先停止shutdownServer()再備份。但是這樣會影響MongoDB正常的工作。

b. mongodump和mongorestore

bin 中還有 mongodump 和 mongorestore 兩個可執行檔案,這個是對MongoDB的某個資料庫進行備份,可以在MongoDB正在執行時進行備份,比如備份test資料庫,然後將備份的資料庫檔案再倒入別的MongoDB伺服器上。這種備份的方式備份的不是最新資料,只是已經寫入MongoDB中的資料,可能還有的資料在快取中沒有寫入,那麼這部分資料就是備份不到的。mongodump和mongorestore也可以通過--help查詢所有選項。

$ mongodump -d text -o test_db
connected to: 127.0.0.1
2014-06-06T12:54:59.741+0800 DATABASE: text	 to 	test_db/text

-d是指定資料庫,-o是輸出備份檔案,上面將 test 資料庫備份為 test_db 檔案。

$ mongorestore --port 27017 -d temple --drop test_db/test/

這裡將上面備份出來的 test 資料庫現在重新匯入到 temple 資料庫,--drop代表如果有了 temple 資料庫則將其中的所有集合刪除,不指定就會和原來 temple 中的集合合併。

c. mongoexport和mongoimport

備份某個資料庫中的某個表,同樣可以通過--help來檢視所有的選項,當然mongoexport也是可以不統計的備份,但是卻不一定是最新資料。

$ mongoexport --port 27017 -d zhihu -c zh_user -o zh_user 
$ mongoimport --port 9352 -d temple -c user zh_user

-c表示 collection 集合,上面將 zhihu 庫中的 zh_user 集合備份出來為 zh_user 檔案,然後再匯入到 temple 庫中的user集合。

d. sync和鎖

mongodump和mongoexport對都可以不停MongoDB伺服器來進行備份,但是卻失去了獲取實時資料的能力,而fsync命令也能在不停MongoDB的情況下備份實時資料,它的實現其實就是上鎖,阻止對資料庫的寫入操作,然後將緩衝區的資料寫入磁碟,備份後再解鎖。在這個期間,任何對資料庫的寫入操作都會阻塞,直到鎖被釋放。

> db.runCommand({"fsync" : 1, "lock" : 1})
{
        "info" : "now locked against writes, use db.fsyncUnlock() to unlock",
        "seeAlso" : "http://dochub.mongodb.org/core/fsynccommand",
        "ok" : 1
}
>
>在這之間進行備份,執行任何insert操作都會阻塞
>
> db.fsyncUnlock()
{ "ok" : 1, "info" : "unlock completed" }

資料型別

MongoDB的檔案儲存格式為BSON,同JSON一樣支援往其它文件物件和陣列中再插入文件物件和陣列,同時擴充套件了JSON的資料型別.與資料庫打交道的那些應用。例如,JSON沒有日期型別,這會使得處理本來簡單的日期問題變得非常繁瑣。只有一種數字型別,沒法區分浮點數和整數,更不能區分32位和64位數字。也沒有辦法表示其他常用型別,如正規表示式或函式。

下面是MongoDB的支援的資料型別:

  • null null用於表示空值或者不存在的欄位。 {"x":null}
  • 布林 布林型別有兩個值’true’和’false1’。 {"X":true}
  • 32位整數 型別不可用。JavaScript僅支援64位浮點數,所以32位整數會被自動轉換。
  • 64位整數 不支援這個型別。shell會使用一個特殊的內嵌文件來顯示64位整數。
  • 64位浮點數 shell中的數字都是這種型別。下面的表示都是浮點數: {"X" : 3.1415926} {"X" : 3}
  • 字串 UTF-8字串都可表示為字串型別的資料: {"x" : "foobar"}
  • 符號 不支援這種型別。shell將資料庫裡的符號型別轉換成字串。
  • 物件id 物件id是文件的12位元組的唯一ID:{"_id":ObjectId() }
  • 日期 日期型別儲存的是從標準紀元開始的毫秒數。不儲存時區: {"X" : new Date()}
  • 正規表示式 文件中可以包含正規表示式,採用JavaScript的正規表示式語法:{"x": /foobar/i}
  • 程式碼 文件中還可以包含JavaScript程式碼:{"x": function() { /* …… */ }}
  • 二進位制資料 二進位制資料可以由任意位元組的串組成。不過shell中無法使用。
  • 最大值 BSON包括一個特殊型別,表示可能的最大值。shell中沒有這個型別。
  • 最小值 BSON包括一個特殊型別,表示可能的最小值。shell中沒有這個型別。
  • 未定義 文件中也可以使用未定義型別:{"x":undefined}
  • 陣列 值的集合或者列表可以表示成陣列:{"x" : ["a", "b", "c"]}
  • 內嵌文件 文件可以包含別的文件,也可以作為值嵌入到父文件中,資料可以組織得更自然些,不用非得存成扁平結構的:{“x” : {“food” : “noodle”}}

JavaScript中只有一種“數字”型別。因為MongoDB中有3種數字型別(32位整數、64位整數和64位浮點數),shell必須繞過JavaScript的限制。預設情況下,shell中的數字都被MongoDB當做是雙精度數。這意味著如果你從資料庫中獲得的是一個32位整數,修改文件後,將文件存回資料庫的時候,這個整數也被轉換成了浮點數,即便保持這個整數原封不動也會這樣的。所以明智的做法是儘量不要在shell下覆蓋整個文件。

由於MongoDB中不同文件的同一個key的value資料型別可以不同,當我們根據某個key查詢的時候會發生不同資料型別之間的比較。所以MongoDB內部設定了資料型別間的大小,順序如下:

最小值<null<數字(32位整數、63位整形、64位浮點數)<字串<物件/文件<陣列<二進位制資料<物件ID<布林型<日期型<時間戳<正則<最大值


相關文章