02-1.Mongodb基礎知識

 

·文檔是Mongodb中數據的基本單元,非常類似於關係型數據庫管理系統中的行,但更具有表現力。

·集合(collection)可以看作是一個擁有動態模式(dynamic schema)的表。

·Mongodb的一個實例可以擁有多個相互獨立的數據庫(database),每個數據庫都擁有自己的集合。

·每一個文檔都擁有一個特殊的鍵“_id”,這個鍵在文檔所屬的集合中是唯一的。

·Mongodb自帶了一個簡單但功能強大的JavaScript Shell,可以用於管理Mongodb的實例或數據庫操作。

 

1. 文檔

文檔是Mongodb的核心概念。文檔就是鍵值對的一個有序集。

文檔的鍵是字符串,除了少數例外情況,鍵可以使用任意UTF-8字符。

鍵不能含有\0(空字符)。這個字符用於表示鍵的結尾。

.$具有特殊意義,只能在特定環境下使用。

Mongodb文檔不能有重複的鍵。

 

2.集合

集合就是一組文檔。

集合是動態模式的。這意味着一個集合裏面的文檔可以是各式各樣的。

 

思考:因爲集合裏面可以放置任何文檔,那麼有必要使用多個集合嗎?

·如果把各種各樣的文檔不加區分地放在同一個集合裏,無論對開發者還是對管理員來說都將是噩夢。

·在一個集合裏查詢特定類型的文檔在速度上也很不划算,分開查詢多個集合要快得多。

·把同種類型的文檔放在一個集合裏,數據會更加集中。

·創建索引時,需要使用文檔的附加結構(特別是創建唯一索引時)。索引是按照集合來定義的。在一個集合中只放入一種類型的文檔,可以更有效的對集合進行索引。

 

集合命名:

·集合名不能是空字符串("")。

·集合名不能包含\0字符(空字符)。這個字符表示集合名的結束。

·集合名不能以“system.”開頭,這是爲系統集合保留的前綴。

·創建的集合不能包含保留字符“$”。

