mongodb知识点回顾

https://blog.csdn.net/kuang_jia_ji/article/details/78667199

mongodb介绍

mongodb文档数据库,存储的是文档(Bson->json的二进制化)
特点:内部执行引擎为JS解释器,把文件存储成bson结构,在查询时转换成js对象,并可以通过熟悉的js语法来操作。
mongo和传统型数据库相比最大的不同:
传统型数据库:结构化数据,定好了表结构后,每一行的内容,必是符合表结构的,就是说--列的个数,类型都一样。
mongo文档型数据库:表下的每篇文档,都可以有自己独特的结构(josn对象都可以有自己独特的属性和值);

思路:如果有电影,影评,影评的回复,回复的打分;如果在传统型数据库中,至少要4张表,关联度十分复杂,在文档数据库中,通过1篇文档即可完成。
{
film:'天龙八部'
comment:[
{content:'王家卫的电影风格'
reply:['支持','好']
}

]

}

mongodb的安装

1.点下载download linux版本 stable版 复制链接
wget 链接地址
2.解压文件
ls
tar zxvf mongodb-linux-x86_64-2.2.6.tgz
ls
cd mongodb-linux-x86_64-2.2.6
ls
ll
ls bin/
ll bin/

各个文件的作用:
bsondump 导出bson结构
mongo 客户端(相当于mysql.exe)
mongod 服务端(相当于mysqld.exe)
mongodump 整体数据库导出(二进制,相当于mysqldump)
mongoexport 导出易识别的json文档或CSV文档
mongorestore 数据库整体导入
mongos 路由器(分片时用)

cd ..
ls
移动文件
rm -rf/usr/local/mongodb/
mv mongodb-linux-x86_64-2.2.6 /usr/local/mongodb
cd /usr/local/mongodb/
ls
./bin/mongod --help
3.启动mongodb服务
./bin/mongod --dbpath/path/to/database --logpath/path/to/log --fork --port27017
参数解释:
--dbpath 数据存储目录
--logpath 日志存储目录
--port 运行端口(默认27017)
--fork 后台进程运行
查看文件
df -h
mkdir -p /home/m17 /home/mlog
./bin/mongod --dbpath/home/m17/ --logpath/home/mlog/m17.log --fork --port27017
ps aux|grep mongo
./bin/mongo

5.mongodb非常占磁盘空间,刚启动后要占3-4G左右
cd /home/
ll
cd m17
ll
du -h
如果你用虚拟机练习,可能空间不够,导致无法启动
可以用 --smallfiles 选项来启动,将会占用较小空间300-400M

mongo入门语句

1.show dbs;//查看数据库
2.use 数据库名
3.show tables/collections ;查看当前库下的collection
4.db.help();//查看db有哪些方法
5.如何创建库?
mongodb的库是隐式创建,你可以use一个不存在的库,然后在该库下创建collection,即可创建看库
6.创建集合
db.createCollection('collectName')
db.createCollection('user')
db.user.insert({name:'lisi',age:22});//集合中添加数据
db.user.find();//查看user集合中添加的数据
db.user.insert({_id:2,name:'poly',age:23});
db.user.insert({_id:3,name:'hmm',hobby:['baskketball','football'],intro:{'title':'my intro',content:'from china'}});
db.user.find();
集合也是可以隐式创建的,比如:
show collections;
db.goods.insert({_id:1,name:'noydd',price:29.9});
show collections;
db.user.find();
7.删除集合
db.user.drop();
8.删除数据库
db.dropDatabase();

mongo基本操作增删改查(create/retrieve/update/delete)
1.增:insert

