首先部凑,我們要了解MongoDB的基本運(yùn)行機(jī)制祷嘶。這將有助于我們理解MongoDB的核心。
在此之前盯漂,我們需要明白六個簡單的概念:
- MongoDB與你所熟悉的數(shù)據(jù)庫有一些相同的概念集乔。在一個MongoDB實例instance中去件,你可以擁有0個或者多個數(shù)據(jù)庫database,它們每一個都是高性能容器扰路。
- 一個database可以擁有0個或者多個集合collection尤溜。你可以認(rèn)為傳統(tǒng)的table和collection是同一個概念。
- 一個集合可以擁有0個或者多個文檔document汗唱。同樣地宫莱,你可以將它看作是傳統(tǒng)數(shù)據(jù)庫中的row。
- 一個文檔document是由field組成的哩罪,你可能已經(jīng)猜出來了授霸,你可以把它看作是一個column。
- MongoDB中的索引index际插,和關(guān)系型數(shù)據(jù)庫中索引的概念十分相似碘耳。
- 游標(biāo)Cursor不同于其他5個概念,但是它們是非常重要的框弛,但通常會被忽視辛辨。重點需要理解的是,當(dāng)向MongoDB請求數(shù)據(jù)瑟枫,它將返回一個結(jié)果集的指針斗搞,我們稱之為游標(biāo)。
概要回顧慷妙,MongoDB由database組成僻焚,database包含有collection,collection由document組成膝擂,每個document由若干個field組成虑啤。
Collection可以被索引隙弛,這將提高查找和排序的性能。最終咐旧,當(dāng)我們通過游標(biāo)cursor來獲取MongoDB中的數(shù)據(jù)驶鹉。當(dāng)游標(biāo)返回時候绩蜻,并沒有執(zhí)行查詢操作铣墨,真正的查詢操作會延時要真正需要的結(jié)果的時候,比如調(diào)用它的hasNext或者next方法办绝,這是才會訪問數(shù)據(jù)庫伊约。
為什么要使用這些新的名詞(集合vs 表, 文檔vs行孕蝉, field vs列)屡律?僅僅是為了讓事情更加復(fù)雜嗎?真相就是降淮,這些概念很傳統(tǒng)關(guān)系型數(shù)據(jù)庫中對等物的概念很相似超埋,但是,它們又不一樣佳鳖。核心的不同在于霍殴,關(guān)系型數(shù)據(jù)庫在table的層次定義列,而面向文檔的數(shù)據(jù)庫中系吩,數(shù)據(jù)庫定義它的field在文檔的層次上来庭。這就是說,在集合中每一個文檔都有它自己獨立的field集穿挨。因此月弛,collection是一個相對table簡化的容器,而文檔擁有比row更多的信息科盛。
雖然理解這些很重要帽衙,但是如果對一些概念還不夠清晰,不要擔(dān)心贞绵。用不了幾個插入操作厉萝,你就能真正理解它的含義。最終但壮,你將明白關(guān)鍵就是collection對于將存儲什么樣的結(jié)構(gòu)的數(shù)據(jù)要求是不嚴(yán)格的冀泻,或者說它是無模式的。Field被獨立的文檔所跟蹤蜡饵。這其中的優(yōu)點和缺點我們將在后續(xù)的章節(jié)中說明弹渔。
讓我們來動手實踐一下(hands-on)。運(yùn)行mongod server和 mongo shell溯祸。Shell可以運(yùn)行JavaScript肢专。這里有一些可以執(zhí)行的全局(global)命令舞肆,比如 db.help() db.stats()等。這些命令的執(zhí)行可以是針對某個一個指定的collection博杖,而我們也通常會這么做椿胯,比如,通過db.COLLCECTION_NAME對象剃根,執(zhí)行
db.unicorns.help() or db.unicorns.count() 哩盲。
需要注意的一點是,因為這是一個JavaScript shell狈醉,如果你要執(zhí)行一個method廉油,而忽略了圓括號(),你將看到方法體苗傅,而是不要執(zhí)行的方法抒线。所以,如果你輸入db.help而不是db.help()渣慕,你將看到help方法內(nèi)部的實現(xiàn)嘶炭。
首先,我們使用use來選擇數(shù)據(jù)庫逊桦。即使數(shù)據(jù)庫不存在也沒有關(guān)系眨猎,因為當(dāng)我們創(chuàng)建collection時候,如果database不存在卫袒,它會被自動創(chuàng)建(注:默認(rèn)使用test數(shù)據(jù)庫宵呛,如果需要切換或者新建,可以使用use命令夕凝,需要注意的是宝穗,對于新建,需要往數(shù)據(jù)庫中插入一條數(shù)據(jù)码秉,才能看到新建的數(shù)據(jù)庫)逮矛。
現(xiàn)在,你正在一個database的世界中转砖,你可以使用(issuing)數(shù)據(jù)庫命令须鼎,比如db.getCollectionNames()。如果你這么做了府蔗,你將得到一個空的數(shù)組([ ])晋控。因為collection事無模式的,我們并不需要顯式創(chuàng)建它們姓赤,直接插入即可赡译。
我們可以使用insert命令簡單地插入一個document到一個新的collection中:
db.unicorns.insert({name: 'ygs'})
上面這一行將在unicorns集合中執(zhí)行insert命令,并傳遞進(jìn)入了一個參數(shù)不铆。MongoDB內(nèi)部使用二進(jìn)制的序列化JSON格式蝌焚,即BSON裹唆。外部,這就意味著我們更多的是使用JSON作為參數(shù)只洒。如果此時執(zhí)行db.getCollectionNames()我們將看到一個unicorns集合许帐。
你可以使用unicorns的find命令來返回document文檔的列表。
db.unicorns.find()
結(jié)果輸出:
{ "_id" : ObjectId("593580006556fa7ec7a3735b"), "name" : "ygs" }
注意毕谴,這里有個_id field成畦。每個document都必須有個唯一的_id field。你可以選擇自己創(chuàng)建一個或者讓MongoDB為你創(chuàng)建一個ObjectId類型的值析珊。通常羡鸥,你可以希望MongoDB幫你創(chuàng)建蔑穴。默認(rèn)的忠寻,_id field是索引,你可以使用getIndexes()命令確認(rèn):
db.unicorns.getIndexes()
結(jié)果輸出:
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.unicorns"
}
]
現(xiàn)在存和,回到我們討論的無模式的collection奕剃。插入一個完全不相同的document到unicorns中,比如
db.unicorns.insert({age:26})
通過find命令列出所有document結(jié)果為:
{ "_id" : ObjectId("593580006556fa7ec7a3735b"), "name" : "ygs" }
{ "_id" : ObjectId("593585316556fa7ec7a3735c"), "age" : 26 }