Mongo个人笔记

来源:互联网 发布:java ftp 编辑:程序博客网 时间:2024/04/28 21:52

一、Mongo文档数据库(Gridfs磁盘之上 Bson == json的二进制化)
特点:内部执行引擎为JS解释器.把文档存储成bson结构,在查询时,转换成json对象,并可以通过熟悉js语法来操作.

二、mongo和传统数据库相比,最大的不同:
1、传统数据库:结构化数据库,定义好了表结构,每一行数据都样,列的数据类型都一样.
2、文档数据库:表下面的每篇文档,没有固定的结构,可以是自己独特的属性和值.

三、安装
下载:http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.4.8.tgz
解压:tar -zxvf mongodb-linux-x86_64-2.4.8.tgz
不用编译:拷贝到/usr/local/
目录介绍: bin
bsondump 导出bson结构
mongo 客户端
mongod 服务端
mongodump 整体数据库导出(二进制)
mongoexport 导出json、csv结构
mongorestore 整体数据库导入(二进制)
mongos 路由器(分片时用)

启动服务:/usr/local/mongodb/bin/mongod --dbpath=/data/mongod17/ --logpath=/data/mongod17/mongod17.log --fork --smallfiles --port 27017--dbpath=/data/mongodb --logpath=/data/mongodb/logs/mongodb.log --auth          访问密码--port=27017    访问端口--fork          后端运行--smallfiles    最小运行400Mdu -h 查看空间、它非常占磁盘空间3-4Gkillall mogon   删除进程

四、常用命令
show dbs; 查看当前数据库
use databaseName; 选择数据库
show collections; 查看当前数据表
db.help(); 查看帮助

如何创建库(隐创建,可以不用创建,直接插入)db.createCollection('user');插入文档表db.user.insert({_id:1,name:'lisi',age:22});db.user.insert({_id:2,name:'wangbaojian',hobby:['computer','study']});db.user.find();删除库和表db.dbname.drop(); 删除数据表db.dropDatabase(); 删除数据库,需要先切换.

五、详细命令CURD
增加一篇文档
db.stu.insert({_id:’001’,sn:’001’,name:’xiaoming’});

增加多篇文档db.user.insert([{_id:1,name:'zhangsan',sex:'1',xueli:'dazhuan'},{_id:2,name:'lisi',sex:'1',xueli:'dazhuan'},{_id:3,name:'wangwu',sex:'0',xueli:'benke'}]);删除文档db.user.remove();注意:1、查询表达式依然是json对象;      2、查询表达式的匹配行被删掉;      3、如果没有查询表达式,collections中的所有文档被删除;db.user.remove({sex:'1'},true/false); 第二个参数如果为真,则只删一行.修改文档db.user.update({name:'zhansan'},{name:'zhangsantongxue'}); 除了ID以外,旧文档替换了新的文档.db.user.update({name:'lisi'},{$set:{name:'lisitongxue'}});db.user.update{{name:'lisi'},$set:{},$unset:{},$rename:{},$incr:{}}$set     修改某个列的值 >>db.user.update({name:'lisi'},{$set:{name:'lisitongxue'}},true); 修改时候命中多行,也只改一行,除非第三个参数为true.$unset   删除某个列     >>db.stu.update({_id:3},{$unset:{shcool:"zhejiang"}});$rename  重命名某个列   >>db.stu.update({_id:3},{$rename:{name:'xname'}});$incr    增长某个列的值 >>db.stu.update({_id:4},{$inc:{sex:10}});>>db.user.update({name:'lisi'},{$set:{name:'lisitongxue'}},{upsert:true}); 如果存在修改,不存在进行添加.$setOnInsert  当修改值成功,可以补充一些字段查询文档db.user.find(); 查询所有的行db.user.find({},{}) 查询表达式、查询的列值0/1

六、查询表达式
db.shop.find().count();

>>比较运算符主键为13的商品db.shop.find({goods_id:13});不属第3的所有商品($ne)db.shop.find({goods_id:{$ne:3}},{goods_id:1,_id:0,goods_name:1})其他判断关键字$ne   不等于$gt   大于$lt   小于$gte  大于等于$lte  小于等于包含的数值$in   in     db.shop.find({goods_id:{$in:[10,11]}},{_id:0,goods_id:1,goods_name:1})不包含的数值$nin  not indb.shop.find({goods_id:{$nin:[1,3]}},{_id:0,goods_id:1,goods_name:1});指数组所有值$all  db.user.find({hobby:{$all:[1]}},{_id:0,name:1,passwd:1,$hobby:1});>>逻辑运算符与$and  anddb.shop.find({$and:[{goods_id:{$gte:1}},{goods_id:{$lte:10}}]},{_id:0,goods_id:1,goods_name:1}) db.shop.find({$and:[{goods_id:{$ne:1}},{goods_id:{$ne:3}}]},{_id:0,goods_id:1,goods_name:1})或$or   ordb.shop.find({$or:[{goods_id:12},{goods_id:1}]},{_id:0,goods_id:1,goods_name:1})非$not  not所有列举条件都不成立为真    $nor  db.shop.find({$nor:[ {goods_id:12}, {goods_id:1} ]},{_id:0,goods_id:1,goods_name:1})某列存在则为真$existsdb.shop.find({goods_id:{$exists:1}},{_id:0,goods_id:1,goods_name:1})满求余条件为真$moddb.shop.find({goods_id:{$mod:[5,0]}},{_id:0,goods_id:1,goods_name:1})数据为某类为真$typedb.shop.find({goods_name:{$type:2}},{_id:0,goods_id:1,goods_name:1})