use test
db.stu.insert({sn:'001',name:'xiaoming'});
db.stu.insert({_id:2,sn:'002',name:'xiaoqiang'});
如何一次添加多个文档
\color{red}{json是一个对象,js里有数组这个概念,我们只需要把多个对象放到一个数组中即可}
db.stu.insert([{_id:3,sn:'003',name:'zhangfei'},{sn:'004',name:'guanyu'},{sn:'005,name:'liubei'}]);
db.stu.insert({name:{x:'li',m:'shimin'},ji:['war','kill']});
db.stu.find();

2.删:remove

语法:db.collectionName.remove(查询表达式 选项);
选项是指{justOne:true/false}是否只删一行,默认为false
(1)查询表达式依然是个json对象
(2)查询表达式匹配的行,将被删掉
(3)如果不写查询表达式,collection中的所有文档将被删掉
db.stu.remove({sn:'001'});
db.stu.find();
db.stu.remove({gender:'m'},true);//删除stu表中genner属性为m的一行

3.查 find

db.stu.insert([{name:'songjiang',gender:'m'},{name:'dalang',gender:'m'},{name:'jinlian',genner:'f'},{name:'poxi',genner:'f'}]);
db.stu.find();


image.png

语法:db.collectionName.find(查询表达式,查询的列);
db.collectionName.find(表达式,{列1:1,列2:1});
例1:db.stu.find();//查询所有文档所有内容
例2:db.stu.find({},{gender:1});//查询所有文档的gender:属性,(id属性默认总是查询出来)
例3:db.stu.find({},{gender:1,_id:0});//查询所有文档的gender属性,且不查询_id属性
例4:db.stu.find({gender:'male'},{name:1,_id:0});//查询所有gender属性为male的name属性,且不显示id属性

4.改 update操作

改谁?---查询表达式
改成什么样?--新值或赋值表达式
操作选项---可选参数

语法:db.collectionName.update(查询表达式,新值,选项);
例:
db.news.update({name:'QQ'},{name:'MSN'});//是指选中news表中name值为QQ的文档,并把该文档中的其他的文档值改为{name:'MSN'}
\color{blue}{结果:文档中的其他列也不见了,改后只有_id和name列了,即新文档直接替换了旧文档,而不是修改}
db.stu.update({name:'poxi'},{$set:{name:'yanpoxi'}});

修改时的赋值表达式
$set 修改某列的值
$unset 删除某列的值
$rename重命名某个列
$inc 增长某个列
$setOnInsert 当upsert为true,并且发生了insert操作时,可以补充字段
db.stu.update({name:'wusong'},{$set:{name:'xingzhewusong'}},{$setOnInsert:{gender:'mail'}},{upsert:true});//如果出现错误,可以去mongodb官网上查询关键字的适用条件
db.stu.insert({
name:'wukong',
jinggu:true,
age:500
});
db.update({name:'wukong'},{$set:{name: 'dzsf' },$unset:{jingu:1},$rename:{sex:'genner'},$inc:{age:16}});

Option的作用
(upsert:true/false,multi:true/false)
Upsert---是指如果有匹配的行就进行值的更改,没有匹配的行,则直接插入该行,(和mysql中的replace一样)
例:
db.news.update({_id:99},{x:123,y:234},{upsert:true});//没有_id=99的文档被修改,因此直接插入该文档
Multi:是指修改多行(即使查询表达式可以匹配多行,也只改一行)
例:
db.news.update({age:21},{$set:{age:22}},{multi:true});
则把news中所有age=21的文档都修改

深入查询表达式

mysql-->mongodb json.dumps()

db.goods.find().count();//统计个数


image.png

image.png

image.png
1.最简单的查询表达式
{field:value},是指查询field列的值为value的文档

2.$ne --- != 查询表达式
{field:{$ne:value}}
作用:查field列的值不等于value的文档
例:db.goods.find({cat_id:{$ne:3}},{cat_id:1,goods_name:1,_id:0});
db.goods.find({shop_price:{$gt:3000}},{goods_name:1,shop_price:1,_id=0})//查询大于3000的商品
db.goods.find({shop_price:{$lt:3000}},{goods_name:1,shop_price:1,_id=0})//查询小于3000的商品
db.goods.find({shop_price:{$lte:3000}},{goods_name:1,shop_price:1,_id=0})//查询小于等于3000的商品
3: $nin ---> not in
例:db.goods.find({cat_id:{$in:[4,11]}},{cat_id:1,goods_name:1,_id:0});

4.$all  指数组所有单元匹配
语法:{field:{$all:[v1,v2..]}}
是指取出field列是一个数组,且至少包含v1,v2值
db.stu.drop();
db.stu.insert({name:'lily',hobby:['a','b','c']});
db.stu.insert({name:'lily',hobby:['b','c','e']});
db.stu.find({hobby:{$all:['b','c']}});

5.$exists  某列存在则为真
语法:{field:{$exists:1}}
作用:查询出含有field字段的文档
db.stu.find({age:{$exists:1}})//取出有年龄属性的文档

6.$not
{$not:[条件1,条件2]}
是指:所有条件都不满足的文档为真返回

7.$regex 正则表达式匹配则为真//效率也不高,能不用则不用

例:db.goods.find({goods_name:{$regex:/^诺基亚.*/}},{goods_name:1});//用正则表达式查询以“诺基亚”开头的商品

8.用$where表达式来查询//js语句实现,将磁盘中的二进制数据转化成json格式,再查询,效率不高,能不用则不用。
db.goods.find({$where:'this.shop_price>5000'});

9.$and
db.goods.find({$and:[{shop_price:{$gte:100}},{shop_price:{$lte:500}}]},{shop_price:1,shop_name:1,_id:0});

10.$nor  无对应项,所有列举条件都不成立则为真
db.goods.find({$nor:[{cat_id:3},{cat_id:11}]},{cat_id:1,goods_name:1,_id:0});

11.$mod 满足某求余条件则为真
db.goods.find({goods_id:{$mod:{5,0}}},{goods_id:1,gooods_name:1,_id:0})//除5余0

12.$type 数据为某类型则为真//数值参考见上面的图片

db.foo.insert({name:'dingdang',age:'23'});
db.foo.insert({name:'manong',age:23});//这两个age不一样,一个有引号
db.foo.find({age:{$type:2}});
db.foo.find({age:{$type:1}});

游标操作 //查询大量数据的时候 cursor

游标是什么?
通俗的说,游标不是查询结果,而是查询的返回资源或者接口,通过这个接口,你可以逐条读取,就像php中的fopen打开文件,得到一个资源一样,通过资源,可以一行一行的读文件
声明游标:

var cursor = db.collectionName.find(query,projection);
cursor.hasNext()判断游标是否已经取到尽头
cursor.Next()取出游标的下一个单元

use test
show tables;

mongo底层是js解释器
加入要插入10000条数据
for(var i=0; i<=10000;i++){
...db.bar.insert({_id:i+1,title:'hello world',content:'aaa'+i});
...};
db.bar.find().count();//只显示前20条


var mycursor = db.bar.find();
var mycursor = db.bar.find({_id:{$lte:5}});
print(mycursor.next())
printjson(mycursor.next())

var mycursor = db.bar.find({_id:{$lte:5}});
while(mycursor.hasNext()){
...printjson(mycursor.next());
...}//用while来循环游标


for(var mycursor=db.bar.find({_id:{$lte:5}});mycursor.hasNext();){
...printjson(mycursor.next())
...}

游标还有一个迭代函数,允许我们自定义回调函数来逐个处理每个单元
cursor.forEach(回调函数);
例:
var gettitle = function(obj){printjson(obj)}
var mycursor = db.bar.find({_id:{$lte:5}});
mycursor.forEach(gettitle);


游标在分页中的应用
比如查到10000行,跳过100页,取10行
一般地,我们假设每页N行,当前是page页,就需要跳过前(page-1)*N行,再取N行,在
mysql中,limit offset,N来实现;在mongo中,用skip(),limit()函数来实现的
如:var mycursor = db.bar.find().skip(9995);
mycursor.forEach(function(obj){printjson(obj)});//查询结果中跳过9995行
如:var mycursor = db.bar.find().skip(9000).limit(10);
mycursor.forEach(function(obj){printjson(obj)});//查询第901页,每页10条

也可以直接使用skip(),limit()函数
db.bar.find().skip(1000).limit(5)


通过cursor一次性得到所有数据,并返回数组.
例:
var cursor = db.goods.find();
printjson(cursor.toArray());//看到所有行
printjson(cursor.toArray()[2]);//看到第二行
【注意】不要随意使用toArray(),原因:会把所有的行立即以对象形式组织在内存里,
可以在取出少数几行时,用此功能
索引

1.索引提高了查询速度,降低了写入速度,权衡常用的查询字段,不必在太多列上建索引
2.在mongo中索引可以按字段升序,降序来创建,便于排序
3.默认是用btree来组织索引文件,2.4版本以后也允许建立hash索引

for(var i=1;i<=1000;i++){
...db.stu.insert({sn:i,name:'student'+i})
...}

db.stu.find().count();
db.stu.find({sn:99}).explain();

查看查询计划
db.find(query).explain();
"cursor"S:"BasicCursor"---说明没有索引发挥作用
"nscannedObjects":1000---理论上要扫描多少行

索引创建
db.stu.ensureIndex({sn:1})
db.stu.find({sn:99}).explain()
"cursor":"BtreeCursor sn_1" //用到Btree索引

常用命令:
查看当前索引状态:db.collectionName.getIndexes();

db.stu.getIndexes();
创建普通的单列索引:db.collectionName.ensureIndex({field:1/-1});//1和-1分别代表升序和降序

创建多列索引:db.collectionName.ensureIndex({field1:1/-1,field2:1/-1})//多列索引将多列绑定在一块,查询的更快
db.stu.ensureIndex({sn:1,name:1});

创建子文档列索引:db.collectionName.ensureIndex({field.subfield:1/-1})
db.shop.insert({name:'Nokia',spc:{weight:120,area:'taiwan'}});
db.shop.insert({name:'sanxing',spc:{weight:100,area:'hanguo'}});
db.shop.find({name:'Nokia'})
db.shop.find({'spc.area':'taiwan'})//子文档的查询
db.shop.ensureIndex({'spc.area':1});
db.shop.getIndexes();

创建唯一索引:db.collectionName.ensureIndex({field.subfield:1/-1},{unique:ture});
db.tea.insert({email:'a@163.com'})
db.tea.insert({email:'b@163.com'})
db.tea.getIndexes();
db.tea.ensureIndex({email:1},{unique:ture})
db.tea.getIndexes();
db.tea.dropIndexes();
db.tea.insert({email:'c@163.com'})
db.tea.insert({})
db.tea.find();
db.tea.ensureIndex({email:1});
db.tea.find({email:null});
db.tea.find({email:null}).explain();

删除单个索引:db.stu.dropIndex({name:-1});
删除所有索引:db.stu.dropIndex();

创建稀疏索引:
稀疏索引的特点----如果针对field做索引,针对不含field列的文档将不建立索引,
与之相对,普通索引,会把该文档的field列的值认为NULL,并建索引
适用于:小部分文档含有某列值时
db.collectionName.ensureIndex({field:1/-1},{sparse:ture});
db.tea.dropIndexes();
db.tea.ensureIndex({email:1},{sparse:true});
db.tea.find({email:null})

哈希索引//在内存中占优势
Btree和哈希
db.tea.dropIndexes();
db.tea.ensureIndex({email:'hashed'});
db.tea.find({email:'a@163.com'});
db.tea.find({email:'a@163.com'}).explain();

重建索引
语法:db.collectionName.reIndex()
作用:重建collectionName中的所有索引,包括_id
意义:减少索引文件碎片
一张表经过很多次修改后,导致表的文件产生空洞,索引文件也如此;
可以通过索引的重建,来提高索引的效率,类似mysql中的optimize table
db.foo.insert([{title:'hello'},{title:'world'}])
db.foo.ensureIndex({title:'hashed'});
db.foo.find({title:'hello'});
db.foo.find({title:'hello'}).explain();
db.foo.reIndex();

mongodb的用户管理

【注意】
A)在mongo中有一个admin数据库,牵涉到服务器配置层面的操作,需要先切换到admin数据库。
即 use.admin--->相当于进入超级用户管理模式

B)mongo的用户是以数据库为单位来建立的,每个数据库有自己的管理员

C)我们在设置用户时,需要先在admin数据库下建立管理员--这个管理员登录后,相当于超级管理员

