MongoDB实战1
传统关系数据库,难以定义表结构:
- 先定义最低限度必要字段,需要再添加(更改表结构):反复变更表结构
- 事先定义魔术字段,按需采用
- 数据序列化:序列化和反序列化带来额外开销,序列化的数据无法直接读取
MongoDB(面向文档型数据库):
- 不需要定义表结构,以BSON形式保存数据
- 表:集合;记录:文档
- 变更时无需考虑程序和表结构不一直问题
- 容易扩展(数据库升级-买更好的机器;扩展-数据分散到更多的机器上)可以自动在多台服务器间分散数据,并且可以平衡集群和负载
- 支持更多的功能:通用辅助索引(多种快速查询,复合的地理空间索引);存储JavaScript;支持MapReduce等聚合工具;固定集合(大小有上限);文件存储(支持一种易用的协议存储大型文件和元数据)
- 性能卓越,使用自带的传输协议,对文档动态填充,用空间换取性能
- 管理简单
- 不支持JOIN和事务处理
- 创建和更新数据不会实时写入硬盘
- 保存数据预留很大空间,对硬盘空间需求呈逐渐增大趋势
安装要求
- Linux要求glibc版本为2.5以上
- 32bit版本数据库文件不得超过2G
- 偶数为稳定版本,奇数为开发版本
安装
- 下载
- 设置存放目录:
tar zxvf
,mkdir
,mv
- 设置数据文件目录和日至目录:
mkdir -p /data/db
,mkdir -p /Apps/mongo/logs/
,touch /Apps/mongo/logs/mongodb.log
- 启动服务:
/Apps/mongo/bin/mongod --dbpath=/data/db --logpath=/Apps/mongo/logs/mongodb.log
,服务默认端口为27017,默认HTTP接口28017 - 设置开机启动:
vi /etc/rc.local
,添加/Apps/mongo/bin/mongod --dbpath=/data/db --logpath=/Apps/mongo/logs/mongodb.log
- 客户端连接验证:打开中端,输入
/Apps/mongo/bin/mongo
;查看日志:cd /Apps/mongo/logs
- 配置文件方式启动:
cat /etc/mongodb.cnf
,dbpath=/data/db/
,./mongod -f /etc/mongodb.cnf
- Daemon方式启动:加上
--fork
参数,并且加上该参数必须也启用--logpath
源代码中,参数分为一般参数、windows参数、replication参数、replica set参数及隐含参数。隐含参数不建议生产使用。MongoDB使用os mmap机制缓存数据文件,自身不提供缓存机制。数据量超过内存写入不太稳定。
主要参数:
参数名称 | 内容 |
---|---|
dbpath | 数据文件存放目录,每个数据库会在该目录下创建子目录,确保目录存在且有访问权限 |
Logpath | 错误日志文件 |
logappend | 错误日志采用追加方式 |
bind_ip | 对外服务绑定IP,一般为空 |
port | 对外服务端口,Web管理端口在此数值基础上加1000 |
fork | 后台方式运行服务 |
journal | 开启日志功能保存操作日志 |
syncdelay | 系统同步刷新硬盘时间,单位为秒,默认60 |
directoryperdb | 每个db存放单独目录,与MySql独立表空间类似 |
maxConns | 最大连接数 |
repairpath | 执行repair时的临时目录,若未开启journal,异常重启必须执行repair |
停止数据库
- 若处在连接状态:
use admin;
,db.shutdownServer();
kill -2 PID
,或者kill -15 PID
(kill -9 PID
可能导致数据损坏)
增删改查(JavaScript Shell)
./mongo --help
查看连接参数,默认连接本机localhost上的test库use mydb;
- 创建对象
j = {name:"mongo"};
,保存对象db.things.save(j);查看对象db.things.find();
,find
只显示10条,想继续查看,输入it
- 不需要预先创建集合,文档可以存任一结构数据插入数据会有一个ID:
_id
,主键,默认为ObjectId
,可自定义,`db.c1.insert({_id:3,name:”bill”,age:”22”}),MongoDB原生不支持自增主键 - 修改:
db.things.update({name:"bill"},{$set:{name:"billnew"}});
- 删除:
db.things.remove({name:"bill"});
- 插入数据支持
for
:for ( var i = 1;i < 10; i++) db.things.save({x:4,j:i});
- 查询:
var cursor = db.things.find();while (cursor.hasNext()) printjson(cursor.next());
db.things.find().forEach(printjson);
:注意内存溢出- 迭代方式查询:
var arr = db.things.find().toArray();arr[5];
- 条件查询:
db.things.find({name:"bill"}).forEach(printjson);
,db.things.find({name:"bill"},{j:true}).forEach(printjson);
- findOne():
printjson(db.things.findOne({name:"bill"}));
- 限制结果集数量:
db.things.find().limit(3);
高级查询
查询 | 代码 |
---|---|
条件查询(> < >= <=) | db.collection.find({"field":{$gt:value}}); lt,gte,lte,支持链式 |
匹配所有 | db.users.find({age:{$all:[6,8]}}); |
判断是否存在 | db.users.find({age:{$exists:true}}); |
Null处理 | db.c2.find({age:{"$in":[null],"exists":true}}); |
取模运算 | db.student.find({age:{$mod:[10,1]}}); |
不等于 | db.things.find({x:{$ne:3}}); |
包含 | db.c1.find({age:{$in:[2,3,4]}}); |
不包含 | db.c1.find({age:{$nin:[2,3,4]}}); |
数组元素个数 | db.users.find({favorite:{$size:3}}); |
正则匹配 | db.users.find({name:{$not:/^B.*/}}); |
JavaScript查询 | db.c1.find({a:{$gt:3}}); ,db.c1.find({$where:"this.a>3"}); ,db.c1.find("this.a>3"); ,f=func(){return this.a>3;} db.c1.find(f); |
查询记录数 | db.users.find().count(); ,db.users.find().skip(10).limit(5).count(); |
限制返回记录起点 | db.users.find().skip(3).limit(3); |
排序 | db.users.find().sort({age:1}); ,db.users.find().sort({age:-1}); |
游标 | for(var c=db.t3.find();c.hasNext();){printjson(c.next());} ,db.t3.find().forEach(function(u){printjson(u);}); |