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);}); |