備注:本文非原創(chuàng),參考自以下文章
https://blog.csdn.net/hayre/article/details/80628431
https://www.runoob.com/mongodb/mongodb-databases-documents-collections.html
一、為什么要使用MongoDB?
1、MongoDB提出的是文檔、集合的概念,使用BSON(類(lèi)JSON)作為其數(shù)據(jù)模型結(jié)構(gòu),其結(jié)構(gòu)是面向?qū)ο蟮亩皇嵌S表,存儲(chǔ)一個(gè)用戶(hù)在MongoDB中是這樣子的。
{
username:'123',
password:'123'
}
使用這樣的數(shù)據(jù)模型,使得MongoDB能在生產(chǎn)環(huán)境中提供高讀寫(xiě)的能力,吞吐量較于mysql等SQL數(shù)據(jù)庫(kù)大大增強(qiáng)。
2、易伸縮,自動(dòng)故障轉(zhuǎn)移。易伸縮指的是提供了分片能力,能對(duì)數(shù)據(jù)集進(jìn)行分片,數(shù)據(jù)的存儲(chǔ)壓力分?jǐn)偨o多臺(tái)服務(wù)器。自動(dòng)故障轉(zhuǎn)移是副本集的概念,MongoDB能檢測(cè)主節(jié)點(diǎn)是否存活,當(dāng)失活時(shí)能自動(dòng)提升從節(jié)點(diǎn)為主節(jié)點(diǎn),達(dá)到故障轉(zhuǎn)移。
3、數(shù)據(jù)模型因?yàn)槭敲嫦驅(qū)ο蟮模钥梢员硎矩S富的、有層級(jí)的數(shù)據(jù)結(jié)構(gòu),比如博客系統(tǒng)中能把“評(píng)論”直接懟到“文章“的文檔中,而不必像myqsl一樣創(chuàng)建三張表來(lái)描述這樣的關(guān)系。
二、主要特性
1、文檔數(shù)據(jù)類(lèi)型
SQL類(lèi)型的數(shù)據(jù)庫(kù)是正規(guī)化的,可以通過(guò)主鍵或者外鍵的約束保證數(shù)據(jù)的完整性與唯一性,所以SQL類(lèi)型的數(shù)據(jù)庫(kù)常用于對(duì)數(shù)據(jù)完整性較高的系統(tǒng)。MongoDB在這一方面是不如SQL類(lèi)型的數(shù)據(jù)庫(kù),且MongoDB沒(méi)有固定的Schema,正因?yàn)镸ongoDB少了一些這樣的約束條件,可以讓數(shù)據(jù)的存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)更靈活,存儲(chǔ)速度更加快。
2、即時(shí)查詢(xún)能力
MongoDB保留了關(guān)系型數(shù)據(jù)庫(kù)即時(shí)查詢(xún)的能力,保留了索引(底層是基于B tree)的能力。這一點(diǎn)汲取了關(guān)系型數(shù)據(jù)庫(kù)的優(yōu)點(diǎn),相比于同類(lèi)型的NoSQL redis 并沒(méi)有上述的能力。
3、復(fù)制能力
MongoDB自身提供了副本集能將數(shù)據(jù)分布在多臺(tái)機(jī)器上實(shí)現(xiàn)冗余,目的是可以提供自動(dòng)故障轉(zhuǎn)移、擴(kuò)展讀能力。
4、速度與持久性
MongoDB的驅(qū)動(dòng)實(shí)現(xiàn)一個(gè)寫(xiě)入語(yǔ)義 fire and forget ,即通過(guò)驅(qū)動(dòng)調(diào)用寫(xiě)入時(shí),可以立即得到返回得到成功的結(jié)果(即使是報(bào)錯(cuò)),這樣讓寫(xiě)入的速度更加快,當(dāng)然會(huì)有一定的不安全性,完全依賴(lài)網(wǎng)絡(luò)。
MongoDB提供了Journaling日志的概念,實(shí)際上像mysql的bin-log日志,當(dāng)需要插入的時(shí)候會(huì)先往日志里面寫(xiě)入記錄,再完成實(shí)際的數(shù)據(jù)操作,這樣如果出現(xiàn)停電,進(jìn)程突然中斷的情況,可以保障數(shù)據(jù)不會(huì)錯(cuò)誤,可以通過(guò)修復(fù)功能讀取Journaling日志進(jìn)行修復(fù)。
5、數(shù)據(jù)擴(kuò)展
MongoDB使用分片技術(shù)對(duì)數(shù)據(jù)進(jìn)行擴(kuò)展,MongoDB能自動(dòng)分片、自動(dòng)轉(zhuǎn)移分片里面的數(shù)據(jù)塊,讓每一個(gè)服務(wù)器里面存儲(chǔ)的數(shù)據(jù)都是一樣大小。
三、C/S服務(wù)模型
MongoDB核心服務(wù)器主要是通過(guò)mongod程序啟動(dòng)的,而且在啟動(dòng)時(shí)不需對(duì)MongoDB使用的內(nèi)存進(jìn)行配置,因?yàn)槠湓O(shè)計(jì)哲學(xué)是內(nèi)存管理最好是交給操作系統(tǒng),缺少內(nèi)存配置是MongoDB的設(shè)計(jì)亮點(diǎn),另外,還可通過(guò)mongos路由服務(wù)器使用分片功能。
MongoDB的主要客戶(hù)端是可以交互的js shell 通過(guò)mongo啟動(dòng),使用js shell能使用js直接與MongoDB進(jìn)行交流,像使用sql語(yǔ)句查詢(xún)mysql數(shù)據(jù)一樣使用js語(yǔ)法查詢(xún)MongoDB的數(shù)據(jù),另外還提供了各種語(yǔ)言的驅(qū)動(dòng)包,方便各種語(yǔ)言的接入。
四、完善的命令行工具
mongodump和mongorestore,備份和恢復(fù)數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)工具。輸出BSON格式,遷移數(shù)據(jù)庫(kù)。
mongoexport和mongoimport,用來(lái)導(dǎo)入導(dǎo)出JSON、CSV和TSV數(shù)據(jù),數(shù)據(jù)需要支持多格式時(shí)有用。mongoimport還能用與大數(shù)據(jù)集的初始導(dǎo)入,但是在導(dǎo)入前順便還要注意一下,為了能充分利用好mongoDB通常需要對(duì)數(shù)據(jù)模型做一些調(diào)整。
五、MongoDB 常用操作
更多內(nèi)容可查閱此文:https://www.runoob.com/mongodb/mongodb-databases-documents-collections.html
1、相關(guān)概念對(duì)比
| SQL術(shù)語(yǔ)/概念 | MongoDB術(shù)語(yǔ)/概念 | 解釋/說(shuō)明 |
|---|---|---|
| database | database | 數(shù)據(jù)庫(kù) |
| table | collection | 數(shù)據(jù)庫(kù)表/集合 |
| row | document | 數(shù)據(jù)記錄行/文檔 |
| column | field | 數(shù)據(jù)字段/域 |
| index | index | 索引 |
| table joins | 表連接,MongoDB不支持 | |
| primary key | primary key | 主鍵,MongoDB自動(dòng)將_id字段設(shè)置為主鍵 |
?
2、創(chuàng)建數(shù)據(jù)庫(kù)
use DATABASE_NAME
如果數(shù)據(jù)庫(kù)不存在,則創(chuàng)建數(shù)據(jù)庫(kù),否則切換到指定數(shù)據(jù)庫(kù)。
?
3、刪除數(shù)據(jù)庫(kù)
db.dropDatabase()
刪除當(dāng)前數(shù)據(jù)庫(kù),默認(rèn)為 test,你可以使用 db 命令查看當(dāng)前數(shù)據(jù)庫(kù)名。
?
4、創(chuàng)建集合
db.createCollection(name, options)
參數(shù)說(shuō)明:
name: 要?jiǎng)?chuàng)建的集合名稱(chēng)
options: 可選參數(shù), 指定有關(guān)內(nèi)存大小及索引的選項(xiàng)
其實(shí)在 MongoDB 中,你不需要?jiǎng)?chuàng)建集合。當(dāng)你插入一些文檔時(shí),MongoDB 會(huì)自動(dòng)創(chuàng)建集合。
> db.mycol2.insert({"name" : "菜鳥(niǎo)教程"})
> show collections
mycol2
?
5、刪除集合
db.collection_1.drop()
?
6、插入文檔
文檔的數(shù)據(jù)結(jié)構(gòu)和 JSON 基本一樣。
所有存儲(chǔ)在集合中的數(shù)據(jù)都是 BSON 格式。
BSON 是一種類(lèi)似 JSON 的二進(jìn)制形式的存儲(chǔ)格式,是 Binary JSON 的簡(jiǎn)稱(chēng)。
db.COLLECTION_NAME.insert(document)
>db.col.insert({title: 'MongoDB 教程',
description: 'MongoDB 是一個(gè) Nosql 數(shù)據(jù)庫(kù)',
by: '菜鳥(niǎo)教程',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
插入文檔你也可以使用 db.col.save(document) 命令。如果不指定 _id 字段 save() 方法類(lèi)似于 insert() 方法。如果指定 _id 字段,則會(huì)更新該 _id 的數(shù)據(jù)。
?
7、更新文檔
update() 方法用于更新已存在的文檔。語(yǔ)法格式如下:
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
參數(shù)說(shuō)明:
query : update的查詢(xún)條件,類(lèi)似sql update查詢(xún)內(nèi)where后面的。
update : update的對(duì)象和一些更新的操作符(如inc...)等,也可以理解為sql update查詢(xún)內(nèi)set后面的
upsert : 可選,這個(gè)參數(shù)的意思是,如果不存在update的記錄,是否插入objNew,true為插入,默認(rèn)是false,不插入。
multi : 可選,mongodb 默認(rèn)是false,只更新找到的第一條記錄,如果這個(gè)參數(shù)為true,就把按條件查出來(lái)多條記錄全部更新。
writeConcern :可選,拋出異常的級(jí)別。
db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
?
8、查詢(xún)文檔
db.collection.find(query, projection)
query :可選,使用查詢(xún)操作符指定查詢(xún)條件
projection :可選,使用投影操作符指定返回的鍵。查詢(xún)時(shí)返回文檔中所有鍵值, 只需省略該參數(shù)即可(默認(rèn)省略)。
如果你需要以易讀的方式來(lái)讀取數(shù)據(jù),可以使用 pretty() 方法,語(yǔ)法格式如下:
>db.col.find().pretty()
如果你熟悉常規(guī)的 SQL 數(shù)據(jù),通過(guò)下表可以更好的理解 MongoDB 的條件語(yǔ)句查詢(xún):
| 操作 | 格式 | 范例 | RDBMS中的類(lèi)似語(yǔ)句 |
|---|---|---|---|
| 等于 | {<key>:<value>} | db.col.find({"by":"菜鳥(niǎo)教程"}).pretty() | where by = '菜鳥(niǎo)教程' |
| 小于 | {<key>:{$lt:<value>}} | db.col.find({"likes":{$lt:50}}).pretty() | where likes < 50 |
| 小于或等于 | {<key>:{$lte:<value>}} | db.col.find({"likes":{$lte:50}}).pretty() | where likes <= 50 |
| 大于 | {<key>:{$gt:<value>}} | db.col.find({"likes":{$gt:50}}).pretty() | where likes > 50 |
| 大于或等于 | {<key>:{$gte:<value>}} | db.col.find({"likes":{$gte:50}}).pretty() | where likes >= 50 |
| 不等于 | {<key>:{$ne:<value>}} | db.col.find({"likes":{$ne:50}}).pretty() | where likes != 50 |
以下實(shí)例演示了 AND 和 OR 聯(lián)合使用,類(lèi)似常規(guī) SQL 語(yǔ)句為: 'where likes>50 AND (by = '菜鳥(niǎo)教程' OR title = 'MongoDB 教程')'
>db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鳥(niǎo)教程"},{"title": "MongoDB 教程"}]}).pretty()
{
"_id" : ObjectId("56063f17ade2f21f36b03133"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一個(gè) Nosql 數(shù)據(jù)庫(kù)",
"by" : "菜鳥(niǎo)教程",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
?
9、刪除文檔
執(zhí)行remove()函數(shù)前先執(zhí)行find()命令來(lái)判斷執(zhí)行的條件是否正確,這是一個(gè)比較好的習(xí)慣。
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
參數(shù)說(shuō)明:
query :(可選)刪除的文檔的條件。
justOne : (可選)如果設(shè)為 true 或 1,則只刪除一個(gè)文檔,如果不設(shè)置該參數(shù),或使用默認(rèn)值 false,則刪除所有匹配條件的文檔。
writeConcern :(可選)拋出異常的級(jí)別。
備注:remove() 方法 并不會(huì)真正釋放空間。
需要繼續(xù)執(zhí)行 db.repairDatabase() 來(lái)回收磁盤(pán)空間。
> db.repairDatabase()
或者
> db.runCommand({ repairDatabase: 1 })
remove() 方法已經(jīng)過(guò)時(shí)了,現(xiàn)在官方推薦使用 deleteOne() 和 deleteMany() 方法。
如刪除集合下全部文檔:
db.inventory.deleteMany({})
刪除 status 等于 A 的全部文檔:
db.inventory.deleteMany({ status : "A" })
刪除 status 等于 D 的一個(gè)文檔:
db.inventory.deleteOne( { status: "D" } )