0:查看用户
1:添加用户
命令:db.addUser()
简单参数:db.addUser(用户名,密码,是否只读)
【注意】添加用户后,我们再次退出并登录,发现依然可以直接读数据库?
原因:mongodb服务器启动时,默认不是需要认证的
要让用户生效,需要启动服务器时,就指定--auth选项,这样操作时就需要认证了

例:
1.添加用户
use admin
db.addUser('sa','sa',false);
exit
pkill -9 mongo
./bin/mongod --dbpath/home/m17/--logpath/home/mlog/m17.log \ --fork --auth
./bin/mongo
show tables

2.认证
use admin
db.auth('sa','sa');
show tables;
use test;
show tables;
db.addUser('web','web123',false);
db.auth('web','web123');
show tables;

3.修改用户名和密码
use test
db.changeUserPassword(用户名,新密码);

4.删除用户
use test
db.removeUser(用户名);
【注】:如果需要给用户添加更多的权限,可以用json结构来传递用户参数

mongodb备份与恢复

mongodb导入与导出
1:导入/导出可以操作的是本地的mongodb服务器,也可以是远程的服务器
所以都有如下通用选项:
-h host 主机
-port port 端口
-u username 用户名
-p password 密码

2.mongoexport 导出json格式的文件
问:导出哪个库,哪张表,哪几列,哪几行?

