基本數據類型
1、在概念上,MongoDB的文檔與Javascript的對象相近,因而可以認為它類似於JSON。JSON(http://www.json.org)是一種簡單的數據表示方式:其規范僅用一段文字就能描述清楚(其官網證明了這點),且僅包含六種數據類型。
2、這樣有很多好處:易於理解、易於解析、易於記憶。然而從另一方面說,因為只有null、布爾、數字、字符串、數字和對象這幾種數據類型,所以JSON的表達能力有一定的局限。
3、雖然JSON具備的這些類型已經具有很強的表現力,但絕大數應用(尤其是在於數據庫打交道時)都還需要其他一些重要的類型。例如,JSON沒有日期類型,這使得原本容易日期處理變得煩人。另外,JSON只有一種數字類型,無法區分浮點數和整數,更別區分32位和64位了。再者JSON無法表示其他一些通用類型,如正則表達式或函數。
4、MongoDB在保留了JSON基本鍵/值對特性的基礎上,添加了其他一些數據類型。在不同的編程語言下,這些類型的確切表示有些許差異。下面說明了MongoDB支持的其他通用類型,以及如何正在文檔中使用它們
#1、null:用於表示空或不存在的字段
d={'x':null}
#2、布爾型:true和false
d={'x':true,'y':false}
#3、數值
d={'x':3,'y':3.1415926}
#4、字符串
d={'x':'egon'}
#5、日期
d={'x':new Date()}
d.x.getHours()
#6、正則表達式
d={'pattern':/^egon.*?nb$/i}
正則寫在//內,后面的i代表:
i 忽略大小寫
m 多行匹配模式
x 忽略非轉義的空白字符
s 單行匹配模式
#7、數組
d={'x':[1,'a','v']}
#8、內嵌文檔
user={'name':'egon','addr':{'country':'China','city':'YT'}}
user.addr.country
#9、對象id:是一個12字節的ID,是文檔的唯一標識,不可變
d={'x':ObjectId()}
_id和Objectid
MongoDB中存儲的文檔必須有一個"_id"鍵。這個鍵的值可以是任意類型,默認是個ObjectId對象。
在一個集合里,每個文檔都有唯一的“_id”,確保集合里每個文檔都能被唯一標識。
不同集合"_id"的值可以重復,但同一集合內"_id"的值必須唯一
#1、ObjectId
ObjectId是"_id"的默認類型。因為設計MongoDb的初衷就是用作分布式數據庫,所以能夠在分片環境中生成
唯一的標識符非常重要,而常規的做法:在多個服務器上同步自動增加主鍵既費時又費力,這就是MongoDB采用
ObjectId的原因。
ObjectId采用12字節的存儲空間,是一個由24個十六進制數字組成的字符串
0|1|2|3| 4|5|6| 7|8 9|10|11
時間戳 機器 PID 計數器
如果快速創建多個ObjectId,會發現每次只有最后幾位有變化。另外,中間的幾位數字也會變化(要是在創建過程中停頓幾秒)。
這是ObjectId的創建方式導致的,如上圖
時間戳單位為秒,與隨后5個字節組合起來,提供了秒級的唯一性。這個4個字節隱藏了文檔的創建時間,絕大多數驅動程序都會提供
一個方法,用於從ObjectId中獲取這些信息。
因為使用的是當前時間,很多用戶擔心要對服務器進行時鍾同步。其實沒必要,因為時間戳的實際值並不重要,只要它總是不停增加就好。
接下來3個字節是所在主機的唯一標識符。通常是機器主機名的散列值。這樣就可以保證不同主機生成不同的ObjectId,不產生沖突
接下來連個字節確保了在同一台機器上並發的多個進程產生的ObjectId是唯一的
前9個字節確保了同一秒鍾不同機器不同進程產生的ObjectId是唯一的。最后3個字節是一個自動增加的 計數器。確保相同進程的同一秒產生的
ObjectId也是不一樣的。
#2、自動生成_id
如果插入文檔時沒有"_id"鍵,系統會自幫你創建 一個。可以由MongoDb服務器來做這件事。
但通常會在客戶端由驅動程序完成。這一做法非常好地體現了MongoDb的哲學:能交給客戶端驅動程序來做的事情就不要交給服務器來做。
這種理念背后的原因是:即便是像MongoDB這樣擴展性非常好的數據庫,擴展應用層也要比擴展數據庫層容易的多。將工作交給客戶端做就
減輕了數據庫擴展的負擔。
