官方說明文檔:https://docs.mongodb.com/manual/mongo/
1 NoSQL 簡介
NoSQL,全稱是”Not Only Sql”,指的是非關系型的數據庫(相對於關系型數據庫RDBMS)。這類數據庫主要有這些特點:非關系型的、分布式的、開源的、水平可擴展的。
NOSQL數據庫相對於關系型數據庫主要解決的問題包括:
l 對數據庫高並發讀寫的需求(High performance)
l 對海量數據的高效率儲存和訪問的需求(Huge Storage)
l 對數據庫的高擴展性和高可用性的需求(High Scalability&&High vailability)
2 MongoDB 基礎知識
mongoDB是一種開源的文檔數據庫系統,開發語言為C++。它提供了一種高效的面向文檔的存儲結構,同時支持通過MapReduce程序來處理所存儲的文檔;它的擴展性很好,而且支持自動分區。Mapreduce可以用來實現數據聚合。它的數據以BSON(二進制JSON)格式存儲,在存儲結構上支持動態schema,並且允許動態查詢。和RDBMS的SQL查詢不同,Mongo查詢語言以JSON表示。
MongoDB是一個面向集合的,模式自由的文檔型數據庫。
l 面向集合(Collenction-Orented),是指數據被分組存儲在數據集中,每個集合在數據庫中都有一個唯一的標識名,並且可以包含無限數目的文檔。類似關系型數據庫(RDBMS)里的表(table),不同的是它不需要定義任何模式(schema)。
l 模式自由(schema-free),意味着對於存儲在MongoDB 數據庫中的文件,我們不需要知道它的任何結構定義。
l 文檔型,存儲的數據是鍵-值對的集合,鍵是字符串,值可以是數據類型集合里的任意類型, 這種數據格式被稱作 “BSON” 即 “Binary Serialized dOcumentNotation.”
2.1 數據邏輯結構
² MongoDB 的文檔(document),相當於關系數據庫中的一行記錄。
² 多個文檔組成一個集合(collection),相當於關系數據庫的表。
² 多個集合(collection),邏輯上組織在一起,就是數據庫(database)。
² 一個MongoDB 實例支持多個數據庫(database)。
邏輯結構對比 |
|
MongoDB |
SQL |
文檔(document) |
行(row) |
集合(collection) |
表(table) |
數據庫(database) |
數據庫(database) |
2.2 數據庫的安裝、啟動和關閉
數據庫的安裝很簡單,一路next即可。
數據庫的啟動:默認端口27017,默認HTTP端口28017
(在環境變量中創建path路徑C:\Program Files\MongoDB\Server\3.2\bin
,這樣可以在C:\workspace
路徑下命令行打開,不用輸儲存數據路徑)
l 命令行方式啟動
在安裝路徑bin
目錄下
下打開命令行,輸入下列語句:
C:\Program Files\MongoDB\Server\3.2\bin> mongod – dbpath C:\workspace\database
|
l 配置文件打開:
一般數據庫啟動時會有很多參數,為了方便,可以把配置參數放入配置文件然后打開。
- 在bin目錄下創建一個mongodb.cnf文件,文件內容如下:
dbpath = C:\workspace\database
- 在bin目錄下的命令行中輸入下列命令:
C:\Program Files\MongoDB\Server\3.2\bin>mongod -f mongodb.cnf
|
l Daemon方式打開(只能在Linux中使用,我們使用創建window服務方法代替)
(Daemon程序是一直運行的服務器程序,被稱為守護進程,通常作為系統服務在后台運行,沒有終端,不能和前台交互,在系統開啟時啟動在系統關閉后關閉)
在上兩種方式中都需要打開一個命令行窗口,一旦窗口關閉,服務隨之停止。所以為了使服務在窗口關閉之后能繼續使用,我們可以添加一個fork參數。需要注意的是在添加fork參數的同時應該添加logpath參數,這是強制性的。
C:\Program Files\MongoDB\Server\3.2\bin>mongod – dbpath C:\workspace\database – fork – logpath C:\workspace\database\log\r3.log
|
同上文標注的一樣,這種方法實際上只能在Linux系統中使用,windows系統中無法使用這種方法,但是作為一種變通,我們可以將mongoDB作為windows服務來啟動。
方法如下:
1.
首先在C:\workspace
路徑下創建
database
和
log
文件夾,在
log
文件夾下創建
mongo.log
文件
- 在bin目錄下打開命令行輸入下列語句
- 在創建服務成功后,在命令行中繼續輸入
C:\Program Files\MongoDB\Server\3.2\bin> mongod -dbpath c:\workspace\database --logpath c:\workspace\log\mongo.log --install --serviceName "MongoDB"
|
C:\Program Files\MongoDB\Server\3.2\bin>net start mongodb
|
可以看到命令行中打印出來mongoDB服務已經啟動成功。
數據庫的關閉:
如果使用的是前兩中的數據庫啟動方法
- 在命令行窗口下按ctrl+C
- 在命令行窗口中輸入指令d
b.shutdownServer()
C:\Program Files\MongoDB\Server\3.2\bin> db.shutdownServer()
|
使用windows服務啟動的方法
- 關閉服務,在bin目錄下打開命令行輸入
|
- 刪除服務,在bin目錄下打開命令行輸入
|
- 輸入啟動命令可以看到命令行中打出 “服務名無效的提示”
2.3數據庫的訪問控制
訪問控制一般是考慮到安全方面的因素,在開發環境中通常不用設置,但在生產環境中需要仔細考慮。訪問控制包含三個方面:IP綁定,設置監聽端口,使用用戶名和口令登陸
l 綁定IP內網地址
添加一個bind_ip參數即可實現綁定
|
在綁定內網后,客戶端訪問時必須輸入服務端的ip,否則報錯,如
|
l 設置監聽端口
官方默認的端口為27017,為了避免惡意連接,可以修改端口,添加-port參數
|
同樣客戶端在訪問時需要添加端口號
|
l 使用用戶名和密碼登錄
在服務端啟動時添加auth參數即可開啟登陸驗證模塊
|
但是,如果我們的admin.system.users中沒有添加任何用戶時,登陸驗證模塊是沒有用的,直到我們添加了一個用戶。
|
這時,我們輸入命令查看驗證
|
這時如果我們如果想操作數據庫就需要輸入用戶名和密碼了
|
3 MongoDB的操作
下面的所有操作都需要在啟動mongoDB服務的情況下進行,同時這些操作都可以使用圖形化工具運行,這里使用的是robomongo工具。
3.1 連接數據庫
如果我們想進入數據庫后台管理部分,我們需要進入bin目錄下,打開命令行輸入mongo命令:
|
命令行會提醒connect to本地數據庫中的test數據庫。
3.2 創建和刪除數據庫
假設我們創建一個名為Sample的數據庫,輸入use Sample
命令
|
我們可以使用show dbs命令查看所有的數據庫
|
這時並沒有發現我們新建的數據庫,這是因為新建的數據庫沒有數據,我們需要向里面插入數據才會顯示,我們插入一段數據:
|
然后在show dbs命令下就能看到我們新建的數據庫了
同時,如果我們需要切換數據庫,我們也可以使用use+數據庫名的命令
如果我們想要刪除這個數據庫,我們可以使用db.dropDatabase()命令
- 首先使用show dbs命令顯示所有的數據庫
|
- 使用use命令指向這個數據庫
|
- 使用db.dropDatabase命令刪除這個數據庫
|
注意事項:有些數據庫的名稱是保留的,可以直接訪問
admin: 從權限的角度來看,這是"root"數據庫。要是將一個用戶添加到這個數據庫,這個用戶自動繼承所有數據庫的權限。一些特定的服務器端命令也只能從這個數據庫運行,比如列出所有的數據庫或者關閉服務器。
local: 這個數據永遠不會被復制,可以用來存儲限於本地單台服務器的任意集合
config: 當Mongo用於分片設置時,config數據庫在內部使用,用於保存分片的相關信息。
3.3文檔的增刪改查
假如我們對Sample數據庫進行增刪改查的操作,首先使用use命令定位到該數據庫。
l
文檔的插入:db.Sample.insert
(),括號里面是插入的內容
|
也可以先用變量定義文檔內容,然后直接插入,如:
>document = {title:
”
Sample
”
}
>db.Sample.insert(document)
l
文檔的查看:db.Sample.find()
|
這個方法返回的是一串非結構化的數據
通常我們可以使用db
.Sample.find().pretty()
方法來返回結構化數據
在
find
方法里面可以插入參數來作為查找條件
.
1.
AND條件:db.Sample.find(
{key1:value1,key2:value2}
)
.pretty()
2.
OR條件:db.Sample.find(
{$or:{key1:value1,key2:value2} }
)
.pretty()
3.
ANG
和
OR
條件同時使用:
db.Sample.find(
{
key1:value1,
$or:{key1:value1,key2:value2}
}
)
.pretty()
l 文檔的更新:
1. 使用update方法: db.Sample.update(),前面的是查詢的條件,后面的是替換的內容
|
Update()函數主要是用於已經存在數據的更新,下面介紹了他的參數及各個參數的作用。
db.
Sample
.update(
<query>,
//
查詢條件
<update>,
//
更新的對象及操作符
{
upsert: <boolean>,
//
可選
true
或
false
,如果值不存在判斷是否插入
multi: <boolean>,
//
可選
true
或
false
,默認為
false
,只更新找到的第一個記錄,
true
為更新找到的全部記錄
writeConcern: <document>
//
可選
拋出異常的級別
}
)
2. 使用save()方法通過傳入新的文檔來替代原有文檔
|
l 文檔的刪除操作
建議:在執行刪除操作前先用find()方法來判斷條件是否正確
使用remove()方法:
|
db.collection.remove(
<query>,
//
查詢條件
{
justOne: <boolean>,
//
可選,
true
為只刪除一條數據
writeConcern: <document>
//
可選,拋出異常的級別
}
)
3.4
操作符與
limit
、
skip
方法
數據庫的操作符包括條件操作符和
$type
操作符
l
條件操作符
|
|
|
|
|
|
|
|
|
|
|
|
使用方法如下:
查找
number
值大於
100
的文檔
|
查找
number
值大於
100
小於
200
的文檔
|
l
$type
操作符
此方法是根據
BSON
數據格式來檢索集合中匹配的數據,格式如下:
|
$type
的值是跟表中類型對應的數字。如下
類型 |
數字 |
備注 |
Double |
1 |
|
String |
2 |
|
Object |
3 |
|
Array |
4 |
|
Binary data |
5 |
|
Undefined |
6 |
已廢棄。 |
Object id |
7 |
|
Boolean |
8 |
|
Date |
9 |
|
Null |
10 |
|
Regular Expression |
11 |
|
JavaScript |
13 |
|
Symbol |
14 |
|
JavaScript (with scope) |
15 |
|
32-bit integer |
16 |
|
Timestamp |
17 |
|
64-bit integer |
18 |
|
Min key |
255 |
Query with -1. |
Max key |
127 |
|
類型 |
數字 |
備注 |
Double |
1 |
|
String |
2 |
|
Object |
3 |
|
Array |
4 |
|
Binary data |
5 |
|
Undefined |
6 |
已廢棄。 |
Object id |
7 |
|
Boolean |
8 |
|
Date |
9 |
|
Null |
10 |
|
Regular Expression |
11 |
|
JavaScript |
13 |
|
Symbol |
14 |
|
JavaScript (with scope) |
15 |
|
32-bit integer |
16 |
|
Timestamp |
17 |
|
64-bit integer |
18 |
|
Min key |
255 |
Query with -1. |
Max key |
127 |
|
l
L
imit()
方法:限制查找到數據的個數
|
限制查找到數據的值為三個
l
S
kip()
方法:跳過制定數量的數據
|
查找到的數據跳過
3
個
l
$exists
方法
:
查找字段是否存在
|
這種方法可以用來判斷數據值為
null
還是不存在。例如查找
rollbackTime
類的值為
null
的文檔
|
其中
$in
為查找內容
(include
的縮寫
)
,必須是數組
l
$mod
方法:取模運算
|
查找
number
中模
5
為
0
的值
l
$ne
方法:不等於
|
查找
number
中不等於
11
的值
l
$in
方法:包含
|
查找
number
中等於
11,12
的值
$nin
方法是同樣的用法,意為不包含
l
$size
方法:數組元素的格式
|
查找
something
中數組長度為
3
的項
l
對指定字段進行排序
|
根據
number
字段進行排序,
1
代表正序,
-1
代表倒序
3.5
正則表達式匹配
Mongo
DB
數據庫的查詢用到的是
js
的語法,所以可以使用正則表達式進行匹配
|
查找
reason
中不以
h
開頭的項
3.6
數據庫的索引和聚合
l
索引
(
涉及
性能優化
部分
)
索引是一種特殊的數據結構,存在一個易於讀取的數據結構中,它是對數據庫中一個或多個值進行排序的一種結構,創建索引的格式如下:
|
K
ey
為要創建的索引字段,
1
代表的是按升序創建
,2
代表降序創建
Parameter |
Type |
Description |
background |
Boolean |
建索引過程會阻塞其它數據庫操作,background可指定以后台方式創建索引,即增加 "background" 可選參數。 "background" 默認值為false。 |
unique |
Boolean |
建立的索引是否唯一。指定為true創建唯一索引。默認值為false. |
name |
string |
索引的名稱。如果未指定,MongoDB的通過連接索引的字段名和排序順序生成一個索引名稱。 |
dropDups |
Boolean |
在建立唯一索引時是否刪除重復記錄,指定 true 創建唯一索引。默認值為 false. |
sparse |
Boolean |
對文檔中不存在的字段數據不啟用索引;這個參數需要特別注意,如果設置為true的話,在索引字段中不會查詢出不包含對應字段的文檔.。默認值為 false. |
expireAfterSeconds |
integer |
指定一個以秒為單位的數值,完成 TTL設定,設定集合的生存時間。 |
v |
index version |
索引的版本號。默認的索引版本取決於mongod創建索引時運行的版本。 |
weights |
document |
索引權重值,數值在 1 到 99,999 之間,表示該索引相對於其他索引字段的得分權重。 |
default_language |
string |
對於文本索引,該參數決定了停用詞及詞干和詞器的規則的列表。 默認為英語 |
language_override |
string |
對於文本索引,該參數指定了包含在文檔中的字段名,語言覆蓋默認的language,默認值為 language. |
例如我們創建一個索引
|
如果我們想在后台創建索引的話,
只需要加個參數
background:true
|
查看已創建的索引
|
l
數據庫聚合方法(
mapReduce,
進行並行統計
)
聚合的方法主要是用來處理數據(如求平均值,求和等)
,
並返回處理結果
|
這個方法里面使用了管道的概念,即將當前命令的結果作為下個命令的參數
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
聚合框架中常用的幾個操作:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
例如:
|
其中聚合操作先匹配
number
值大於
5
小於
16
,在得出的結果中跳過第一個,執行下面的修改文檔結構工作
3.7
其他操作
l Count查詢記錄的條數
在find后面加上count方法可以顯示查找到的數據的個數,比如
|
l Skip可以用來限制返回記錄的起點
|
表示查詢到的數據跳過兩條,顯示三條
l 查看活動進程,了解系統正在干什么
|
顯示結果中參數的含義:
Opid |
操作進程號 |
Op |
操作類型(查詢,更新等) |
Ns |
命名空間,指操作對象 |
Query |
顯示查詢操作中的具體內容 |
lockType |
指明是讀鎖還是寫鎖 |
l 結束進程
|
1234為opid
4存儲過程
MongoDB支持儲存過程,並且可以在儲存過程中自定義處理數據,使用的是JavaScript語法。數據庫的存儲過程是在db.system.js表里面的。方法如下:
- 首先將自定義的方法轉化為存儲過程
|
這里添加了一個get
_counts
的方法,value的值就是方法的具體內容,可以使用find方法查看過程是否被儲存
|
- 使用eval函數來調用自定義的方法(eval函數里面也可以直接定義並調用方法)
|
5 GridFS:MongoDB存儲大型文件的規范
由於MongoDB中BSON對象的大小是有限制的,所以采用GridFS規范來將一個大文件分隔成多個小文件,使得數據庫可以存儲視頻,高清圖片之類的大文件。這個規范支持Java,Perl,PHP,Python,Ruby等程序
5.1 簡介
GridFS使用兩個表來存儲數據:
- files包含元數據對象
- chunks包含相關信息的二進制塊
為保證多個GridFS命名為一個單一的數據庫,文件和塊都有一個前綴,默認為fs,所以任何的GridFS存儲都會包括fs.files和fs.chunks。前綴fs可以被修改。
5.2 使用方法
我們以存入一個pdf文檔為例,
|
-d參數指定的是數據庫名稱,如果沒有,會自動增加一個名為test的數據庫。
我們可以查看一下數據庫中有哪些GridFS文件
|
同時也可以使用find命令查看文件內容
|
6 Mapreduce計算模型
將大批量的工作分解(MAP)執行,再將結果合並(reduce)成最終的結果。可以用來構建大型的復雜的聚合查詢
它命令的基本語法是:
>db.collection.mapReduce(
function() {emit(key,value);}, //map
函數
function(key,values) {return reduceFunction}, //reduce
函數
{
out: collection,
//
統計結果存放集合,不指定則使用臨時集合
query: document,
//
篩選條件
sort: document,
//
排序函數
limit: number
//
限制發往
map
函數的文檔數量
}
)
例如:我們現在要找到
number
值相同的
_id
。
1.
首先寫
map
函數
|
其中
_id
是要統計的數據,
number
為分組的依據,
map
函數實現的是分組功能
2.
編寫
reduce
函數
|
這里
reduce
函數處理分組后的數據
3.
編寫
finalize
函數
|
f
函數用來做最后的處理
4.
運行函數
|
5.
使用
find
函數來查詢處理后的結果
|
結果參數:
result:儲存結果的collection的名字,這是個臨時集合,MapReduce的連接關閉后自動就被刪除了。
timeMillis:執行花費的時間,毫秒為單位
input:滿足條件被發送到map函數的文檔個數
emit:在map函數中emit被調用的次數,也就是所有集合中的數據總量
ouput:結果集合中的文檔個數(count對調試非常有幫助)
ok:是否成功,成功為1
7 MongoDB工具
MongoDB數據庫暗轉目錄下有幾個工具可以進行導入導出及備份恢復的功能。
包括:
mongo.exe 客戶端程序,連接MongoDB
mongod.exe 服務端程序,啟動MongoDB
mongo.exe 備份程序
mongoexport.exe 數據導出程序
mongofiles.exe GridFS工具,內建的分布式文件系統
mongostat.exe 狀態監測工具,固定時間獲取數據庫的運行狀態。
mongotop.exe 默認返回每個集合每一秒讀入寫出的狀態
mongoimport.exe 數據導入程序
mongorestore.exe 數據恢復程序
mongos.exe 數據分片程序,支持數據的橫向擴展
mongodump.exe 備份程序
bsondump.exe 用於將導出的bson格式轉變成json格式
mongoperf.exe 獨立檢查數據庫I/O性能的工具
7.1 GUI工具
MongoDB有很多的GUI管理工具:
l MongoVUE 主頁:http://www.mongovue.com/
l RockMongo 主頁:http://code.google.com/p/rock-php/
l MongoHub 主頁:https://github.com/bububa/MongoHub
l Robomongo 主頁:https://robomongo.org/
我用的是robomongo
7.2 監控
在mongoDB中有兩種自帶的監控工具來監控數據庫的運行情況
l 工具mongostat
間隔固定時間獲取數據庫當前的運行狀態
|
l 工具mongotop
獲取每一個集合每一秒讀取寫入的信息
|
可以在命令后面跟一個數字作為參數(sleeptime)來設定獲取信息的時間間隔
命令行打印信息參數含義:
ns |
數據庫的名稱和集合 |
Total |
在這個集合中操作花費的時間總和 |
Read |
讀入操作花費的時間 |
Write |
寫入操作花費的時間 |
7.3 數據導入和導出
輸入命令中各個參數的含義:
-d :數據庫名稱 -c:集合名稱 --csv是數據格式csv
-f :指名導出那些類 -o:導出文件的名稱
l 數據導入:mongoimport
導入JSON數據
|
導入csv格式數據
|
其中,--type 指定的是導入數據的格式,-headerline指的是忽略導入數據的第一行(因為是類),-file指的是導入文件的路徑。
l 數據導出:mongoexport工具
|
我們可以查看導出的文件,可以發現是JSON格式的。同理我們可以導出csv格式的數據。
|
7.4 數據備份和恢復
l 數據備份:mongodump
|
這個命令會創建一個dump文件夾,備份的文件都放在這個文件夾里,也可以指定-o參數,將備份文件放入指定文件夾
l 數據恢復:mongorestore
數據恢復分為兩種情況:原數據已刪除和原數據未刪除
實際操作中直接執行mongorestore命令即可恢復dump中的數據庫
- 源數據已刪除
|
- 原數據未刪除,在上個命令中加入-drop參數
|