MongoDB常用操作

# MongoDB

## 數(shù)據(jù)庫分類

### 關(guān)系型數(shù)據(jù)庫

* 具備ACID特性

? ? * Atomic原子性刹缝,也就是說事務(wù)里的所有操作要么全部做完问慎,要么都不做惫叛,事務(wù)成功的條件是事務(wù)里的所有操作都成功奕锌,只要有一個(gè)操作失敗著觉,整個(gè)事務(wù)就失敗,需要回滾歇攻。*比如銀行轉(zhuǎn)賬固惯,從A賬戶轉(zhuǎn)100元至B賬戶梆造,分為兩個(gè)步驟:1)從A賬戶取100元缴守;2)存入100元至B賬戶。這兩步要么一起完成镇辉,要么一起不完成屡穗,如果只完成第一步,第二步失敗忽肛,錢會(huì)莫名其妙少了100元村砂。*

? ? * Consistency一致性,也就是說數(shù)據(jù)庫要一直處于一致的狀態(tài)屹逛,事務(wù)的運(yùn)行不會(huì)改變數(shù)據(jù)庫原本的一致性約束础废。*例如現(xiàn)有完整性約束a+b=10,如果一個(gè)事務(wù)改變了a罕模,那么必須得改變b评腺,使得事務(wù)結(jié)束后依然滿足a+b=10,否則事務(wù)*失敗淑掌。

? ? * Isolation獨(dú)立性蒿讥,所謂的獨(dú)立性是指并發(fā)的事務(wù)之間不會(huì)互相影響,如果一個(gè)事務(wù)要訪問的數(shù)據(jù)正在被另外一個(gè)事務(wù)修改抛腕,只要另外一個(gè)事務(wù)未提交芋绸,它所訪問的數(shù)據(jù)就不受未提交事務(wù)的影響。*比如現(xiàn)在有個(gè)交易是從A賬戶轉(zhuǎn)100元至B賬戶担敌,在這個(gè)交易還未完成的情況下摔敛,如果此時(shí)B查詢自己的賬戶,是看不到新增加的100元的全封。*

? ? * Durability持久性舷夺,持久性是指一旦事務(wù)提交后苦酱,它所做的修改將會(huì)永久的保存在數(shù)據(jù)庫上,即使出現(xiàn)宕機(jī)也不會(huì)丟失给猾。

* 局限性和不適用場景

? ? * 關(guān)系型數(shù)據(jù)庫為了維護(hù)一致性所付出的巨大代價(jià)就是其讀寫性能比較差疫萤。在網(wǎng)頁應(yīng)用中,尤其是SNS(社交)應(yīng)用中敢伸,一致性卻不是顯得那么重要扯饶,用戶A看到的內(nèi)容和用戶B看到同一用戶C內(nèi)容更新不一致是可以容忍的,或者說池颈,兩個(gè)人看到同一好友的數(shù)據(jù)更新的時(shí)間差那么幾秒是可以容忍的尾序,因此,關(guān)系型數(shù)據(jù)庫的最大特點(diǎn)在這里已經(jīng)無用武之地躯砰,起碼不是那么重要了每币。

? ? * 關(guān)系數(shù)據(jù)庫的另一個(gè)特點(diǎn)就是其具有固定的表結(jié)構(gòu),因此琢歇,其擴(kuò)展性比較差兰怠,而在SNS中,系統(tǒng)的升級(jí)李茫,功能的增加揭保,往往意味著數(shù)據(jù)結(jié)構(gòu)巨大變動(dòng),這一點(diǎn)關(guān)系型數(shù)據(jù)庫也難以應(yīng)付魄宏,需要新的結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)秸侣。

### **非關(guān)系型數(shù)據(jù)庫 NoSQL(Not Only SQL )**

*? NoSQL數(shù)據(jù)庫的四大分類

|分類 |舉例 |典型應(yīng)用場景 |數(shù)據(jù)模型 |優(yōu)點(diǎn) |缺點(diǎn) |

|--- |--- |--- |--- |--- |--- |

|鍵值(key-value)存儲(chǔ)數(shù)據(jù)庫 |Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB |內(nèi)容緩存,主要用于處理大量數(shù)據(jù)的高訪問負(fù)載宠互,也用于一些日志系統(tǒng)等等味榛。 |Key 指向 Value 的鍵值對(duì),通常用hash table來實(shí)現(xiàn) |查找速度快 |數(shù)據(jù)無結(jié)構(gòu)化予跌,通常只被當(dāng)作字符串或者二進(jìn)制數(shù)據(jù) |

|--- |--- |--- |--- |--- |--- |

|**列存儲(chǔ)數(shù)據(jù)庫** |Cassandra, HBase, Riak |分布式的文件系統(tǒng) |以列簇式存儲(chǔ)搏色,將同一列數(shù)據(jù)存在一起 |查找速度快,可擴(kuò)展性強(qiáng)匕得,更容易進(jìn)行分布式擴(kuò)展 |功能相對(duì)局限 |