七、游标操作
插入数据
for(var i=0;i<10000;i++){db.bar.insert({_id:i,title:’hellow’,content:’word’+i})};

声明游标var mycusor = db.bar.find({_id:{$lte:5}});print(mycusor.next());while打印案例while(mycusor.hasNext()){      printjson(mycusor.next());}for循环for(var mycusor = db.bar.find({_id:{$lte:5}});mycusor.next();){     printjson(mycusor.next());}forEach循环,回调函数var mycusor = db.stu.find();mycusor.forEach(function(obj){printjson(obj)});分页的应用skip() limit()每页n行,当前page页,跳过(page-1)* 行var mycusor = db.stu.find().skip(800).limit(10);while(mycusor.hasNext()){      printjson(mycusor.next());}直接返回结果(资源大)var mycusor = db.stu.find().skip(800).limit(10);mycusor.toArray();

七、索引操作
解释执行计划
db.find(query).explain(); >>db.stu.find().skip(0).limit(10).explain();
“cursor” : “BasicCursor”, 没有索引列
“nscannedObjects” : 10, 理论扫描行
查看当前索引
db.stu.getIndexes();

创建索引db.stu.ensureIndex({title:1}); -/+ 1正序/倒序删除索引db.stu.dropIndex({title:1});     删除指定db.stu.dropIndexes();            删除所有多列索引db.stu.ensureIndex({a:1,b:1...});子文档索引及查询db.user.insert({_id:3,name:'lili',hobby:{yundong:'yumaoqiu',yule:'kandianshi'}})db.user.find({'hobby.yule':'kandianshi'});  查询子文档  db.stu.ensureIndex('hobby.yule':1);索引性质普通索引(包含空值)唯一索引db.user.ensureIndex({name:1},{unique:true});稀疏索引(不包含空)db.user.ensureIndex({name:1},{sparse:true});哈希索引(理论1次命中,但不适合范围.2.4新增的功能)db.user.ensureIndex({name:'hashed'});重建索引(多次修改会产生空洞)db.stu.reindex;删除索引db.stu.dropIndexes();删除所有

八、用户管理

1、切换到admin数据库   use admin2、添加超级管理员   db.addUser('sa','shunjian','false');用户名、密码、是否只读   给其他库添加用户需要使用管理员身份切换到其他库   db.addUser('web','123456','false');3、关闭所有进程killall mongod 4、权限验证--auth/usr/local/mongodb/bin/mongod --dbpath=/data/mongod17/ --logpath=/data/mongod17/mongod17.log --auth --port=27017 --fork --smallfiles5、登入认证   use admin   db.auth('sa','shunjian');6、修改用户密码   db.changeUserPassword('sa','newpasswd');7、修改用户密码   db.removeUser('sa');8、用户权限(细分角色管理,dba的工作了)

九、导入导出
导出参数
-h 主机
-port 端口
-u 用户名
-p 密码

 mongoexport -d [库] -c [表] -f 列1,列2 -q [条件] -o ./stu.json -d 库名 -c 表名 -f 列名 -q 条件 -o 路径 --cvs 导出csv格式(便于和传统数据库交换数据) >>导出json ./mongoexport -h 192.168.0.174 -port 27017 -u www -p 321 -d test -c stu -f _id,title,content -q '{_id:{$lte:1000}}' --json -o ./stu.json   >>导入json ./mongoimport -h 192.168.0.174 -port 27017 -u www -p 321 -d test -c stu --type json --file ./stu.json >>导出csv ./mongoexport -h 192.168.0.174 -port 27017 -u www -p 321 -d test -c stu -f _id,title,content -q '{_id:{$lte:1000}}' --csv -o ./stu.csv >>导入csv ./mongoimport -h 192.168.0.174 -port 27017 -u www -p 321 -d test -c stu -f _id,title,content --headerline --type csv --file ./stu.csv 导出二进制 ./mongodump -h 192.168.0.174 -port 27017 -u www -p 321 -d test -c stu -o ./ 导入二进制 ./mongorestore -d test -c stu --directoryperdb /usr/local/mongodb/bin/test/

十、复制集replication set
1、多台服务器维护相同的副本
2、原理图 |
|
primary(write)
| | | |
secondary(read) <–> secondary(read)

