一、Introduction
MongoDB是一个面向文档的数据库。mysql等是面向记录的。MongoDB中,一个记录是一个文档。是NoSQL类型的产品。即非关系型的。类似还有memcache、redis等。存储数据时是key-value方式的。NoSQL在处理大数据和高并发性能非常好。
MongoDB,易于扩展、性能非常快、分布式存储与操作。缺陷是基本不支持事务和join操作。适合做非事务型的以及数据结构简单的数据,比如,日志等,以数据存储为主。很好的实现了面向对象的思想,每条记录都是一个document对象,json形式的,无需手动编写sql语句,直接调用方法就可以轻松的实现crud操作。文档模型自由灵活,不用建表;很适合大数据量、高并发、弱事务的需求。
二、安装和使用
从官网下载windows版的MongoDB软件包,解压。执行程序在bin目录下,一般,执行程序中,以d结尾的表示daemon,是服务端的,不带d结尾的是客户端。
1. 安装服务
创建数据库目录和日志文件。以管理员,打开cmd窗口。在bin目录下,执行命令mongod.exe --dbpath F:\MongoDB\data --logpath F:\MongoDB\log.txt --install
就安装了。
2. 开启和管理服务
然后,打开服务窗口管理
在cmd执行,services.msc,找到MongoDB的服务启动。启动后,监听的端口号27017,还会开启一个web管理页面,监听的端口号是28017,在浏览器,localhost:2807可以访问。
在cmd中使用mongo.exe连接到服务器操作。成功会显示连接的版本号和数据库名字。这个客户端就是一个javascript的解析引擎,可以执行javascript代码。
比如:
var a = Math.random()
a
new Date()
for(var i=0; i<10; i++){
print(i)
}
3. 使用客户端提供的帮助系统
系统级别的帮助,执行help
数据库级别的帮助,执行db.help()
集合级别的帮助,执行db.集合名.help()
集合中查询的帮助,执行db.集合名.find().help()
方法级别的帮助,查询方法的参数,执行db.集合名.方法名,比如db.googs.update
4. 面向文档的数据库中的概念
与mysql中叫法的对应
MYSQL MONGODB
数据库 数据库
表 集合
记录 文档
5. db变量代表当前数据库
db表示显示当前数据库名。切换数据库,使用use 数据库名
6. MongoDB是无模式的数据库
无模式就是不需要创建数据库和集合就可以使用,而且集合中的字段随意加不用提前定义好。甚至同一个集合中可以放完全不同的文档,比如订单、商品、类别、头像、甚至其他项目的文档,比如博客,也放在一个集合中。但是一般不这样做,而是将用一个结构的文档当道一个集合中,这样性能更好、便于管理。
三、使用MongoDB完成crud
1. 向php1数据库的商品集合中插入10件商品
use php1
for(var i=0; i<10; i++){
db.goods.insert({"goods_name":"goods_"+i,"price":100*Math.random()})
}
MongoDB会为每条新添加的id添加_id字段,确保在同一个集合中是唯一的。其类型为ObjdecId类型。这样做是为了避免分布式存储数据时id冲突,所以没有使用自增整型。
2. 查询出10条记录
db.goods.count()
db.goods.find()
3. 删除goods_name =goods_4的商品
db.goods.remove({"goods_name":"goods_4"})
4. 修改商品名称为goods_2的商品的价格为3
var d = db.goods.findOne({"goods_name":"goods_2"})
d.price = 3
db.goods.save(d)
四、MongoDb实现复杂操作
1. 常用的操作符,$lt,$lte,$gt,$gte,$ne,$in,$nin,$or,$not,$mod,$exists,$where。
比如,查询大于10的
db.user.find({"age":{“$gt”:10}})
查询价格大于50的商品
db.goods.find({"price":{"$gt":50}})
2. 修改数组
$push向数组中添加
$pop从数组的首或尾取出数据
向tom的商品中添加一个商品book
db.member.insert({"member":"tom","goods":[]})
db.member.update({"member":"tom"},{"$push":{"goods":"book"}})
从tom的商品中删除最后一件商品
db.member.update({"member":"tom"},{"$pop":{"goods":1}})
从tom的商品中删除第一件商品
db.member.update({"member":"tom"},{"$pop":{"goods":-1}})
3. 修改器
$inc加一个数字
$set修改某一个字段,如果该字段不存在就增加这个字段
把tom的积分加2
db.member.update({"member":"tom"},{"$inc":{"jifen":2}})
把tom的地址改为北京,如果没有就增这个字段
db.member.update({"member":"tom"},{"$set":{"address":"bj"}})
其他参考手册。
五、MongoDB可以存的数据类型
几乎支持任何类型的数据。
null,用于表示空或者不存在的字{"x":null}
布尔,true或false{"y":false}
32位整数,shell中所有数字都是64位浮点数,所以不能在shell中使用
64位整数,同样不能在shell中使用
64位浮点数,{"pi":3.14}
字符串,utf-8字符串{"z":"abs"}
对象id{"_id":ObjectId()}
日期{"d":newDate()}
正则表达式{"reg":/^asx/i}
代码{"code":function(){/***/}}
二进制文件,比如视频文件
未定义{"a":undefined}
数组{"arr":[1,2,3]}
内嵌文档{"x":{"y":"z"}}
六、MongoDB的瞬间完成和安全操作
MongoDB中的插入、删除和更新都是瞬间完成的,因为它们不需要等待数据库响应。客户端将文档发送给服务器后就立刻做其他操作,客户端不会收到ok或不ok之类的响应。就是说没有返回值。优点是速度快。缺点是不知道发生异常了没有。
针对瞬间完成的安全操作是在执行完操作后立即运行db.runCommand({getLastError:1})命令,来检查是否成功。
七、复制
mysql中有主从复制,MongoDB中的复制也是指主从复制。当向主服务器中插入数据时,也会插入从服务器,从而实现读写分离。
步骤,
启动主服务器,a电脑,mongod.exe --master --bind_id 192.168.0.113 --dbpath 数据目录 --logpath 日志目录
启动从服务器,b电脑,mongod.exe --slave --source 192.168.0.115 --dbpath 数据目录 --logpath 日志目录
八、分片
类似mysql的NDB集群处理,实际是分表。MongoDB的分片,用于大数据的分布式存储。具有健康检查机制和数据冗余防丢失机制。
大数据中会使用MapReduce编程模型,用于快速处理大数据。比如从100T的数据中统计某个平均值或最高值等。大数据主要涉及到如何存和如何快速统计两个问题。存储可以采用分布式的,比如将100T分布到10000个服务器,然后,每个服务器大概存10G数据,然后每个服务器分别统计要计算的值,计算完毕,汇总这些计算的值进一步统计得出最终结果。这时,可以使用MongoDB的分片来划分100T来存。使用MapReduce模型,Map把一个任务拆分映射成10000个任务,Reduce就是把多个任务的结果汇总。
九、地理空间索引
为坐标平面查询提供的专门的索引。比如要找到给定经纬度坐标周围最近的火锅店,就需要创建一个专门的索引来提高这种查询的效率。这种服务称为LBS,location based server。
十、使用php操作MongoDB
1. 在php中安装mongodb的扩展
下载php_mongo.dll的扩展包。注意和php的版本,ts与否,vc号以及php的位数的对应。放到ext/目录下。
然后修改php.ini,添加
;mongodb的模块
extension=php_mongodb.dll
extension=php_mongo.dll
然后,重启apache,然后在phpinfo()中可以看到mongdo和mongodb的扩展。否则版本等不对。
2. php代码操作MongoDB
<?php
/**
* php操作mongodb
*/
//创建mongo类
$mongo = newMongoClient ();
//取出所有的商品
$goods =$mongo->php1->goods->find();
foreach ($goods as $k=> $v)
{
echo$v['goods_name'].'--'.$v['price'].'<hr />';
}
//添加记录
$mongo->php1->goods->insert(array(
'goods_name' => 'hah',
'price' => 12,
));