MongoDB是一個(gè)比較年輕的數(shù)據(jù)庫(kù)系統(tǒng),但在近些年發(fā)展的很迅速。MongoDB是NoSQL類型的數(shù)據(jù)庫(kù)。
NoSQL
NoSQL,泛指非關(guān)系型的數(shù)據(jù)庫(kù)。隨著互聯(lián)網(wǎng)web2.0網(wǎng)站的興起,傳統(tǒng)的關(guān)系數(shù)據(jù)庫(kù)在應(yīng)付web2.0網(wǎng)站,特別是超大規(guī)模和高并發(fā)的SNS類型的web2.0純動(dòng)態(tài)網(wǎng)站已經(jīng)顯得力不從心,暴露了很多難以克服的問(wèn)題,而非關(guān)系型的數(shù)據(jù)庫(kù)則由于其本身的特點(diǎn)得到了非常迅速的發(fā)展。NoSQL數(shù)據(jù)庫(kù)的產(chǎn)生就是為了解決大規(guī)模數(shù)據(jù)集合多重?cái)?shù)據(jù)種類帶來(lái)的挑戰(zhàn),尤其是大數(shù)據(jù)應(yīng)用難題。 --百度百科
數(shù)據(jù)會(huì)以key-value變量的形式儲(chǔ)存,以文件型數(shù)據(jù)庫(kù)的模式達(dá)到更好的性能。在之前的SQL數(shù)據(jù)庫(kù)中,數(shù)據(jù)儲(chǔ)存到表里,以主鍵或者外鍵的形式進(jìn)行檢索。在文件型數(shù)據(jù)庫(kù)中,數(shù)據(jù)不再儲(chǔ)存在表里,而是以標(biāo)準(zhǔn)文件形式比如JSON或XML。下面以一個(gè)簡(jiǎn)單的博客數(shù)據(jù)庫(kù)為例,SQL形式的數(shù)據(jù)庫(kù)可能需要兩張表來(lái)儲(chǔ)存博文和回復(fù)如下圖:
文件型數(shù)據(jù)庫(kù)則是以JSON形式,如下圖:
以上就是關(guān)系型數(shù)據(jù)庫(kù)和文件型 數(shù)據(jù)庫(kù)的最基本區(qū)別,一個(gè)用表,一個(gè)用文件。另外文件型數(shù)據(jù)庫(kù)在修改表(數(shù)據(jù))結(jié)構(gòu)的時(shí)候要比關(guān)系型數(shù)據(jù)庫(kù)要簡(jiǎn)單。
MongoDB
MongoDB有以下特點(diǎn):
BSON格式
類似于JSON形式的數(shù)據(jù)存儲(chǔ)格式Binary-JSON,又很快的讀取速率。
- 類似JSON,BSON文件是一個(gè)簡(jiǎn)單地key-value object形式的數(shù)據(jù)。一個(gè)文件包含多個(gè)element(元素),每一個(gè)element有一個(gè)name和對(duì)應(yīng)的value。這些文件支持所有JSON支持的數(shù)據(jù)類型。
- 使用_id字段作為主鍵,由應(yīng)用驅(qū)動(dòng)或者M(jìn)ongoDB server自動(dòng)生成 ObjectId,類型優(yōu)先級(jí)為:
- 4byte的Unix epoch時(shí)間
- 3byte的設(shè)備ID
- 2byte的進(jìn)程ID
- 3byte的計(jì)數(shù)器,以一個(gè)隨機(jī)數(shù)為起點(diǎn)
所以一個(gè)Object會(huì)長(zhǎng)成這個(gè)樣子:
MongoDB ad hoc檢索
對(duì)key-value儲(chǔ)存形式的擴(kuò)展,MongoDB有其類似于SQL的動(dòng)態(tài)檢索語(yǔ)言,下面對(duì)比SQL語(yǔ)言檢索所有title包含mongo的post:
SQL:
SELECT * FROM Posts WHRER Title LIKE ‘%mongo%’;
MongoDB:
db.posts.find({ title:/mongo/});
- MongoDB indexing,唯一的數(shù)據(jù)結(jié)構(gòu),給某字段設(shè)置index來(lái)提高檢索效率,例子:
檢索所有評(píng)論次數(shù)超過(guò)10次的博文:
"_id": ObjectId("52d02240e4b01d67d71ad577"),
"title": "First Blog Post",
"comments": [
],
"commentsCount": 12
}
MongoDB檢索:
db.posts.find({ commentCount:{$ gt:10} });
為了檢索以上數(shù)據(jù),MongoDB需要查詢所有的posts數(shù)據(jù),然后檢查commentCount是否大于10。但如果commonCount字段的index定義了,效率就會(huì)大大提高。下圖所示index是怎樣工作的:
MongoDB replica set
數(shù)據(jù)的備份,用到再說(shuō),先略了
MongoDB sharding
解決業(yè)務(wù)增長(zhǎng)后的性能問(wèn)題,略
多數(shù)據(jù)庫(kù)
一個(gè)MongoDB服務(wù)可以存儲(chǔ)多個(gè)DB,除非特意設(shè)定,MongoDB默認(rèn)打開(kāi)test數(shù)據(jù)庫(kù),想要切換到其他數(shù)據(jù)庫(kù)使用:
>use mean
切換到名字為mean的數(shù)據(jù)庫(kù),需要注意的是,在你不需要先創(chuàng)建數(shù)據(jù)庫(kù)再去使用,因?yàn)镸ongoDB的數(shù)據(jù)庫(kù)是在插入文件前懶創(chuàng)建的。這是MongoDB的動(dòng)態(tài)數(shù)據(jù)策略。另一個(gè)打開(kāi)數(shù)據(jù)庫(kù)的方法是:
$mongo mean
如果想要列出所有的數(shù)據(jù)庫(kù):
>show dbs
MongoDB collections
一個(gè)MongoDB collection是一些列的db文件,相當(dāng)于SQL數(shù)據(jù)庫(kù)的一些列表。一個(gè)collection是在第一個(gè)文件插入時(shí)被創(chuàng)建的。想要操作collection,要使用collection方法。現(xiàn)在創(chuàng)建一個(gè)posts collection:
`>db.posts.insert({"title:"First Post","user":"bob"})
上述,會(huì)自動(dòng)建一個(gè)posts collection。下面檢索一下posts:
db.posts.find()
上述,會(huì)看到結(jié)果。
想要看到所有可見(jiàn)的collection:
>show collections
刪除collection:
db.posts.drop()
MongoDB CRUD 操作
Create,Read,Update,Delete。
新建文件:insert()
新建object:update() 和 save()
新建文件
使用insert()創(chuàng)建文件:
> db.posts.insert({"title":"Second Post", "user": "alice"})
使用update()創(chuàng)建文件
> db.posts.update({
"user": "alice"
}, {
"title": "Second Post",
"user": "alice"
}, {
upsert: true
})
上述,DB首先會(huì)去查找作者是alice的post,然后更新;如果沒(méi)有找到并且upsert是true的話,新建一個(gè)文件。
使用save()創(chuàng)建文件
``` > db.posts.save({"title":"Second Post", "user": "alice"}) ``
上述,傳入文件可以有_id也可以沒(méi)有_id。
insert和save的區(qū)別當(dāng)主鍵"_id"不存在時(shí),都是添加一個(gè)新的文檔,但主健"_id"存在時(shí),就有些不同了:
insert:當(dāng)主鍵"_id"在集合中存在時(shí),不做任何處理。
save:當(dāng)主鍵"_id"在集合中存在時(shí),進(jìn)行更新。
save需要遍歷整個(gè)集合,效率沒(méi)有insert快。
讀取文件
讀取文件使用find()方法。
查找條件:
> db.posts.find({ "user": "alice" })
> db.posts.find({ "user": { $in: ["alice", "bob"] } })
AND/OR:
and不用關(guān)鍵字,羅列上就行
> db.posts.find({ "user": "alice", "commentsCount": { $gt: 10 } })
> db.posts.find( { $or: [{ "user": "alice" }, { "user": "bob" }] })
更新文件
update():
> db.posts.update({
"user": "alice"
}, { $set: {
"title": "Second Post"
}
}, {
multi: true
})
上述,update()有三個(gè)參數(shù),第一個(gè)參數(shù)是指更新哪些數(shù)據(jù)(篩選),第二個(gè)參數(shù)時(shí)更新內(nèi)容,第三個(gè)是強(qiáng)制更新所有符合條件的文件。
save()
> db.posts.save({
"_id": ObjectId("50691737d386d8fadbd6b01d"),
"title": "Second Post",
"user": "alice"
});
上述,需要傳一個(gè)_id,來(lái)告訴DB你要跟新的文件。** 如果save()沒(méi)有找到object,會(huì)新建一個(gè) **
刪除
使用remove()來(lái)刪除文件
刪除所有:
> db.posts.remove()
刪除多個(gè):
> db.posts.remove({ "user": "alice" })
刪除單個(gè):
> db.posts.remove({ "user": "alice" }, true)
上述,將會(huì)刪除第一個(gè)符合條件的文件,留下其他的。