|**文檔型數(shù)據(jù)庫** |CouchDB, MongoDb |Web應(yīng)用(與Key-Value類似继榆,Value是結(jié)構(gòu)化的,不同的是數(shù)據(jù)庫能夠了解Value的內(nèi)容) |Key-Value對(duì)應(yīng)的鍵值對(duì)汁掠,Value為結(jié)構(gòu)化數(shù)據(jù) |數(shù)據(jù)結(jié)構(gòu)要求不嚴(yán)格略吨,表結(jié)構(gòu)可變,不需要像關(guān)系型數(shù)據(jù)庫一樣需要預(yù)先定義表結(jié)構(gòu) |查詢性能不高考阱,而且缺乏統(tǒng)一的查詢語法翠忠。 |

|**圖形(Graph)數(shù)據(jù)庫** |Neo4J, InfoGrid, Infinite Graph |社交網(wǎng)絡(luò),推薦系統(tǒng)等乞榨。專注于構(gòu)建關(guān)系圖譜 |圖結(jié)構(gòu) |利用圖結(jié)構(gòu)相關(guān)算法秽之。比如最短路徑尋址当娱,N度關(guān)系查找等 |很多時(shí)候需要對(duì)整個(gè)圖做計(jì)算才能得出需要的信息,而且這種結(jié)構(gòu)不太好做分布式的集群方案考榨。 |

* Mongodb

? ? * 是文檔型的非關(guān)系型數(shù)據(jù)庫跨细,使用bson( Binary Serialized Document Format) 結(jié)構(gòu)。其優(yōu)勢(shì)在于查詢功能比較強(qiáng)大河质,能存儲(chǔ)海量數(shù)據(jù)冀惭。

# Mac OSX 平臺(tái)安裝Mongo

## 使用 brew 下載并安裝

1、終端輸入:brew install mongodb

2掀鹅、安裝成功后可以看到提示:

```

To have launchd start mongodb now and restart at login:

? brew services start mongodb

Or, if you don't want/need a background service you can just run:

? mongod --config /usr/local/etc/mongod.conf

==> Summary

??? /usr/local/Cellar/mongodb/4.0.0: 18 files, 268.4MB

```

## 運(yùn)行mongoDB服務(wù)

1散休、首先創(chuàng)建一個(gè)數(shù)據(jù)庫存儲(chǔ)目錄 /data/db,命令行輸入:sudo mkdir -p /data/db

2乐尊、創(chuàng)建日志文件:sudo vim /data/db/mongo.log戚丸;創(chuàng)建pid文件:sudo vim /var/run/mongo.pid

3、啟動(dòng) mongodb扔嵌,分兩種啟動(dòng)方式:

* 啟動(dòng)命令直接指定命令參數(shù)方式:sudo mongod -port 27017 -dbpath /data/db -fork? -pidfilepath=/var/run/mongo.pid? -logpath /data/db/mongo.log

* 啟動(dòng)命令指定配置文件方式:

? ? * 1限府、創(chuàng)建配置文件 :sudo vim /etc/mongodb.conf?


? ? *? ? 2、執(zhí)行:sudo mongo -f /etc/mongodb.conf

* 啟動(dòng)參數(shù)說明(可以通過mongo -help來查看全部參數(shù)):

? ? * -port arg? ? #指定服務(wù)端口號(hào)对人,默認(rèn)端口27017谣殊。

? ? * -dbpath? ? #? 指定存儲(chǔ)路徑拂共。

? ? * -logpath arg? ? # 指定MongoDB日志文件牺弄,注意是指定文件不是目錄。使用fork參數(shù)時(shí)因?yàn)槿罩緹o法寫到控制臺(tái)宜狐,所以需要同時(shí)使用logpath參數(shù)势告。

? ? * -pidfilepath arg? ? # 指定PID File 的完整路徑,如果沒有設(shè)置抚恒,則沒有PID文件咱台。

? ? * -fork? ? # 以守護(hù)進(jìn)程的方式運(yùn)行MongoDB,相當(dāng)于nohup “shell”? &用法俭驮。使用fork參數(shù)時(shí)因?yàn)槿罩緹o法寫到控制臺(tái)回溺,所以需要同時(shí)使用logpath參數(shù)。

? ? * -directoryperdb? ? # 設(shè)置每個(gè)數(shù)據(jù)庫將被保存在一個(gè)單獨(dú)的目錄

? ? * -maxConns arg? # 最大同時(shí)連接數(shù) 默認(rèn)2000

? ? * -auth? ? #用戶認(rèn)證混萝,默認(rèn)false遗遵,當(dāng)設(shè)置為true時(shí)候,進(jìn)入數(shù)據(jù)庫需要auth驗(yàn)證逸嘀,當(dāng)數(shù)據(jù)庫里沒有用戶车要,則不需要驗(yàn)證也可以操作。直到創(chuàng)建了第一個(gè)用戶崭倘,之后操作都需要驗(yàn)證翼岁。

啟動(dòng)成功后可以看到以下提示:

```

[initandlisten] waiting for connections on port 27017

forked process: 41540

child process started successfully, parent exiting

```