-d 库名
-c 表名
-f field1,field2..列名
-q 查询条件
-o 导出的文件名
--csv 导出csv格式(便于和传统数据库交换数据)

./bin/mongoexport -d test -c stu -f sn,name -q '{sn:{$lte:1000}}' -o ./test.stu.json

more test.stu.json

./bin/mongoexport --help()

./bin/mongoexport -d test -c stu -f sn,name -q '{sn:{$lte:1000}}' --csv -o ./test.stu.csv

more test.stu.csv

mongoimport导入

-d待导入的数据库
-c待导入的表(不存在会自己创建)
--type csv/json(默认)
--file 备份文件路径

1:导入json
./bin/mongoimport -d test -c goods --file ./goodsall.json

例:./bin/mongoimport -d test -c animal --type json --file ./test.stu.json

2:导入csv
./bin/mongoimport -d test -c goods --type csv --headline -f goods_id,goods_name --file ./goodsall.csv

例:./bin/mongoexport -d test -c stu -f sn,name -q '{sn:{$lte:10}}' --csv -o ./test.stu.csv

./bin/mongoimport -d test -c bird --type csv --headline -f sn,name --file ./test.stu.csv

mongodump 导出二进制bson结构的数据及其索引信息

-d 库名
-c 表名
-f field1,field2...列名

