NoSql數(shù)據(jù)庫優(yōu)缺點(diǎn)
在優(yōu)勢(shì)方面主要體現(xiàn)在下面幾點(diǎn):
簡(jiǎn)單的擴(kuò)展
快速的讀寫
低廉的成本
靈活的數(shù)據(jù)模型
在不足方面主要有下面幾點(diǎn):
不提供對(duì)SQL的支持
支持的特性不夠豐富
現(xiàn)有的產(chǎn)品不夠成熟
MongoDB簡(jiǎn)介
MongoDB是用C++語言編寫的非關(guān)系型數(shù)據(jù)庫。特點(diǎn)是高性能、易部署、易使用,存儲(chǔ)數(shù)據(jù)十分方便,主要特性有:+
面向集合存儲(chǔ),易于存儲(chǔ)對(duì)象類型的數(shù)據(jù)
模式自由
支持動(dòng)態(tài)查詢
支持完全索引,包含內(nèi)部對(duì)象
支持復(fù)制和故障恢復(fù)
使用高效的二進(jìn)制數(shù)據(jù)存儲(chǔ),包括大型對(duì)象
文件存儲(chǔ)格式為BSON(一種JSON的擴(kuò)展)
MongoDB基本概念介紹
文檔(document)是MongoDB中數(shù)據(jù)的基本單元,非常類似于關(guān)系型數(shù)據(jù)庫系統(tǒng)中的行(但是比行要復(fù)雜的多)
集合(collection)就是一組文檔,如果說MongoDB中的文檔類似于關(guān)系型數(shù)據(jù)庫中的行,那么集合就如同表
MongoDB的單個(gè)計(jì)算機(jī)可以容納多個(gè)獨(dú)立的數(shù)據(jù)庫,每一個(gè)數(shù)據(jù)庫都有自己的集合和權(quán)限
MongoDB自帶簡(jiǎn)潔但功能強(qiáng)大的JavaScript shell,這個(gè)工具對(duì)于管理MongoDB實(shí)例和操作數(shù)據(jù)作用非常大
每一個(gè)文檔都有一個(gè)特殊的鍵"_id",它在文檔所處的集合中是唯一的,相當(dāng)于關(guān)系數(shù)據(jù)庫中的表的主鍵
MongoDB數(shù)據(jù)類型
數(shù)據(jù)類型描述舉例
null表示空值或者未定義的對(duì)象{"x":null}
布爾值真或者假:true或者false{"x":true}
32位整數(shù) ? ? ? ? ?32位整數(shù)。shell是不支持該類型的,shell中默認(rèn)會(huì)轉(zhuǎn)換成64位浮點(diǎn)數(shù)
64位整數(shù) ? ? ? ? ?64位整數(shù)。shell是不支持該類型的,shell中默認(rèn)會(huì)轉(zhuǎn)換成64位浮點(diǎn)數(shù)
64位浮點(diǎn)數(shù) ? ? ?64位浮點(diǎn)數(shù)。shell中的數(shù)字就是這一種類型{"x":3.14,"y":3}
字符串UTF-8字符串{"foo":"bar"}
符號(hào)shell不支持,shell會(huì)將數(shù)據(jù)庫中的符號(hào)類型的數(shù)據(jù)自動(dòng)轉(zhuǎn)換成字符串
對(duì)象id文檔的12字節(jié)的唯一id{"id": ObjectId()}
日期從標(biāo)準(zhǔn)紀(jì)元開始的毫秒數(shù){"date":new Date()}
正則表達(dá)式 ? ? ?文檔中可以包含正則表達(dá)式,遵循JavaScript的語法 ?{"foo":/foobar/i}
代碼文檔中可以包含JavaScript代碼{"x":function() {}}
未定義undefined{"x":undefined}
數(shù)組值的集合或者列表{"arr": ["a","b"]}
內(nèi)嵌文檔 ? ? ? ? ?文檔可以作為文檔中某個(gè)key的value{"x":{"foo":"bar"}}
1 安裝MongoDB
MongoDB的安裝非常簡(jiǎn)單,只需要將下載的MongoDB的壓縮文件解壓到任意目錄,并將其中的bin目錄加入到系統(tǒng)的path環(huán)境變量中即可。
2 啟動(dòng)MongoDB
在啟動(dòng)MongoDB之前,要手動(dòng)創(chuàng)建一個(gè)存放MongoDB數(shù)據(jù)文件的目錄,如D:\mongo_data在命令行執(zhí)行 mongod --dbpath=D:\mongo_data
小技巧:手動(dòng)創(chuàng)建一個(gè)后綴為bat的文件,文件名任意,內(nèi)容為: mongod --dbpath=D:\mongo_data,雙擊此文件就可以啟動(dòng)MongoDB服務(wù),
不用每次都到命令行執(zhí)行啟動(dòng)命令
在啟動(dòng)服務(wù)器的shell下可以鍵入Ctrl-C來完全的停止mongod的運(yùn)行
3 連接到MongoDB服務(wù)器
重新開啟一個(gè)命令行 運(yùn)行mongo命令
輸入mongo命令默認(rèn)連接到本地的名稱為test的數(shù)據(jù)庫,如果希望連接到遠(yuǎn)程數(shù)據(jù)庫,可以使用mongo ip:port
4 常用命令
數(shù)據(jù)庫操作
創(chuàng)建數(shù)據(jù)庫,使用命令 use 數(shù)據(jù)庫名稱
use 命令后跟的數(shù)據(jù)庫名,如果存在就進(jìn)入此數(shù)據(jù)庫,如果不存在就創(chuàng)建,所以這種創(chuàng)建方式又叫隱式創(chuàng)建
注意:使用命令use mydb1創(chuàng)建數(shù)據(jù)庫后,并沒有真正生成對(duì)應(yīng)的數(shù)據(jù)文件,如果此時(shí)退出,此數(shù)據(jù)庫將被刪除,只有在此數(shù)據(jù)庫中創(chuàng)建集合后,才會(huì)真正生成數(shù)據(jù)文件
查看所有數(shù)據(jù)庫,使用命令 show dbs
查看當(dāng)前所在數(shù)據(jù)庫,使用命令 db
集合操作
查看當(dāng)前數(shù)據(jù)庫中所有的集合,使用命令 show collections 或使用show tables
創(chuàng)建集合有兩種方式,顯示創(chuàng)建和隱式創(chuàng)建
顯示創(chuàng)建可以使用命令 db.createCollection("集合名稱")
隱式創(chuàng)建可以使用命令 db.集合名稱.insert({}),指創(chuàng)建集合并同時(shí)向集合中插入數(shù)據(jù),例如:db.customer.insert({name:”jack”})
刪除集合使用命令:db.集合名稱.drop()
向集合添加文檔,使用命令 db.集合名稱.insert({}),例如:db.user1.insert({name:”jack”,age:20})
可以使用下面的循環(huán)語句批量插入多個(gè)文檔
for(var i=0;i<1000;i++){
db.hjb.insert({name:”name”+i ,age:i});
}
還可以使用db.集合名稱.save({})向集合中添加文檔,save于insert不同之處為:
使用insert如果插入的文檔中_id已經(jīng)存在,則不能插入,類似于關(guān)系型數(shù)據(jù)庫中的主鍵沖突
save方法如果插入的文檔中_id已經(jīng)存在,則執(zhí)行更新
刪除集合中的文檔,使用命令 db.集合名稱.remove({刪除條件}),不加刪除條件為刪除集合中的所有文檔,
例如,db.c1.remove() 為刪除c1集合中的所有文檔,db.c1.remove({name:”user1”})為刪除c1集合中name為user1的文檔
查詢集合中的文檔,可以使用命令 db.集合名稱.find({條件}),或者使用 db.集合名稱.findOne() ?查詢第一個(gè)文檔
db.customer.find()
db.customer.find({name:"name5"}) 查詢customer集合中name為name5的文檔
查詢集合中的文檔,返回某些特定的鍵值
//返回除了age字段外的所有字段
db.user.find({age:0});
//返回tags=tennis除了comments的所有列
db.posts.find({tag:'tennis'},{comments:0})
//返回userid=16的name字段
db.user.find({userid:16},{name:1});
{"_id":16,"name":"user16"}
//返回x=john的所有z字段
db.things.find({x:"john"},{z:1});
查詢集合中的文檔 ,使用條件表達(dá)式(<, <=, >, >=,!=)
//大于: field > value
db.collection.find({field:{$gt:value}});
//小于: field < value
db.collection.find({field:{$lt:value}});
//大于等于: field >= value
db.collection.find({field:{$gte:value}});
//小于等于: field <= value
db.collection.find({field:{$lte:value}});
//不等于: ?field != value
db.collection.find({field:{$ne:value}});
查詢集合中的文檔 ,統(tǒng)計(jì)(count)、排序(sort)、分頁(skip、limit)
db.customer.count();
db.customer.find().count();
db.customer.find({age:{$lt:5}}).count();
db.customer.find().sort({age:1}); 降序-1
db.customer.find().skip(2).limit(3);
db.customer.find().sort({age:-1}).skip(2).limit(3);
db.customer.find().sort({age:-1}).skip(2).limit(3).count();
db.customer.find().sort({age:-1}).skip(2).limit(3).count(0);
db.customer.find().sort({age:-1}).skip(2).limit(3).count(1);
查詢集合中的文檔 ,$all主要用來查詢數(shù)組中的包含關(guān)系,查詢條件中只要有一個(gè)不包含就不返回
db.c2.insert({name:"user1",post:[1,2,3,4,5]});
查詢集合中的文檔 ,$in,類似于關(guān)系型數(shù)據(jù)庫中的IN
db.cunstomer.find({age:{$in:[3,5,7]}})
查詢集合中的文檔 ,$nin,與$in相反
db.customer.find({age:{$nin:[4]}})
查詢集合中的文檔 ,$or,相當(dāng)于關(guān)系型數(shù)據(jù)庫中的OR,表示或者的關(guān)系,例如查詢name為user2或者age為3的文檔,命令為:
db.customer.find({$or:[{name:”user2”},{age:3}]})
查詢集合中的文檔 ,$nor,表示根據(jù)條件過濾掉某些數(shù)據(jù),例如查詢name不是user2,age不是3的文檔,命令為:
db.customer.find({$nor:[{name:”user2”},{age:3}]})
查詢集合中的文檔 ,$exists,用于查詢集合中存在某個(gè)鍵的文檔或不存在某個(gè)鍵的文檔,例如查詢customer集合中存在name鍵的所有文檔,可以使用 db.customer.find({name:{$exists:1}}),
$exists:1表示真,指存在
$exists:0表示假,指不存在
查詢集合中的文檔 ,類似于關(guān)系型數(shù)據(jù)庫,mongodb中也有游標(biāo)的概念
var x =db.customer.find()
x.hasNext()
x.next()
更新集合中的文檔,語法如下:
db.collection.update(criteria,objNew,upsert,multi)
參數(shù)說明:
criteria:用于設(shè)置查詢條件的對(duì)象
objNew:用于設(shè)置更新內(nèi)容的對(duì)象
upsert:如果記錄已經(jīng)存在,更新它,否則新增一個(gè)記錄,取值為0或1
multi:如果有多個(gè)符合條件的記錄,是否全部更新,取值為0或1
注意:默認(rèn)情況下,只會(huì)更新第一個(gè)符合條件的記錄
一般情況下后兩個(gè)參數(shù)分別為0,1 ,即:
db.collection.update(criteria,objNew,0,1)
更新集合中的文檔,將集合中name為user1的文檔改成name為jack
db.c1.update({name:"user1"},{name:"jack"})
這種修改有兩個(gè)問題,就是會(huì)使用新文檔覆蓋原來的文檔,如果原來文檔有多個(gè)鍵,修改后就有可能被覆蓋只剩下一個(gè)鍵了
第二個(gè)問題為即使符合更新條件的文檔有多個(gè)也只會(huì)更新第一個(gè)符合條件的記錄
更新集合中的文檔, $set 用來指定一個(gè)鍵的值,如果這個(gè)鍵不存在,則創(chuàng)建它。例如:
給name為user1的文檔添加address,可以使用命令:
db.c1.update({name:”user1”},{$set:{address:”bj”}},0,1)
將name為user1的文檔修改address為tj,其它鍵值對(duì)不變,命令為:
db.c1.update({name:”user1”},{$set:{address:”tj”}},0,1)
更新集合中的文檔,使用 $inc 將集合中name為user1的age加1,其它鍵不變, $inc表示使某個(gè)鍵值加減指定的數(shù)值
db.c1.update({name:"user1"},{$inc:{age:1}})
db.c1.find()
更新集合中的文檔, $unset 用來刪除某個(gè)鍵,例如刪除name為user1的文檔中的address鍵,可以使用命令:
db.c1.update({name:”user1”},{$unset:{address:1}},0,1)
5 索引
索引就是用來加速查詢的。數(shù)據(jù)庫索引與書籍的索引類似:有了索引就不需要翻遍整本書,數(shù)據(jù)庫則可以直接在索引中查找,
使得查找速度能提高幾個(gè)數(shù)量級(jí)。在索引中找到條目以后,就可以直接跳轉(zhuǎn)到目標(biāo)文檔的位置。
創(chuàng)建索引
創(chuàng)建普通索引,使用命令 db.collection.ensureIndex({key:1})
查看關(guān)于索引的相關(guān)信息,使用命令 db.collection.stats()
查看查詢使用索引的情況,使用命令 ? db.collection.find({key:value}).explain()
刪除索引,使用命令 db.collection.dropIndex({key:1})
刪除集合,也會(huì)將集合中的索引全部刪除
?explain是非常有用的工具,會(huì)幫助你獲得查詢方面諸多有用的信息。只要對(duì)游標(biāo)調(diào)用該方法,就可以得到查詢細(xì)節(jié)。explain會(huì)返回一個(gè)文檔,而不是游標(biāo)本身。
如:>db.test.find().explain()
{"cursor" : "BasicCursor",
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 1,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {}?}
explain會(huì)返回查詢使用的索引情況,耗時(shí)和掃描文檔數(shù)的統(tǒng)計(jì)信息。
"cursor":"BasicCursor"表示沒有使用索引。
"nscanned":1 表示查詢了多少個(gè)文檔。
"n":1 表示返回的文檔數(shù)量。
"millis":0 表示整個(gè)查詢的耗時(shí)。
6 固定集合(capped collection)
固定集合指的是事先創(chuàng)建而且大小固定的集合 。
固定集合特性:固定集合很像環(huán)形隊(duì)列,如果空間不足,最早的文檔就會(huì)被刪除,為新的文檔騰出空間。一般來說,固定集合適用于任何想要自動(dòng)淘汰過期屬性的場(chǎng)景,沒有太多的操作限制。
創(chuàng)建固定集合使用命令:db.createCollection(“collectionName”,{capped:true,size:100000,max:100});
size指定集合大小,單位為KB,max指定文檔的數(shù)量
當(dāng)指定文檔數(shù)量上限時(shí),必須同時(shí)指定大小。淘汰機(jī)制只有在容量還沒有滿時(shí)才會(huì)依據(jù)文檔數(shù)量來工作。要是容量滿了,淘汰機(jī)制會(huì)依據(jù)容量來工作。
將普通集合轉(zhuǎn)換為固定集合 :
db.runCommand({convertToCapped:“collectionName",size:10000,max:100});
7 備份(mongodump)和恢復(fù)(mongorestore)
MongoDB提供了備份和恢復(fù)的功能,分別是MongoDB下載目錄下的mongodump.exe和mongorestore.exe文件
備份數(shù)據(jù)使用下面的命令:
>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ù)存放位置,例如:c:\data\dump,當(dāng)然該目錄需要提前建立,在備份完成后,系統(tǒng)自動(dòng)在dump目錄下建立一個(gè)test目錄,這個(gè)目錄里面存放該數(shù)據(jù)庫實(shí)例的備份數(shù)據(jù)。
恢復(fù)數(shù)據(jù)使用下面的命令:
>mongorestore -h dbhost -d dbname -directoryperdb dbdirectory
-h:MongoDB所在服務(wù)器地址
-d:需要恢復(fù)的數(shù)據(jù)庫實(shí)例,例如:test,當(dāng)然這個(gè)名稱也可以和備份時(shí)候的不一樣,比如test2
-directoryperdb:備份數(shù)據(jù)所在位置,例如:c:\data\dump\test
8 導(dǎo)入(mongoimport)和導(dǎo)出(mongoexport)
導(dǎo)出數(shù)據(jù)可以使用命令:
mongoexport -h dbhost -d dbname -c collectionName -o output
參數(shù)說明:
-h ?數(shù)據(jù)庫地址
-d 指明使用的庫
-c 指明要導(dǎo)出的集合
-o 指明要導(dǎo)出的文件名
導(dǎo)入數(shù)據(jù)可以使用命令:
mongoimport -h dbhost -d dbname -c collectionname 文件的地址...
參數(shù)說明:
-h ?數(shù)據(jù)庫地址
-d 指明使用的庫
-c 指明要導(dǎo)入的集合
本地的文件地址...
9 安全和認(rèn)證
每個(gè)MongoDB實(shí)例中的數(shù)據(jù)庫都可以有許多用戶。如果開啟了安全性檢查,則只有數(shù)據(jù)庫認(rèn)證用戶才能執(zhí)行讀或者寫操作。
在認(rèn)證的上下文中,MongoDB會(huì)將普通的數(shù)據(jù)作為admin數(shù)據(jù)庫處理。admin數(shù)據(jù)庫中的用戶被視為超級(jí)用戶(即管理員)。
在認(rèn)證之后,管理員可以讀寫所有數(shù)據(jù)庫,執(zhí)行特定的管理命令,如listDatabases和shutdown。
在開啟安全檢查之前,一定要至少有一個(gè)管理員賬號(hào)。
在admin數(shù)據(jù)庫中創(chuàng)建管理員賬號(hào):
use admin;
db.addUser(“root”,”root”);
在test數(shù)據(jù)庫中創(chuàng)建普通賬號(hào):
use test;
db.addUser(“zhangsan”,”123”);
db.addUser(“l(fā)isi”,”123”,true);
注意:用戶zhangsan,密碼為123,對(duì)test數(shù)據(jù)庫擁有讀寫權(quán)限
用戶lisi,密碼為123,對(duì)test數(shù)據(jù)庫擁有只讀權(quán)限
重新啟動(dòng)數(shù)據(jù)庫服務(wù),并開啟安全檢查:
mongod --dbpath d:\mongo_data --auth
10 主從復(fù)制(主從集群 ) 重點(diǎn)內(nèi)容
主從復(fù)制是MongoDB最常用的復(fù)制方式。這種方式非常靈活,可用于備份、故障恢復(fù)、讀擴(kuò)展等。
最基本的設(shè)置方式就是建立一個(gè)主節(jié)點(diǎn)和一個(gè)或者多個(gè)從節(jié)點(diǎn),每個(gè)從節(jié)點(diǎn)要知道主節(jié)點(diǎn)的地址。
運(yùn)行mongod --master就啟動(dòng)了主服務(wù)器。運(yùn)行mongod --slave --source master_address 則啟動(dòng)了從服務(wù)器,其中master_address就是上面主節(jié)點(diǎn)的地址。
MongoDB的復(fù)制至少需要兩個(gè)服務(wù)器或者節(jié)點(diǎn)。其中一個(gè)是主節(jié)點(diǎn),負(fù)責(zé)處理客戶端請(qǐng)求,其它的都是從節(jié)點(diǎn),負(fù)責(zé)映射主節(jié)點(diǎn)的數(shù)據(jù)。
主節(jié)點(diǎn)記錄在其上執(zhí)行的所有操作。從節(jié)點(diǎn)定期輪詢主節(jié)點(diǎn)獲得這些操作,然后對(duì)自己的數(shù)據(jù)副本執(zhí)行這些操作。由于和主節(jié)點(diǎn)執(zhí)行了
相同的操作,從節(jié)點(diǎn)就能保持與主節(jié)點(diǎn)的數(shù)據(jù)同步。
主節(jié)點(diǎn)的操作記錄成為oplog(operation log)。oplog存儲(chǔ)在一個(gè)特殊的數(shù)據(jù)庫中,叫做local。oplog就在其中的oplog.$main集合
里面。oplog中的每個(gè)文檔都代表主節(jié)點(diǎn)上執(zhí)行的一個(gè)操作。需要重點(diǎn)強(qiáng)調(diào)的是oplog只記錄改變數(shù)據(jù)庫狀態(tài)的操作。比如,查詢就
不再存儲(chǔ)在oplog中。這是因?yàn)閛plog只是作為從節(jié)點(diǎn)與主節(jié)點(diǎn)保持?jǐn)?shù)據(jù)同步的機(jī)制。
為了方便演示,可以在一臺(tái)計(jì)算機(jī)上來模擬主節(jié)點(diǎn)和從節(jié)點(diǎn)。在D盤創(chuàng)建兩個(gè)目錄master和slave,master目錄作為主節(jié)點(diǎn)的數(shù)據(jù)文件的目錄,slave目錄作為從節(jié)點(diǎn)的數(shù)據(jù)文件的目錄。
注意:主節(jié)點(diǎn)和從節(jié)點(diǎn)要指定不同的端口。
啟動(dòng)主節(jié)點(diǎn):mongod --dbpath d:\master --port 10000 --master
啟動(dòng)從節(jié)點(diǎn):mongod --dbpath d:\slave --port 10001 --slave --source localhost:10000
啟動(dòng)成功后就可以連接主節(jié)點(diǎn)進(jìn)行操作了,而這些操作會(huì)同步到從節(jié)點(diǎn)。
注意:主節(jié)點(diǎn)可以進(jìn)行增刪改查所有操作,而從節(jié)點(diǎn)只能進(jìn)行查詢的操作
11 副本集 replset
副本集就是有自動(dòng)故障恢復(fù)功能的主從集群。
主從集群和副本集最大的區(qū)別就是副本集沒有固定的“主節(jié)點(diǎn)”;
整個(gè)集群會(huì)選出一個(gè)“主節(jié)點(diǎn)”,當(dāng)其掛掉后,又在剩下的從節(jié)點(diǎn)中選中其他節(jié)點(diǎn)為“主節(jié)點(diǎn)”,副本集總有一個(gè)活躍點(diǎn)(primary)和一個(gè)或多個(gè)備份節(jié)點(diǎn)(secondary)。
以三個(gè)節(jié)點(diǎn)為例:
節(jié)點(diǎn)1:
HOST:localhost:10001
Log File:D:\mongodb\logs\node1\logs.txt
Data File:D:\mongodb\dbs\node1
節(jié)點(diǎn)2:
HOST:localhost:10002
Log File:D:\mongodb\logs\node2\logs.txt
Data File:D:\mongodb\dbs\node2
節(jié)點(diǎn)3:
HOST:localhost:10003
Log File:D:\mongodb\logs\node3\logs.txt
Data File:D:\mongodb\dbs\node3
啟動(dòng)節(jié)點(diǎn)1:
mongod --dbpath D:\mongodb\dbs\node1 --logpath D:\mongodb\logs\node1\logs.txt --logappend --port 10001 --replSet itcast/localhost:10002? --master
啟動(dòng)節(jié)點(diǎn)2:
mongod --dbpath D:\mongodb\dbs\node2 --logpath D:\mongodb\logs\node2\logs.txt --logappend --port 10002 --replSet itcast/localhost:10001
啟動(dòng)節(jié)點(diǎn)3:??
mongod --dbpath D:\mongodb\dbs\node3 --logpath D:\mongodb\logs\node3\logs.txt --logappend --port 10003 --replSet itcast/localhost:10001,localhost:10002
初始化節(jié)點(diǎn)(只能初始化一次):隨便登錄一個(gè)節(jié)點(diǎn),以10001為例
?mongo localhost:10001/admin
?db.runCommand({
"replSetInitiate":{"_id":“itcast",
"members":[{"_id":1,
"host":"localhost:10001",
"priority":3},
{"_id":2,"host":"localhost:10002","priority":2},{"_id":3,"host":"localhost:10003","priority":1}]}});
參數(shù)解釋:
--replSet? 指定副本集? 后面緊跟著副本集的名稱
--logappend 日志文件末尾添加
--port 指定端口號(hào)
db.runCommand({})? 初始化副本集
初始化文檔:
"_id":“itcast",? 指副本集的名稱
?"members":[...]? 副本集的服務(wù)器列表? 每個(gè)列表有個(gè)
?????????????? "_id": 每個(gè)服務(wù)器的唯一id,?
??????????????"host" 指定服務(wù)器的主機(jī),
??????????????"priority"設(shè)置優(yōu)先級(jí),默認(rèn)優(yōu)先級(jí)為1,可以是1-1000的數(shù)字
查詢當(dāng)前主庫,登錄10002
mongo localhost:10002
db.$cmd.findOne ( {ismaster: 1 } );
關(guān)閉10001服務(wù)Dos命令窗口,? 登錄10002查詢當(dāng)前主庫
mongo localhost:10002
db.$cmd.findOne ( {ismaster: 1 } );
默認(rèn)情況下從庫是不能進(jìn)行讀寫操作的設(shè)置從庫可讀(在從庫secondary上執(zhí)行):
rs.slaveOk ( );
12 分片(sharding)分布式存儲(chǔ)..
分片(sharding)是指將數(shù)據(jù)拆分,將其分散存在不同的機(jī)器上的過程。有時(shí)也用分區(qū)(partitioning)來表示這個(gè)概念。
將數(shù)據(jù)分散到不同的機(jī)器上,不需要功能強(qiáng)大的大型計(jì)算機(jī)就可以儲(chǔ)存更多的數(shù)據(jù),處理更多的負(fù)載。
MongoDB分片的基本思想就是將集合切分成小塊。這些塊分散到若干片里面,每個(gè)片只負(fù)責(zé)總數(shù)據(jù)的一部分。
應(yīng)用程序不必知道哪片對(duì)應(yīng)哪些數(shù)據(jù),甚至不需要知道數(shù)據(jù)已經(jīng)被拆分了,所以在分片之前要運(yùn)行一個(gè)路由進(jìn)程,該進(jìn)程名為mongos。
這個(gè)路由器知道所有數(shù)據(jù)的存放位置,所以應(yīng)用可以連接它來正常發(fā)送請(qǐng)求。對(duì)應(yīng)用來說,它僅知道連接了一個(gè)普通的mongod。
路由器知道數(shù)據(jù)和片的對(duì)應(yīng)關(guān)系,能夠轉(zhuǎn)發(fā)請(qǐng)求到正確的片上。如果請(qǐng)求有了回應(yīng),路由器將其收集起來回送給應(yīng)用。
設(shè)置分片時(shí),需要從集合里面選一個(gè)鍵,用該鍵的值作為數(shù)據(jù)拆分的依據(jù)。這個(gè)鍵稱為片鍵(shard key)。
{name:"zhangsan",age:1}
用個(gè)例子來說明這個(gè)過程:假設(shè)有個(gè)文檔集合表示的是人員。
如果選擇名字("name")作為片鍵,第一片可能會(huì)存放名字以A~F開頭的文檔,第二片存的G~P的名字,第三片存的Q~Z的名字。
隨著添加或者刪除片,MongoDB會(huì)重新平衡數(shù)據(jù),使每片的流量都比較均衡,數(shù)據(jù)量也在合理范圍內(nèi)。
mongos就是一個(gè)路由服務(wù)器,它會(huì)根據(jù)管理員設(shè)置的“片鍵”將數(shù)據(jù)分?jǐn)偟阶约汗芾淼膍ongod集群,數(shù)據(jù)和片的對(duì)應(yīng)關(guān)系以及相應(yīng)的配置信息保存在“config服務(wù)器”上。
mongod:一個(gè)普通的數(shù)據(jù)庫實(shí)例,如果不分片的話,我們會(huì)直接連上mongod。
步驟:
1、創(chuàng)建三個(gè)目錄,分別存放兩個(gè)mongod服務(wù)的數(shù)據(jù)文件和config服務(wù)的數(shù)據(jù)文件
2、開啟config服務(wù)器 。mongos要把mongod之間的配置放到config服務(wù)器里面,所以首先開啟它,這里就使用2222端口。 命令為:
mongod --dbpath E:\sharding\config_node --port 2222
3、開啟mongos服務(wù)器 。這里要注意的是我們開啟的是mongos,端口3333,同時(shí)指定下config服務(wù)器。命令為:
mongos --port 3333 --configdb=127.0.0.1:2222
4、啟動(dòng)mongod服務(wù)器 。對(duì)分片來說,也就是要添加片了,這里開啟兩個(gè)mongod服務(wù),端口分別為:4444,5555。命令為:
mongod --dbpath E:\sharding\mongod_node1 --port 4444
mongod --dbpath E:\sharding\mongod_node2 --port 5555
5、服務(wù)配置 。client直接跟mongos打交道,也就說明我們要連接mongos服務(wù)器,然后將4444,5555的mongod交給mongos,添加分片也就是addshard()。
6、開啟數(shù)據(jù)庫分片功能,命令很簡(jiǎn)單 enablesharding(),這里就開啟test數(shù)據(jù)庫。
7、指定集合中分片的片鍵,這里就指定為person.name鍵。
8、通過mongos插入10w記錄,然后通過printShardingStatus命令查看mongodb的數(shù)據(jù)分片情況。
這里主要看三點(diǎn)信息:
? ① shards: ? ? 可以看到已經(jīng)別分為兩個(gè)片了,shard0000和shard0001。
? ② databases::?這里有個(gè)partitioned字段表示是否分區(qū),這里可以看到test已經(jīng)分區(qū)。
? ③ chunks: ? ? 集合被砍成四段:
? ? ? ? ? ? 無窮小 —— jack0,
jack0 ——jack234813,
jack234813——jack9999,
jack9999——無窮大。
分區(qū)情況為:3:1,從后面的 on shardXXXX也能看得出。