## 停止mongoDB服務(wù)

正常關(guān)閉方式:

* 前臺(tái)方式啟動(dòng)時(shí)类垫,命令行光標(biāo)鍵入CTRL+C

* 通過連接的客戶端關(guān)閉,首先連接mongo成功后

? ? * 第一步:use admin

? ? * 第二步:db.shutdownServer()

異常關(guān)閉再次啟動(dòng)報(bào)錯(cuò)時(shí):

* 使用kill進(jìn)程方式

? ? * ps -ef |grep mongo

? ? * kill -15 pid? ? #建議不要使用 ”kill -9 pid“琅坡,因?yàn)槿绻\(yùn)行在沒開啟日志(—journal)的情況下悉患,可能會(huì)造成數(shù)據(jù)損失。

> 注意:在mongodb的啟動(dòng)時(shí)榆俺,在數(shù)據(jù)目錄下购撼,會(huì)生成一個(gè)mongod.lock文件。如果在正常退出時(shí)谴仙,會(huì)清除這個(gè)mongod.lock文件迂求,若是異常退出,在下次啟動(dòng)的時(shí)候晃跺,會(huì)禁止啟動(dòng)揩局,并看到下面的報(bào)錯(cuò)。

```

? ? exception in initAndListen: DBPathInUse: Unable to lock the lock file:

? ? /data/db/mongod.lock (Resource temporarily unavailable). Another mongod instance is already running on the /data/db directory, terminating

```

## Mongo連接

### 客戶端連接

語法格式:mongo 遠(yuǎn)程主機(jī)ip或DNS:端口號(hào)/數(shù)據(jù)庫名 -u user -p password

例:連接本地?cái)?shù)據(jù)庫掀虎,在終端窗口輸入:mongo

```

~ ? mongo

MongoDB shell version v4.0.0

connecting to: mongodb://127.0.0.1:27017

MongoDB server version: 4.0.0

```

例:連接遠(yuǎn)程sit環(huán)境mongo數(shù)據(jù)庫

```

~ ? mongo 10.4.12.78/admin -u sit-user -p xxxxA5

MongoDB shell version v4.0.0

connecting to: mongodb://10.4.12.78:27017/admin

MongoDB server version: 3.2.12

```

### 標(biāo)準(zhǔn)uri連接

語法格式:mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

```

`#!/usr/bin/env python

``# -*- coding:utf-8 -*-

from pymongo import MongoClient

uri = 'mongodb://sit-user:xxxxqA5@10.4.12.78/admin'

con = MongoClient(uri)`

```

# MongoDB語法

## 概念術(shù)語

|SQL術(shù)語/概念 |MongoDB術(shù)語/概念 |解釋/說明 |

|--- |--- |--- |

|database |database |數(shù)據(jù)庫 |

|--- |--- |--- |

|table |collection |數(shù)據(jù)庫表/集合 |

|row |document |數(shù)據(jù)記錄行/文檔 |

|column |field |數(shù)據(jù)字段 |

|index |index |索引 |

|primary key |primary key |主鍵,MongoDB自動(dòng)將_id字段設(shè)置為主鍵 |


## 數(shù)據(jù)庫操作

### 創(chuàng)建數(shù)據(jù)庫

1凌盯、語法格式:use <database_name>? ? #如果數(shù)據(jù)庫存在時(shí)會(huì)切換到該數(shù)據(jù)庫,不存在時(shí)會(huì)創(chuàng)建該數(shù)據(jù)庫烹玉。

2驰怎、操作成功后可以看到提示:

```

> use sms

switched to db sms

```

### 刪除數(shù)據(jù)庫

1、語法格式:db.dropDatabase()? ? #刪除當(dāng)前使用的數(shù)據(jù)庫二打,可以通過命令“db”來查看當(dāng)前數(shù)據(jù)庫

2县忌、操作成功后可以看到提示:

```

> db? ? #查看當(dāng)前數(shù)據(jù)庫

sms

> db.dropDatabase()

{ "ok" : 1 }

```

## 集合操作

### 創(chuàng)建集合

1、語法格式:db.createCollection(<name>,{ <options>})? ? #name為要?jiǎng)?chuàng)建的集合名继效,options為可選參數(shù):

* capped? ? #布爾類型症杏,如果為 true,則創(chuàng)建固定集合瑞信。固定集合是指有著固定大小的集合厉颤,當(dāng)達(dá)到最大值時(shí),它會(huì)自動(dòng)覆蓋最早的文檔凡简。當(dāng)該值為 true 時(shí)逼友,必須指定 size 參數(shù)。

* size? ? #數(shù)值秤涩,為固定集合指定一個(gè)最大值(以字節(jié)計(jì))帜乞。如果 capped 為 true,也需要指定該字段**溉仑。**

* max? ? #數(shù)值挖函,指定固定集合中包含文檔的最大數(shù)量。