例:mongodump -d test [-c 表名] 默认是导出到mongo下的dump目录
./bin/mongodump -d test -c tea
ls
ls dump/
ls dump/test/tea.bson
vim dump/test/tea.bson
rm -rf dump/test
./bin/mongodump -d test

mongorestore 导入二进制bson结构的数据及索引信息
db.dropDatebase();
show dbs;
./bin/mongorestore -d test --diectoryperdb dump/test

replication set复制集

replication set多台服务器维护相同的数据副本,提高服务器的可用性

replication set 原理图:如下


image.png

Replication set 设置全过程

0.创建目录
mkdir -p /data/r0 /data/r1 /data/r2
例:mkdir /home/m17 /home/m18 /home/m19 /home/mlog

1.启动3个实例,且声明实例属于某复制集
./bin/mongod --port 27017 --dbpath /data/r0 --smallfiles --replSet rsa --fork --logpath/var/log/mongo17.log

./bin/mongod --port 27018 --dbpath /data/r0 --smallfiles --replSet rsa --fork --logpath/var/log/mongo18.log

./bin/mongod --port 27019 --dbpath /data/r0 --smallfiles --replSet rsa --fork --logpath/var/log/mongo19.log

例:
./bin/mongod --dbpath /home/m17 --logpath /home/mlog/m17.log --fork --port 27017 --replSet rs2 --smallfiles

./bin/mongod --dbpath /home/m18 --logpath /home/mlog/m18.log --fork --port 27018 --replSet rs2 --smallfiles

./bin/mongod --dbpath /home/m19 --logpath /home/mlog/m19.log --fork --port 27019 --replSet rs2 --smallfiles

