NoSql:not only sql 非关系型数据库 面向对象式的 新浪微博:redis google :bigtable amazon:simpledb 淘宝:tair 视觉网站:mongodb 优酷运营数据分析:mongodb 飞信空间:handlersocket 豆瓣社区:beansdb 优缺点: 优点: 简单的扩展 快速的读写 低廉的成本 灵活的数据模型 缺点: 只是在局部展现出某些优势 不提供对sql的支持 支持的特性不够丰富 现有的产品不够成熟 相对成熟的产品 mongodb,redis 是一个面向集合的,模式自由的文档型数据库 面向集合: 文件存储格式:bson(二进制的json) 使用场景: 持久化的缓存层 高效的实时性 用于对象以及json数据的存储 高伸缩性的场景 大尺寸,低价值的数据存储 不适用: 高度事务 传统的商业智能应用 复杂的多表查询 安装简单: 不需要编译 启动: 建立数据库目录:data 日志文件:dblogs E:\mongodb\bin\mongod.exe --dbpath=e:\mongodb\data --logpath=e:\mongodb\dblogs --install 默认进入:test库 关闭:kill -all 进程号 pkill 进程名 不要用kill -9 否则会产生锁文件 命令: show dbs exit db 当前数据库 show tables /show collections 当前数据库的集合 对比: mysql 数据库(database) 表(table) 记录(rows) mongodb 数据库(database) 集合(collection) 文档对象(document) 隐式创建数据库和表: db.c1.insert({name:"songjiankang"}); db.c1.find() show users 查看所有用户 db.dropdatabase() db.c1.remove(); //删除所有 db.c1.update({name:"user1"},{name:"user00"}) objectid:时间+机器号+进程号+编号 即使把多个集合的数据完全合并都不会冲突 数据类型: null {"one":null} 布尔 {"one":true} 32位整数 64位的整数 64位的浮点数 字符串 符号 objectId类型 对象id是文档中唯一的12位的id 0|1|2|3|4|5|6|7|8|9|10|11 时间戳 机器 pid 计数器 日期 {"one":newDate()} 正则 代码 文档中可以包含js代码{"one":function(){}} 数组:值可以为数组 还可以嵌套{"one":["a",["b","c"]]} 内嵌文档 文档可以包含别的文档,也可以作为值嵌入到父文档中 {"x":{"name":"jian"}} insert save(replace) js 动态插入 for(i=0;i<10;i++){ ... db.c1.insert({user:'name'+i}); ... } //取哪些字段(要的为1,不要的为0,默认会取出_id) db.c1.find({user:"name1"},{user:1,_id:0}); db.c1.find({age:{$gt:5}}); db.c1.find({age:{$lte:5}}); db.c1.find({age:{$ne:5}}); db.c1.count(); db.c1.find().sort({age:-1});//降序 db.c1.find().sort({age:1});//升序 db.c1.find().limit(8)//取多少个 db.c1.find().skip(10).limit(8)//取多少个 db.c2.find({age:{$all:[1,2,4,4444]}});//包含 db.c2.find({age:{$exists:1}});//检测字段是否存在 db.c2.find({age:{$mod:[2,1]}});//取余操作 db.c1.update({name:"user1"},{name:"user2"});//当有满足前面的条件的时候时,直接更新,当不满足前面的条件时,如果有第三个参数1,则会当一条新记录插入进去 db.c1.update({name:10},{$set:{name:100}},0,1);//更新全部符合条件的记录 db.c1.update({name:100},{$set:{age:1000}},0,1);//把满足条件的增加age字段 db.c1.update({"age":50},{$inc:{"ages":100}},0,1); //$set $inc 在字段没有的情况下都会自动增加字段,当条件存在时第三个参数不起作用,第四个参数代表更新记录的行数 db.c1.update({},{$unset:{ages:1}},0,1);//去除多余的字段 db.c1.update({name:"user1"},{$push:{arr:5}});//在val是数组的里面增加值,一次只能增加一个 db.c1.update({name:"user1"},{$pushAll:{arr:[7,8,9]}});//在val是数组的里面增加值,一次只能增加一个 db.c1.update({name:"user1"},{$pop:{arr:1}});//值为数组的减去一个值 $addToSet 同$push 类似,只是前者会检测重复性 db.c1.update({name:"user1"},{$addToSet:{arr:{$each:[1,2,,3,4,5,6]}}});//压入一个数组并检测其重复性 db.c1.update({name:"user1"},{$pull:{arr:1}});//删除数组中值为1的元素 db.c1.update({name:"user1"},{$pullAll:{arr:[2,3,4]}});//一次性删除数组中多个元素 db.c1.update({name:"user1"},{$rename:{"name":"kang"}},0,1);//重命名key { "_id" : ObjectId("50358b45c3fec12531a5f899"), "arr" : [ { "class" : "php" }, { "class" : "mysql" }, { "class" : "java" }, { "class" : "javascript" }, { "class" : "java" } ], "name" : "user1" } 查找上面的记录: db.c1.find({"arr.class":"java"}); db.c1.update({"name.user1":'a'},{$set:{"name.$.user1":"aaaaaaaaaaaa"}});//注意:连写的key都要引起来 var x = db.c1.findOne({"user":"user1"});//x相当于一个json对象 可以用x来动态修改 x.age = 10; db.c1.save(x);//修改到对象中 ———————————————————————————————————————————————————————————————————— db.c1.drop();//删除表 db.stats(); db.dropDatabase();//删除当前数据库 use test;有的进入,没有则创建 db.createCollection("c2");//显式创建集合 —————————————————————————————————————————————————————————————————————————— 普通集合:动态增长 固定集合:可以更新,但不可以超过总大小,不允许删除,但可以drop()删除所有的行,drop后需要显式的重建集合,32位机器上一耳光capped collection的最大值约482.5M,64位上只受系统文件大小的限制 好处: 插入速度极快 按照插入顺序的查询输出速度极快 能够在插入最新数据时,淘汰最早的 用处:存储日志信息 缓存一些少量的文档 创建固定集合(必须显式创建):db. db.createCollection("c3",{capped:true,size:10000,max:3});(没有索引) 先根据容量限制进行淘汰,在根据文档个数限制进行淘汰 普通转固定集合: db.runCommand({convertToCapped:"c1",size:100000,max:3}); gridfs:用来存储大的二进制文件 存储巨大文件:视频高清图片 利用gridfs可以简化需求 直接利用已经建立的复制或分片机制,故障恢复和扩展都很容易 避免用户上传内容的文件系统出现问题 不产生碎片 fs.files 上传文件的基本信息 fs.chunks 二进制文件 db.fs.chunks.find(); db.fs.files.find(); mongofiles list / get/ put /delete md5sum mongo//计算md5值 ___________________________________________________________________ 索引: system.indexes索引 db.fs.files.drop(); db.fs.chunks .drop(); db.c1.find().explain();//查看是否用到索引 db.c1.ensureIndex({name:1}) //name上建立索引 1为升序,-1为降序 db.c1.getIndexKeys();//查看索引状态 db.c1.getIndexes()//详细查看 db.c1.ensureIndex({age:1},{unique:1});//建立唯一索引: db.c1.dropIndex({"name":1});//删除索引 db.c1.dropIndexes(); //删除所有索引 优化器:profile慢查询工具 1.开启方式:db.setProfilingLevel(2);//0:不开启,1:记录慢命令(默认100ms),2:记录所有命令 查看是否开启慢查询:db.getProfilingLevel(); db.systme.profile().find().sort({$natural:-1}).limit(1); ts:时间 info:命令的详细信息 reslen:返回结果集的大小 nscanned:本次查询扫描的记录数 nreturn:本次查询实际返回的结果集 millis:耗时(毫秒) show Profile可列出最近5条超过1ms的记录 限制返回的条数:db.c1.find().sort({ts:-1}).limit(10); 查询指定的字段:db.c1.find({},{ts:1,title:1}).sort({ts:-1}).limit(10); 性能监控工具(监视网络情况): /usr/local/mongodb/bin/mongosniff --source net lo /usr/local/mongodb/bin/mongostat 数据的导出:/usr/local/mongodb/bin/mongoimport -d test -c c1 -o /tmp/song.data 导入:/usr/local/mongodb/bin/mongoimport -d test -c c1 /tmp/song.data 备份数据库: ./mongodump -d test -o /tmp/ 回复数据库: ./mongorestore -d test /tmp/test 用户和授权: 默认不进行验证 两类用户:超级用户,每个数据库的用户 默认用户超级管理员登陆 /usr/local/mongodb/bin/mongod --auth -dbpath=/usr/local/mongodb/data -logpath=/usr/local/mongodb/dblogs --profile 2 & (授权登陆) 启动的时候带 --auth 登陆才受限制 //设定用户以后,匿名用户就没有权限了 use admin(注意admin里面的为超级管理员--特殊) db.addUser("root",123456);//增加用户 db.auth("root",123456); 登陆的时候必须指定指定数据库的指定用户 /usr/local/mongodb/bin/mongo -u root -p 123456 localhost:27017/admin 主从集群: master-slave主从复制 replica sets复制(副本集) 当有一台宕机以后,会发组播从新选举出一台住服务器 实验(主从复制): 启动主: master: /usr/local/mongodb/bin/mongod --master -dbpath=/usr/local/mongodb/data1 --logpath=/usr/local/mongodb/dblogs1 --port 20000 & 启动从: /usr/local/mongodb/bin/mongod --slave --source 127.0.0.1:20000 -dbpath=/usr/local/mongodb/data2 --logpath=/usr/local/mongodb/dblogs2 --port 20001 & ______________________________________________________________ 副本集: 启动多个(只是配置文件不同) 1》 ./mongod --replSet rs1 --keyFile=/usr/local/mongodb/key/key1 --port 20000 --dbpath=/usr/local/mongodb/data/data1/ -logpath=/usr/local/mongodb/log/log1 --fork 2》登陆一个,然后配置下(会议清单) config_rs1={ _id:"rs1", members:[ {_id:0,host:"localhost:20000",priority:1}, {_id:1,host:"localhost:20001",priority:2} ] } rs.initiate(config_rs1);//初始化配置 从的需要 rs.slaveOk();才可以查看 安装mogo php扩展: 打模块 1.解压模块,在目录下运行/bin/phpize 2. ./configure --with-php-config=/www/wdlinux/php/bin/php-config --enable-mongo 3.make && make install 4.php.ini中添加模块的路径 1>extension_dir = "/www/wdlinux/nginx_php-5.2.17/lib/php/extensions/no-debug-zts-20060613" 2>extension=mongo.so 以授权方式连接mongodb:"mongodb://root:123456@localhost:27017/admin" $conn = new Mongo("mongodb://root:123456@localhost:27017/admin"); $db = $conn->test; $c1 = $db->c1; $arr = array(); $res = $c1->find($arr); foreach($res as $val){ print_r($val); }