2、執(zhí)行:db.createCollection("seller",{ capped : true, size :6142800, max : 10000 }怨喘,創(chuàng)建集合成功后可以看到提示:

```

> db? ? #查看當(dāng)前數(shù)據(jù)庫

sms

> db.createCollection("seller",{ capped : true, size :6142800, max : 10000 })

{ "ok" : 1 }

```

### 刪除集合

1津畸、語法格式:db.collection_name.drop()

2、刪除集合成功后必怜,可以看到命令行返回“true”肉拓,否則返回“false”。

```

> show collections? ? #查看當(dāng)前數(shù)據(jù)庫下的集合

ark_open_api_account

seller

> db.ark_open_api_account.drop()

true

> show collections

seller

```

## 文檔操作

### 創(chuàng)建文檔

1梳庆、語法格式:db.collection_name.insert(<document>)

2暖途、執(zhí)行db.seller.insert({"role" : "partner","shopname" : "redqa009-測試","email" : "[xx@163.com](mailto:xx@163.com)"})?

```

> db.seller.insert({"role" : "partner","shopname" : "redqa009-測試","email" : "[xx@163.com](mailto:xx@163.com)"})

WriteResult({ "nInserted" : 1 })

> db.seller.find()? ? #查詢文檔

{ "_id" : ObjectId("5b554bd275f30ccd39ca6483"), "role" : "partner", "shopname" : "redqa009-測試", "email" : "xx@163.com" }

```

或? 先定義document后再執(zhí)行insert(document)

```

> document=([{"role" : "partner","shopname" : "redqa007品牌店","email" : "1401261542@qq.com"},{"role" : "partner","shopname" : "redqa018","email" : "qatest6@redqa.xyz"}])

[

{

"role" : "partner",

"shopname" : "redqa007品牌店",

"email" : "1401261542@qq.com"

},

{

"role" : "partner",

"shopname" : "redqa018",

"email" : "[qatest6@redqa.xyz](mailto:qatest6@redqa.xyz)"

}

]

> db.seller.insert(document)

BulkWriteResult({

"writeErrors" : [ ],

"writeConcernErrors" : [ ],

"nInserted" : 2,

"nUpserted" : 0,

"nMatched" : 0,

"nModified" : 0,

"nRemoved" : 0,

"upserted" : [ ]

})

> db.seller.find()

{ "_id" : ObjectId("5b554bd275f30ccd39ca6483"), "role" : "partner", "shopname" : "redqa009-測試", "email" : "[xx@163.com](mailto:xx@163.com)" }

{ "_id" : ObjectId("5b554ee875f30ccd39ca6484"), "role" : "partner", "shopname" : "redqa007品牌店", "email" : "xx@qq.com" }

{ "_id" : ObjectId("5b554ee875f30ccd39ca6485"), "role" : "partner", "shopname" : "redqa018","email" : "xxx@redqa.xyz" }

```

### 更新文檔

* update()方法

? ? * 1、語法格式:

```

db.collection.update(

<query>,

<update>,

{

upsert: <boolean>,? # 可選膏执,含義為如果不存在update的記錄驻售,是否插入objNew,true為插入,默認(rèn)是false更米,不插入欺栗。

multi: <boolean>,? # 可選,默認(rèn)是false,只更新找到的第一條記錄征峦,如果這個(gè)參數(shù)為true,就把按條件查出來多條記錄全部更新迟几。

writeConcern: <document>? # writeConcern** **:可選,拋出異常的級(jí)別栏笆。

}

)

```

? ? * 2类腮、更新shopname為"redqa009-測試1”商家的郵箱

? ? * 執(zhí)行'db.seller.update({shopname:"redqa009-測試1"},{$set:{email:"xx@163.com"}},{upsert:true})'

```

> db.seller.find()

{ "_id" : ObjectId("5b554bd275f30ccd39ca6483"), "role" : "partner", "shopname" : "redqa009-測試", "email" : "lxx@163.com" }

{ "_id" : ObjectId("5b554ee875f30ccd39ca6484"), "role" : "partner", "shopname" : "redqa007品牌店", "email" : "xx@qq.com" }

{ "_id" : ObjectId("5b554ee875f30ccd39ca6485"), "role" : "partner", "shopname" : "redqa018", "email" : "xx@redqa.xyz" }

> db.seller.update({shopname:"redqa009-測試1"},{$set:{email:"xx@163.com"}},{upsert:true})

WriteResult({

? ? "nMatched" : 0,

? ? "nUpserted" : 1,

? ? "nModified" : 0,

? ? "_id" : ObjectId("5b556dca30563a38f0284e00")

})

```

> 注意:當(dāng)集合為Capped collection時(shí),如果更新或替換操作更改了文檔大小蛉加,則操作將失敗蚜枢。錯(cuò)誤提示如下:

```

WriteResult({

? ? "nMatched" : 0,

? ? "nUpserted" : 0,

? ? "nModified" : 0,

? ? "writeError" : {

? ? ? ? "code" : 10003,

? ? ? ? "errmsg" : "Cannot change the size of a document in a capped collection: 79 != 77"

? ? }

})

```

* save()方法

? ? * 1、語法格式

```

db.collection.save(

? <document>,? ? # 根據(jù)文檔中的'_id'字段七婴,找到一個(gè)已經(jīng)存在的文檔祟偷,進(jìn)行更新察滑。

? {

? ? writeConcern: <document>

? }

)

```

> 補(bǔ)充:

> 當(dāng)文檔中包含'_id'字段打厘,但匹配不到已存在的文檔,也會(huì)將文檔插入數(shù)據(jù)庫贺辰。

> 當(dāng)文檔中不含'_id'字段户盯,save方法將調(diào)用insert方法,插入這條文檔并分配一個(gè)_id饲化。

### 刪除文檔

1莽鸭、語法格式:

```

db.collection.remove(

? <query>,? ? # 可選,刪除的文檔的條件。

? {

? ? justOne: <boolean>,? ? # 可選,如果設(shè)為 true 或 1吃靠,則只刪除一個(gè)文檔硫眨。

? ? writeConcern: <document>

? }

)

```

> 注意:Capped collection不允許使用remove()方法刪除,只能使用db.collection.drop()方法刪除集合巢块。db.collection.isCapped() 命令可以查看一個(gè)集合是否是 Capped Collection礁阁。

### 查詢文檔

```

1巧号、db.collection.find(query, projection) # 可選,query為查詢條件姥闭,可選丹鸿,projection指定返回的鍵。

```

### 比較操作符

* 大于:$gt

* 大于等于:$gte

* 小于:$lt

* 小于等于:$lte

* 等于:$eq

例:查詢訂單“total_discounted_price”大于等于100并且小于等于200的任意一個(gè)訂單號(hào)棚品。

```

db.order.findOne({total_discounted_price:{$gte:150,$lte:200}},{order_id:1})

#projection:1代表只返回指定字段靠欢,為0代表不返回該字段。

```

* 不等于:$ne

例:查詢商家("seller":"53df5710b4c4d6383ae8e9a6")任意一個(gè)不是“已取消”的訂單

```

db.order_package.find({"seller":"53df5710b4c4d6383ae8e9a6","status":{$ne:998}})

```

* 匹配數(shù)組中任意值:$in

例:查詢所有訂單狀態(tài)狀態(tài)為“待配貨”铜跑、“配貨中”或“已發(fā)貨”的訂單门怪。

```

db.order_package.find({ "status": {$in:[4,5,6]}})

```

* 不匹配數(shù)組中任意值:$nin

### 邏輯操作符

* 與查詢:$and

例:查詢商家("seller":"53df5710b4c4d6383ae8e9a6")所有訂單狀態(tài)狀態(tài)為“待配貨”、“配貨中”或“已發(fā)貨”的訂單锅纺。

```

db.order_package.find({$and:[{"seller":"53df5710b4c4d6383ae8e9a6"},{"status": {$in:[4,5,6]}}]})

等同于

db.order_package.find({ "seller":"53df5710b4c4d6383ae8e9a6","status": {$in:[4,5,6]}})

```

* 或查詢:$or

例:查詢訂單“total_discounted_price”小于等于100或大于等于200的訂單號(hào)薪缆。

```

db.order.find({$or:[{total_discounted_price:{$lte:100}},{total_discounted_price:{$gte:200}}]})

```

### 元素操作符

* 查詢是否存在某字段:$exists

例:查詢維護(hù)了貿(mào)易模式的所有商家。

```

db.seller.find({ "trade_mode":{$exists:true} })

```

*? 查詢數(shù)組中元素是否滿足指定的條件:$elemMatch

例:查詢所有支持“red_bonded”物流模式的商家伞广。

```

被查詢集合的數(shù)據(jù)結(jié)構(gòu):

{

? "_id": ObjectId("5a151d9deb90b912e76ee832"),

? "shopname": "redqa009-測試",

? "logistics_infos": [

? ? {

? ? ? "name": "red_auto",

? ? ? "logistics": "auto",

? ? ? "is_default": true

? ? },

? ? {

? ? ? "name": "red_bonded",

? ? ? "logistics": "bonded",

? ? ? "customs_code": "SHANGHAI",

? ? ? "is_default": false

? ? }

? ],

? "trade_mode": 0

}

寫法:

db.seller.find({ "logistics_infos":{$elemMatch:{name:"red_bonded"}} })

```

### 排序

* 升序

```

db.COLLECTION_NAME.find().sort({KEY:1})

```

* 降序

```

db.COLLECTION_NAME.find().sort({KEY:-1})

```

# MongoDB訪問權(quán)限控制

## 訪問控制參數(shù)

### **綁定IP地址**

* mongod 啟動(dòng)參數(shù):-bind_ip? <ip_address>?

默認(rèn)值是所有的IP地址都能訪問拣帽,該參數(shù)指定MongoDB對(duì)外提供服務(wù)的綁定IP地址,用于監(jiān)聽客戶端 Application的連接嚼锄,客戶端只能使用綁定的IP地址才能訪問mongod减拭,其他IP地址是無法訪問的。

### **設(shè)置監(jiān)聽端口**

* mongod 啟動(dòng)參數(shù):-port <port>? ?

MongoDB 默認(rèn)監(jiān)聽的端口是27017区丑,該參數(shù)顯式指定MongoDB實(shí)例監(jiān)聽的TCP 端口拧粪,只有當(dāng)客戶端Application連接的端口和MongoDB實(shí)例監(jiān)聽的端口一致時(shí),才能連接到MongoDB實(shí)例沧侥。

### **啟用用戶驗(yàn)證**

* mongod 啟動(dòng)參數(shù):-auth?

當(dāng)mongod 使用該參數(shù)啟動(dòng)時(shí)可霎,MongoDB會(huì)驗(yàn)證客戶端連接的賬戶和密碼,以確定其是否有訪問的權(quán)限宴杀。如果認(rèn)證不通過癣朗,那么客戶端不能訪問MongoDB的數(shù)據(jù)庫。

### **權(quán)限認(rèn)證**

* mongo 連接參數(shù):-username <username>, -u <username>

* mongo 連接參數(shù):-password <password>, -p <password>

* mongo 連接參數(shù):-authenticationDatabase <dbname> 指定創(chuàng)建User的數(shù)據(jù)庫旺罢;在特定的數(shù)據(jù)庫中創(chuàng)建User旷余,該DB就是User的authentication database。

在連接mongo時(shí)扁达,使用參數(shù) --authenticationDatabase正卧,會(huì)認(rèn)證 -u 和 -p 參數(shù)指定的賬戶和密碼。如果沒有指定驗(yàn)證數(shù)據(jù)庫跪解,mongo使用連接字符串中指定的DB作為驗(yàn)證數(shù)據(jù)塊炉旷。

```

mongo 10.4.12.78/admin -u sit-user -p xxxx4qA5 --authenticationDatabase "admin"

```

## **基于角色的訪問控制**

**內(nèi)置角色**

內(nèi)置角色是MongoDB預(yù)定義的角色,操作的資源是在DB級(jí)別上。MongoDB擁有一個(gè)SuperUser的角色:root窘行,擁有最大權(quán)限骏啰,能夠在系統(tǒng)的所有資源上執(zhí)行任意操作。

* 數(shù)據(jù)庫內(nèi)置用戶角色

? ? * read:授予User只讀數(shù)據(jù)的權(quán)限

? ? * readWrite:授予User讀寫數(shù)據(jù)的權(quán)限

* 數(shù)據(jù)庫內(nèi)置管理角色

? ? * dbAdmin:在當(dāng)前dB中執(zhí)行管理操作

? ? * dbOwner:在當(dāng)前DB中執(zhí)行任意操作

? ? * userAdmin:在當(dāng)前DB中管理User

* 所有數(shù)據(jù)庫角色

? ? * readAnyDatabase

? ? * readWriteAnyDatabase

? ? * userAdminAnyDatabase

? ? * dbAdminAnyDatabase

* 超級(jí)用戶角色

? ? * root

### 用戶創(chuàng)建

```

>? db.createUser({user: "jhh",pwd: "pwd",roles: [{role:"readWrite",db:"sms"}]})

Successfully added user: {

? ? "user" : "jhh",

? ? "roles" : [

? ? ? ? {

? ? ? ? ? ? "role" : "readWrite",

? ? ? ? ? ? "db" : "sms"

? ? ? ? }

? ? ]

}

```

> 補(bǔ)充:查看用戶授權(quán)情況可以在admin庫下通過db.system.users.find({user:"user_name"})查看抽高。

### **用戶的作用范圍**

在admin 數(shù)據(jù)庫中創(chuàng)建的角色判耕,作用范圍是全局的,能夠在admin翘骂,其他數(shù)據(jù)庫中使用壁熄,并且能夠繼承其他數(shù)據(jù)庫的角色;而在非admin中創(chuàng)建的角色碳竟,作用范圍是當(dāng)前數(shù)據(jù)庫草丧,只能在當(dāng)前DB中使用,只能繼承當(dāng)前數(shù)據(jù)庫的角色莹桅。

# MongoDB備份與恢復(fù)

MongoDB官方提供了兩套數(shù)據(jù)導(dǎo)入導(dǎo)出工具:一般來說昌执,進(jìn)行整庫導(dǎo)出導(dǎo)入時(shí)使用mongodump和mongostore,這一對(duì)組合操作的數(shù)據(jù)是BSON格式诈泼,進(jìn)行大量dump和restore時(shí)效率較高懂拾。進(jìn)行單個(gè)集合導(dǎo)出導(dǎo)入時(shí)使用mongoexport和mongoimport,這一對(duì)組合操作的數(shù)據(jù)是JSON格式铐达,可讀性較高岖赋。


## 數(shù)據(jù)庫備份與恢復(fù)

* mongodump腳本語法:mongodump -h dbhost -d dbname -o dbdirectory

? ? * -h:

? ? ? ? MongDB所在服務(wù)器地址,例如:127.0.0.1瓮孙,當(dāng)然也可以指定端口號(hào):127.0.0.1:27017

? ? * -d:

? ? ? ? 需要備份的數(shù)據(jù)庫實(shí)例唐断,例如:test

? ? * -o**:**

? ? ? ? 備份的數(shù)據(jù)存放位置,例如:\data\dump杭抠,當(dāng)然該目錄需要提前建立脸甘,在備份完成后,系統(tǒng)自動(dòng)在dump目錄下建立一個(gè)test目錄偏灿,這個(gè)目錄里面存放該數(shù)據(jù)庫實(shí)例的備份數(shù)據(jù)丹诀。

* mongorestore腳本語法:mongorestore -h <hostname><:port> -d dbname <path>

? ? * --host <:port>, -h <:port>:

? ? ? ? MongoDB所在服務(wù)器地址,默認(rèn)為: localhost:27017

? ? * --db , -d :

? ? ? ? 需要恢復(fù)的數(shù)據(jù)庫實(shí)例菩混,例如:test忿墅,當(dāng)然這個(gè)名稱也可以和備份時(shí)候的不一樣,比如test2

? ? * --drop:

? ? ? ? 恢復(fù)的時(shí)候沮峡,先刪除當(dāng)前數(shù)據(jù),然后恢復(fù)備份的數(shù)據(jù)亿柑。

? ? * <path>:

? ? ? ? mongorestore 最后的一個(gè)參數(shù)邢疙,設(shè)置備份數(shù)據(jù)所在位置,例如:\data\dump\test。

? ? ? ? 你不能同時(shí)指定 <path> 和 --dir 選項(xiàng)疟游,--dir也可以設(shè)置備份目錄呼畸。

? ? * --dir:

? ? ? ? 指定備份的目錄

? ? ? ? 你不能同時(shí)指定 <path> 和 --dir 選項(xiàng)。

## 集合導(dǎo)入與導(dǎo)出

* mongoexport語法:mongoexport -d dbname -c collectionname -o file --type json/csv -f field

? ? * -h:代表遠(yuǎn)程連接的數(shù)據(jù)庫地址颁虐,默認(rèn)連接本地Mongo數(shù)據(jù)庫

? ? * --port:代表遠(yuǎn)程連接的數(shù)據(jù)庫的端口蛮原,默認(rèn)連接的遠(yuǎn)程端口27017

? ? * -d :數(shù)據(jù)庫名

? ? *? -c :collection名

? ? *? -o :輸出的文件名,導(dǎo)出成功后文件會(huì)生成在當(dāng)前執(zhí)行路徑下另绩。

? ? *? --type : 輸出的格式儒陨,默認(rèn)為json

? ? *? -f :輸出的字段,如果-type為csv笋籽,則需要加上-f "字段名"蹦漠。

? ? * -q:代表查詢條件

? ? * -limit:讀取指定數(shù)量的數(shù)據(jù)記錄

例:從sit環(huán)境數(shù)據(jù)數(shù)據(jù)庫導(dǎo)出sms庫里seller集合任意5文檔到本地。

```

~ ? mongoexport -h=10.4.12.78 -d=sms -c=seller -o=seller.json

--limit=5 -u sit-user -p cDk%KVJA4qA5 --authenticationDatabase=admin --query '{logistics:"auto"}'

2018-07-24T12:50:18.992+0800 connected to: 10.4.12.78

2018-07-24T12:50:19.037+0800 exported 5 records

```

> 注意:這里一定要加—authenticationDatabase=admin指定use和password作為admin庫的驗(yàn)證车海,順序直接跟在-u和-p參數(shù)之后笛园,否則會(huì)作為 sms庫的驗(yàn)證,導(dǎo)致驗(yàn)證失斒讨ァ(猜測sit-user是admin庫下全局用戶研铆,在sms的庫用戶中不存在)。具體見“角色作用范圍”一節(jié)州叠。

* mongoimport語法:mongoimport -d dbname -c collectionname --file filename --headerline --type json/csv -f field

? ? *? -d :數(shù)據(jù)庫名

? ? *? -c :collection名

? ? *? --type :導(dǎo)入的格式默認(rèn)json

? ? *? -f :導(dǎo)入的字段名,type為json格式時(shí)不能指定蚜印。

? ? *? --headerline :如果導(dǎo)入的格式是csv,則可以使用第一行的標(biāo)題作為導(dǎo)入的字段

? ? *? --file :要導(dǎo)入的文件

例:將上面導(dǎo)出的seller.json文件導(dǎo)入到本地?cái)?shù)據(jù)庫sms下留量。