3、创建目录(数据、日志)   rm -rf /data/mongodb* && mkdir -p /data/mongodb17 /data/mongodb18 /data/mongodb19 /data/mongodb17/logs/ /data/mongodb18/logs/ /data/mongodb19/logs/4、启动三个实例(声明实例属于某个复制集)--replset   /usr/local/mongodb/bin/mongod --dbpath=/data/mongodb17 --logpath=/data/mongodb17/logs/mongodb17.log --port=27017 --fork --smallfiles --replSet rs2   /usr/local/mongodb/bin/mongod --dbpath=/data/mongodb18 --logpath=/data/mongodb18/logs/mongodb18.log --port=27018 --fork --smallfiles --replSet rs2   /usr/local/mongodb/bin/mongod --dbpath=/data/mongodb19 --logpath=/data/mongodb19/logs/mongodb19.log --port=27019 --fork --smallfiles --replSet rs25、配置var rsconf = {_id:'rs2',members:[    {        _id:0,        host:'192.168.0.174:27017'    },    {        _id:1,        host:'192.168.0.174:27018'    },    {        _id:2,        host:'192.168.0.174:27019'    }]}6、根据配置进行初始化rs.initiate(rsconf);5、查看状态rs.status(); 8、删除节点rs.remove('192.168.0.174:27018');9、添加节点配置(执行步骤5)rs.reconfig(rsconf);10、让从服务器可以读rs.slaveOk();11、关闭服务器db.shutdownServer();12、帮组rs.help();13、脚本#!/bin/bashNA="rs2"IP="192.168.0.174"if [ "$1" == "reset" ]; then    killall mongod    rm -rf /data/m*    mkdir -p /data/mongodb17 /data/mongodb18 /data/mongodb19 /data/mongodb17/logs/ /data/mongodb18/logs/ /data/mongodb19/logs/elif [ "$1" == "install" ]; then    /usr/local/mongodb/bin/mongod --dbpath=/data/mongodb17 --logpath=/data/mongodb17/logs/mongodb17.log --port=27017 --fork --smallfiles --replSet ${NA}    /usr/local/mongodb/bin/mongod --dbpath=/data/mongodb18 --logpath=/data/mongodb18/logs/mongodb18.log --port=27018 --fork --smallfiles --replSet ${NA}    /usr/local/mongodb/bin/mongod --dbpath=/data/mongodb19 --logpath=/data/mongodb19/logs/mongodb19.log --port=27019 --fork --smallfiles --replSet ${NA}    /usr/local/mongodb/bin/mongo << EOFuse adminvar rsconf = {     _id:"rs2",     members:[             {_id:0,host:"${IP}:27017"},             {_id:1,host:"${IP}:27018"},             {_id:2,host:"${IP}:27019"}]}rs.initiate(rsconf);EOFelse     echo "this is error"fi 

十一、数据shard分片(mongos)

>>原理图                                             shard1(片一) mongos               configsvr 路由器     (不存储数据,存储数据上的片信息)                                              shard2(片二)>>说明1、要有N且N>=2个mongod服务做片节点.2、要有configsvr维护mata原信息.3、要启动mongos做路由.4、要设定好数据的分片规则(configsvr才能维护).5、先往一个shard插入数据,当失衡的时候,移动chunk,会造成磁盘IO增高.#!/bin/bashIP="192.168.0.174"if [ "$1" == "reset" ]; thenkillall mongodrm -rf /data/m*mkdir -p /data/mongodb17/logs /data/mongodb18/logs /data/mongodb99/logs /data/mongodb30000/logselif [ "$1" == "install" ]; then/usr/local/mongodb/bin/mongod --dbpath=/data/mongodb17 --logpath=/data/mongodb17/logs/mongodb17.log --port 27017 --smallfiles --fork/usr/local/mongodb/bin/mongod --dbpath=/data/mongodb18 --logpath=/data/mongodb18/logs/mongodb18.log --port 27018 --smallfiles --fork/usr/local/mongodb/bin/mongod --dbpath=/data/mongodb99 --logpath=/data/mongodb99/logs/mongodb99.log --port 27099 --smallfiles --configsvr --fork/usr/local/mongodb/bin/mongos --logpath=/data/mongodb30000/logs/mongodb30000.log --port 30000 --fork --configdb ${IP}:27099/usr/local/mongodb/bin/mongo -port 30000 << EOF     sh.addShard("${IP}:27017")     sh.addShard("${IP}:27018")     sh.enableSharding('test')     sh.shardCollection('test.user',{userid:1})     use config     db.settings.save({_id:'chunksize',value:2}) EOFelse     echo "this is error"fi    5、添加要分片的规则 sh.enableSharding("test") sh.shardCollection("test.user",{userid:1}) 6、修改chunk的默认大小默认64m use config db.settings.find(); db.settings.save({_id:'chunksize',value:1})

36
十二、手工分片
sh.enableSharding(“test”)
sh.shardCollection(“test.user”,{userid:1})
for(var i=1;i<=79;i++){ sh.splitAt(‘test.user’,{userid:i*1000}) }

第八天的课程

一、复制集与分片的结合思路
mongos(A)
port:30000
|
|
configsvr(A)
port:27020
|
|
B复制集RS3 C复制集RS4

27017 >>27017
27018 27018
27019 27019

0 0
原创粉丝点击