子集合:組織集合的一種慣例是使用"."分隔不同命名空間的子集合。(例如:blog.postsblog.authors

 

3.數據庫

Mongodb中,多個文檔組成集合,而多個集合可以組成數據庫。

 

數據庫通過名稱來標識,這點與集合類似。

·不能是空字符串。

·不得含有(/  \  .  "  <  >  :  |  >  $  \0  …)。基本上只能使用ASCII中的字母和數字。

·數據庫名區分大小寫。

·數據庫名最多爲64字節。

 

保留數據庫名:adminlocalconfig

 

命名空間(namespace):是把數據庫名添加到集合名前,得到的集合完全限定名。(如:cms數據庫的blog.posts集合,這個集合的命名空間是cms.blog.posts。)

命名空間的長度不得超過121字節,且在實際使用中應小於100字節。

 

4.啓動數據庫

默認情況下,Mongodb監聽27017端口。mongod還會啓動一個非常基本的HTTP服務器,監聽數字比主端口號高1000的端口,默認是28017端口。

 

5.Mongodb Shell簡介

Mongodb自帶JavaScript Shell,可在Shell中使用命令行與Mongodb實例交互。它是一個獨立的Mongodb客戶端,通過運行mongo啓動Shell時,會連接到Mongodb數據庫服務器的test數據庫。

使用db命令可以查看當前所在數據庫!

 

Shell中查看或操作數據會用到4個基本操作:創建、讀取、更新和刪除(CRUD操作)。

 

創建:insert函數

可以將一個文檔添加到集合中。

下圖爲存儲博客文章的例子,首先創建一個名爲post的局部變量,這是一個JavaScript對象,用於表示我們的文檔。

然後可以用insert方法將其保存到blog集合中。

wKiom1TwCRbwjHb7AAMINppo03c253.jpg

 

讀取:findfindOne方法

可以用於查詢集合裏的文檔。若只查詢一個文檔用findOne,使用find時,Shell會自動顯示最多20個匹配的文檔,也可以獲取更多。

 

更新:update

接受(至少)兩個參數:第一個是限定條件(用於匹配待更新的文檔),第二個是新的文檔。

假設我們要爲先前寫的文章增加評論功能,就需要增加一個新的鍵,用於保存評論數組。

首先修改變量post,增加"comments"鍵,然後執行update操作,用新版本的文檔替換標題爲"My blog post"的文章:

wKioL1TwCmXDC862AAKHD9iJqP0798.jpg

 

刪除:remove

使用remove方法可以將文檔從數據庫中永久刪除。如果沒有使用任何參數,它會將集合內的所有文檔全部刪除。它可以接受一個作爲限定條件的文檔作爲參數。例如下面的命令刪除上面創建的文檔:

>db.blog.remove({title : "My blog post"})

 

6.數據類型

 

基本數據類型:

在概念上,Mongodb的文檔與JavaScript中的對象相近,因而可認爲它類似於JSON

 

·null:用於表示空值或者不存在的字段。  {"x" : null}

·布爾型:有兩個值truefalse  {"x" : true}

·數值:Shell默認使用64位浮點型數值。因此,以下數值在Shell中是很“正常”的: {"x" : 3.14} {"x" : 3}

對於整型值,可使用NumberInt類(表示4字節帶符號整數)或NumberLong類(表示8字符帶符號整數),分別舉例如下:

{"x" : NumberInt("3")}       {"x" : NumberLong("3")}

·字符串:UTF-8字符串都可表示爲字符串類型的數據。  {"x" : "foobar"}

·日期:被存儲爲自新紀元以來經過的毫秒數,不存儲時區。  {"x" : new Date()}

·正則表達式:查詢時,使用正則表達式作爲限定條件,語法與JavaScript的正則表達式語法相同。  {"x" : /foobar/i}

·數組:數據列表或數據集可以表示爲數組。  { "x" : ["a","b","c"]}

·內嵌文檔:文檔可嵌套其它文檔,被嵌套的文檔作爲父文檔的值。  {"x" : {"foo" : "bar"}}

·對象id:是一個12字節的ID,是文檔的唯一標識。  {"x" : ObjectId()}

 

_idObjectId

MongoDB 中存儲的文檔必須有一個"_id" 鍵。這個鍵的值可以是任何類型的,默認是個ObjectId 對象。在一個集合裏面,每個文檔都有唯一的"_id" 值,來確保集合裏面每個文檔都能被唯一標識。如果有兩個集合的話,兩個集合可以都有一個值爲123 的"_id" 鍵,但是每個集合裏面只能有一個"_id" 是123 的文檔。

 

.ObjectId

ObjectId 是"_id" 的默認類型。它設計成輕量型的,不同的機器都能用全局唯一的同種方法方便地生成它。這是MongoDB 採用ObjectId,而不是其他比較常規的做法(比如自動增加的主鍵)的主要原因,因爲在多個服務器上同步自動增加主鍵值既費力還費時。MongoDB 從一開始就設計用來作爲分佈式數據庫,處理多個節點是一個核心要求。後面會看到ObjectId 類型在分片環境中要容易生成得多。

 

ObjectId 使用12 字節的存儲空間,每個字節兩位十六進制數字,是一個24 位的字符串。由於看起來很長,不少人會覺得難以處理。但關鍵是要知道這個長長的ObjectId 是實際存儲數據的兩倍長。

 

如果快速連續創建多個ObjectId,會發現每次只有最後幾位數字有變化。另外,中間的幾位數字也會變化(要是在創建的過程中停頓幾秒鐘)。這是ObjectId 的創建方式導致的。12 字節按照如下方式生成:

wKiom1TwCYLyhq9jAAA3i98PWc0903.jpg

 

4 個字節是從標準紀元開始的時間戳,單位爲秒。這會帶來一些有用的屬性。

·時間戳,與隨後的. 5 個字節組合起來,提供了秒級別的唯一性。

·由於時間戳在前,這意味着ObjectId 大致會按照插入的順序排列。這對於某些方面很有用,如將其作爲索引提高效率,但是這個是沒有保證的,僅僅是“大致”。

·這4 個字節也隱含了文檔創建的時間。絕大多數驅動都會公開一個方法從ObjectId 獲取這個信息。

 

因爲使用的是當前時間,很多用戶擔心要對服務器進行時間同步。其實沒有這個必要,因爲時間戳的實際值並不重要,只要其總是不停增加就好了(每秒一次)。

 

接下來的3 字節是所在主機的唯一標識符。通常是機器主機名的散列值。這樣就可以確保不同主機生成不同的ObjectId,不產生衝突。

 

爲了確保在同一臺機器上併發的多個進程產生的ObjectId 是唯一的,接下來的兩字節來自產生ObjectId 的進程標識符(PID)。

 

9 字節保證了同一秒鐘不同機器不同進程產生的ObjectId 是唯一的。後3 字節就是一個自動增加的計數器,確保相同進程同一秒產生的ObjectId 也是不一樣的。同一秒鐘最多允許每個進程擁有256316 777 216)個不同的ObjectId

 

.自動生成_id

 

前面講到,如果插入文檔的時候沒有"_id" 鍵,系統會自動幫你創建一個。可以由MongoDB 服務器來做這件事情,但通常會在客戶端由驅動程序完成。理由如下。

 

雖然ObjectId 設計成輕量型的,易於生成,但是畢竟生成的時候還是產生開銷。在客戶端生成體現了MongoDB 的設計理念:能從服務器端轉移到驅動程序來做的事,就儘量轉移。這種理念背後的原因是,即便是像MongoDB 這樣的可擴展數據庫,擴展應用層也要比擴展數據庫層容易得多。將事務交由客戶端來處理,就減輕了數據庫擴展的負擔。

 

在客戶端生成ObjectId,驅動程序能夠提供更加豐富的API。例如,驅動程序可以有自己的insert 方法,可以返回生成的ObjectId,也可以直接將其插入文檔。如果驅動程序允許服務器生成ObjectId,那麼將需要單獨的查詢,以確定插入的文檔中的"_id" 值。

 

 

 

PS:內容整理於《Mongodb權威指南》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章