```

~ ? mongoimport -d sms? -c seller --file seller.json --type json

2018-07-24T13:39:05.380+0800? ? connected to: localhost

2018-07-24T13:39:05.394+0800? ? imported 5 documents

```

客戶端查看seller集合文檔條數(shù):

```

導(dǎo)入執(zhí)行前:

> db.seller.find().count();

2

導(dǎo)入執(zhí)行后:

> db.seller.find().count();

7

```

# 數(shù)據(jù)庫與緩存之間更新機(jī)制

## **緩存同步的常用模式**

緩存同步的模式窄赋,可以按照緩存的用途(主要用于讀或者寫)分為兩類:讀緩存的同步和寫緩存的同步。

讀緩存的同步:

### **緩存預(yù)加載模式**

提前將數(shù)據(jù)從數(shù)據(jù)庫加載到緩存楼熄,如果數(shù)據(jù)庫有寫更新忆绰,同步更新緩存。

### **緩存直讀模式**

應(yīng)用先查看緩存中是否有該數(shù)據(jù)可岂,有則直接使用错敢,如果沒有,從數(shù)據(jù)庫加載缕粹,然后放入緩存稚茅,下次以后再訪問就可以直接從緩存中獲得。

### **緩存直寫模式**

在數(shù)據(jù)更新時(shí)平斩,同時(shí)寫入緩存和數(shù)據(jù)庫亚享。這種模式是最穩(wěn)妥的辦法,但是性能會(huì)受到一定的影響绘面。