2.配置
ps aux|grep mongo

./bin/mongo
use admin

var rsconf = {
_id:'rs2',
members:[{
_id:0,
host:'192.168.1.202:27017'
},
{
_id:1,
host:'192.168.1.202:27018'
},
{
_id:2
host:'192.168.1.202:27019'
}
]
}
printjson(rsconf)

3.根据配置做replication set初始化
rs.initiate(rsconf);
rs.status();

./bin/mongo --port 27018

4.删除节点
rs.remove('192.168.1.202:27019');
rs.status();

5.添加节点//rs.help()
var rsconf = {
_id:'rs2',
members:[{
_id:0,
host:'192.168.1.202:27017'
},
{
_id:1,
host:'192.168.1.202:27018'
},
{
_id:2
host:'192.168.1.202:27019'
}
]
}
rs.reconfig(rsconf)
rs.status();

show dbs;
use test
db.stu.insert({title:'hello'})
show dbs;
use test;
show tables;
db.stu.find();

rs.slaveOk();//非主服务器上操作,因为slave默认不许读写
db.stu.find();

use admin
db.shutdownServer()//关闭主服务器

rs.help();
./bin/mongo --port 27018
db.stu.insert({title:'world'})

自动化脚本//快速完成复制集
pkill -9 mongo
vim start.sh

#!/bin/bash
IP='192.168.1.202'
NA='rsb'

if [ "$1" = "reset" ]
then
        pkill -9 mongo
        rm -rf /home/m*
        exit
fi


if [ "$1" = "install" ]
then

    mkdir -p /home/m0 /home/m1 /home/m2 /home/mlog

    /usr/local/mongodb/bin/mongod --dbpath /home/m0 --logpath /home/mlog/m17.log --logappend --port 27017 --fork 
--replSet ${NA}
    /usr/local/mongodb/bin/mongod --dbpath /home/m1 --logpath /home/mlog/m18.log --logappend --port 27018 --fork 
--replSet ${NA}
    /usr/local/mongodb/bin/mongod --dbpath /home/m2 --logpath /home/mlog/m19.log --logappend --port 27019 --fork 
--replSet ${NA}
   
    exit
fi


if [ "$1" = "repl" ]
then
/usr/local/mongodb/bin/mongo <<EOF

use admin
rsconf = {
_id:'${NA}',
members:[
{_id:0,host:'${IP}:27017'},
{_id:1,host:'${IP}:27018'},
{_id:2,host:'${IP}:27019'},
]
}
rs.initiate(rsconf)
EOF
fi

sh start.sh reset

shard 分片//将数据分配在不同服务器
image.png
mkdir -p /home/m17 /home/m18 /home/m20 /home/mlog
./bin/mongod --dbpath/home/m17/ --logpath /home/mlog/m17.log --fork --port 27017 --smallfiles

./bin/mongod --dbpath/home/m18/ --logpath /home/mlog/m18.log --fork --port 27018 --smallfiles

./bin/mongod --dbpath/home/m20/ --logpath /home/mlog/m20.log --fork --port 27020 --configsvr

./bin/mongos --help

./bin/mongos --logpath/home/mlog/m30.log --port 30000 --configdb 192.168.1.202:27020 --fork

ps aux|grep mongo

./bin/mongo --port 30000//连接路由器

sh.help();
sh.addShard('192.168.1.202:27017');
sh.addShard('192.168.1.202:27018');
sh.status()

use test
db.stu.insert({name:'poly'});
db.stu.insert({name:'lily'});
db.stu.insert({name:'hmm'});
db.stu.insert({name:'lucy'});
db.stu.find();//mongos上查询
db.stu.find();//27017上查询
db.stu.find();//27018上查询

sh.status();
sh.enableSharding('shop');//添加待分片的库
sh.status();
sh.shardCollection('shop.goods',{goods_id:1});//添加待分片的表,Field是collection的一个字段,系统将会利用filed的值,来计算应该分到哪一个片上.
这个filed叫”片键”, shard key