其中的過程是這樣的:

1.檢查用戶請(qǐng)求的數(shù)據(jù)是緩存中是否有存在欺税,如果有存在的話侈沪,只需要直接把請(qǐng)求的數(shù)據(jù)返回,無需查詢數(shù)據(jù)庫晚凿。

2.如果請(qǐng)求的數(shù)據(jù)在緩存中找不到亭罪,這時(shí)候再去查詢數(shù)據(jù)庫。返回請(qǐng)求數(shù)據(jù)的同時(shí)歼秽,把數(shù)據(jù)存儲(chǔ)到緩存中一份应役。

3.保持緩存的“新鮮性”,每當(dāng)數(shù)據(jù)發(fā)生變化的時(shí)候(比如燥筷,數(shù)據(jù)有被修改箩祥,或被刪除的情況下),要同步的更新緩存信息荆责,確保用戶不會(huì)在緩存取到舊的數(shù)據(jù)滥比。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市做院,隨后出現(xiàn)的幾起案子盲泛,更是在濱河造成了極大的恐慌,老刑警劉巖键耕,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寺滚,死亡現(xiàn)場離奇詭異,居然都是意外死亡屈雄,警方通過查閱死者的電腦和手機(jī)村视,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來酒奶,“玉大人蚁孔,你說我怎么就攤上這事⊥锖浚” “怎么了杠氢?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵碗硬,是天一觀的道長者甲。 經(jīng)常有香客問我,道長严望,這世上最難降的妖魔是什么摆尝? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任温艇,我火速辦了婚禮,結(jié)果婚禮上堕汞,老公的妹妹穿的比我還像新娘勺爱。我一直安慰自己,他們只是感情好臼朗,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布邻寿。 她就那樣靜靜地躺著蝎土,像睡著了一般视哑。 火紅的嫁衣襯著肌膚如雪绣否。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天挡毅,我揣著相機(jī)與錄音蒜撮,去河邊找鬼。 笑死跪呈,一個(gè)胖子當(dāng)著我的面吹牛段磨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播耗绿,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼苹支,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了误阻?” 一聲冷哼從身側(cè)響起债蜜,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎究反,沒想到半個(gè)月后寻定,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡精耐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年狼速,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卦停。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡向胡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出惊完,到底是詐尸還是另有隱情僵芹,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布专执,位于F島的核電站淮捆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏本股。R本人自食惡果不足惜攀痊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拄显。 院中可真熱鬧苟径,春花似錦、人聲如沸躬审。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至遭殉,卻和暖如春石挂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背险污。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來泰國打工痹愚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蛔糯。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓拯腮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蚁飒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子动壤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • 數(shù)據(jù)庫的基本操作 use db_name 創(chuàng)建數(shù)據(jù)庫 db 查看當(dāng)前連接的數(shù)據(jù)庫 show dbs 顯示所有數(shù)據(jù)庫...
    alonwang閱讀 810評(píng)論 0 1
  • MongoDB常用操作 一、增刪改查 查看當(dāng)前數(shù)據(jù)庫中所有的集合淮逻,使用命令 創(chuàng)建集合有兩種方式琼懊,顯示創(chuàng)建和隱式創(chuàng)建...
    我可能是個(gè)假開發(fā)閱讀 1,027評(píng)論 4 12
  • 一、數(shù)據(jù)庫常用命令1弦蹂、Help查看命令提示 2肩碟、切換/創(chuàng)建數(shù)據(jù)庫 當(dāng)創(chuàng)建一個(gè)集合(table)的時(shí)候會(huì)自動(dòng)創(chuàng)建當(dāng)前...
    十九樓的清風(fēng)閱讀 437評(píng)論 0 0
  • 一、MongoDB簡介 1.概述 ? MongoDB是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫凸椿,由C++語言編寫削祈。旨在為WE...
    鄭元吉閱讀 976評(píng)論 0 2
  • 周衛(wèi)平焦點(diǎn)網(wǎng)絡(luò)第十期堅(jiān)持分享第214天 當(dāng)事人之所以會(huì)前來晤談,常是因?yàn)樗麄兿M约骸案谩蹦月弧案谩笨赡苁窍肴プ?..
    心所安處閱讀 116評(píng)論 0 0