use shop
for(var i=1; i<=30000; i++){
...db.goods.insert({goods_id:i,goods_name:'hello world abcdefg hahahhahah'});
...}
db.goods.find().count();
mongodb不是从单篇文档的级别,绝对平均的散落在各个片上,而是N篇文档形成一个块chunk,优先放在某个片上,当这片上的chunk比另一个片的chunk区别比较大时,(>=3)会把本片上的chunk移动到另一个片上,以chunk为单位,维护片之间的数据均衡

问:为什么插入10万条数据才2个chunk,
show dbs;
use config

show tables
db.settings.find();
chunk的默认大小为64M
db.settings.save({_id:'chunsize'},{$set:{value:4}});

问:既然优先网某个片上插入,当chunk失衡时,再移动chunk,
自然随着数据的增多,shard的实例之间有chunk来回移动的现象,
这将带来什么问题?
答:服务器之间IO的增加
接上问:能否我定义一个规则,某N条数据形成一个块,预先分配M个chunk,M个chunk分配在不同片上
以后的数据直接入各自预分配好的chunk,不再来回移动?
答:能,手动预先分片

手动预先分片

以shop.user表为例:
sh.shardCollection('shop.user',{userid:1});//user表用userid做shard key
sh.status();
sh.help();

use shop
for(var i=1; i<=40; i++){
...sh.splitAt('shop.user',{userid:i*1000})
...}//预先在1k,2k...40k这样的界限切好chunk(虽然chunk是空的),这些chunk将会均匀移动到各片上
sh..status();

for(var i=1;i<=40000;i++){
...db.user.insert({userid:i,name:'hello kitty'});
...}//通过mongos添加user数据,数据会添加到预先分配好的chunk上,chunk就不会来回移动了
db.user.find().count()

replication与shard分片结合使用

打开三台服务器,B号服务器放置configsvr,C,D放置复制集(primary服务器\主服务器)

脚本文件
more start.sh
复制脚本文件
分别在C,D服务器下,在mongodb文件下,vim start.sh,粘贴并修改ip,NA,--smallfiles

sh start.sh reset
sh start.sh install

配置mongos 和 configsvr

sh start.sh reset//初始化
./bin/mongod --help|grep config

mkdir /home/m20 /home/mlog
./bin/mongod --dbpath /home/m20 --logpath /home/mlog/m20.log --port 27020 --fork --configsvr

./bin/mongos --help|grep config
./bin/mongos --logpath /home/mlog/m30.log --port 30000 --configdb 192.168.1.202:27020 --fork

./bin/mongo 192.168.1.202:30000

sh.addShard('rs3/192.168.1.203:27017');

service iptables stop;//关闭防火墙

sh star.sh repl//调用脚本建立复制集

sh.status();

sh.addShard('rs4/192.168.1.204:27017');

sh.status();

=================================================
快速让数据分配到两片上,rs3 500,rs4 1k
sh.enableSharding('shop')
sh.shardCollection('shop.user',{userid:1})
sh.splitAt('shop.user',{userid:1000})
sh.splitAt('shop.user',{userid:2000})
sh.splitAt('shop.user',{userid:3000})

use shop
for(var i=1;i<=4000;i++){
...db.user.insert({userid:i,intro:'i am lilei, from usa'})
...}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容

  • 简介 MongoDB 是一个基于分布式文件存储的NoSQL数据库 由C++语言编写,运行稳定,性能高 旨在为 WE...
    大熊_7d48阅读 36,494评论 1 9
  • 1. MongoDB 简介 MongoDB是一个可扩展的高性能,开源,模式自由,面向文档的NoSQL,基于分布式文...
    rhlp阅读 1,106评论 0 3
  • 简介 NoSQL : 全名为Not Only SQL, 指的是非关系型的数据库 随着访问量上升, 网站的数据库性能...
    奋斗的老王阅读 3,036评论 4 47
  • 一、MongoDB简介 1.概述 ​ MongoDB是一个基于分布式文件存储的数据库,由C++语言编写。旨在为WE...
    郑元吉阅读 976评论 0 2
  • 知识点:美化输出:db.stu.find().pretty() $project:修改输入文档的结构。可以用来重命...
    胖虎很可爱阅读 722评论 0 1