zoukankan      html  css  js  c++  java
  • mongodb学习笔记

    A.
    Mongodb特点、功能、使用场景
    Mongodb的安装和配置
    Mongodb体系结构
    数据库的启动、停止、连接
    JSON/BSON数据格式
    Mongodb
    1. 特点
    数据在内存中,通过后台线程写入磁盘
    无模式结构进行数据存储---->如产品数据,不同的产品描述完全不一样,那么如果用关系数据库很难处理
    可以进行实时插入(写性能非常好)
    自动碎片处理
    存储数据格式是二进制json格式===>bson
    支持二进制数据和大型对象(图片)
    2.使用场景
    网站数据 Mongodb 非常适合实时的插入,更新、查询,并且具备了网站实时数据存储所需要的复制及高度伸缩性
    缓存:作用信息数据的缓存层
    大尺寸,低价值的数据
    高伸缩性,适合百台服务器组成的数据库集群有,MapReduce引擎的内置支持。
    3. 不适用场景
    .高度事务性的系统 例如银行、会计
    传统的商业智能应用
    无法控制数据写入磁盘的顺序
    4.Mongodb 的安装
    windows版: 解压、进入bin目录(如果设置了环境变量无所谓那个目录了)
    在mongodb目录下建立data文件夹,指定存放数据的目录--->可以是其它目录
    启动命令 mongod --dbpath=d:\mongodb\data
    客户端连接:mongo
    Linux版:
    tar -zxvf mongodb-linux-i686-2.6.3.tgz
    建立日志、数据文件夹
    启动命令:./mongod -dbpath=/usr/nosqlsoft/mongodb/db -logpath=/usr/nosqlsoft/mongodb/logs/mongo.log --fork
    客户端连接: ./mongo

    Mongodb启动可以有一些其它参数
    dbpath
    logpath 错误日志文件
    logappend 错误日志采用的追加模式
    bind_ip 对外服务绑定的ip,一般设置为空
    port 对外服务的端口(不想用默认的)
    fork 以后台以守护进行的方式运行服务
    MaxConns
    其它... ....

    5.体系结构
    Mongodb 是一个可移植的数据库,在不同平台是完全一样的,数据的逻辑结构和数据存储方式等等。
    关系数据库是数据库的概念database Mongodb中是db的概念
    关系数据库 -->表 Mongodb--->Collection(集合)
    关系数据库 --->记录 Mongodb --->document(文档)

    数据存储结构
    如果有数据库foo 数据库文件就会有foo.ns,foo.0,foo.1,foo.2等等

    Mongodb有预分配空间的机制,每个预分配文件都用0进填充
    Mongodb就始终保持额外的空间和空余的数据文件,避免数据暴增长带来的磁盘压力写过大的问题
    数据文件每新分配一次,它的大小都会是上一个数据文件大小的2倍。最大2G
    数据库每张表(集合)对应一个命名空间,这写数据都集中在.ns文件中
    6. 数据格式 二进制json ====》bson格式
    {"300001":{name:"上证指数",yes:3000.0,tod:2990.1,now:3002.73},"000001":{name:"浦发银行",yes:23.22,tod:23.5,now:23.0}}
    json格式类型执行非常快,且不昂贵
    对js来说表示的对象
    可以跨域传递信息

    -------------------------------------------------------------------------------------------------------------
    B.
    bson
    Mongodb的增删改查操作
    Mongodb 客户端GUI工具
    Mongodb基本操作
    1.bson 二进制的json
    2.基本操作
    关闭服务 :可以直接ctrl+c关闭
    也可以是进入admin数据库 use admin
    db.shutdownServer()
    2.1插入记录的操作
    j = {name:"zhangsan",age:30};
    db.mydb.save(j)
    t = {name:"lisi",age:32};
    db.mydb.insert(j)
    注意:不需要预先创建一个集合,在第一次插入数据时会自动创建。
    文档中可以存储任何结构的数据,实际应用中大部分还是相同文档的集合,这个比较灵活,结构不同也没关系
    每次插入数据的时候集合中都会有一个ID,属性名称是_id
    写一个循环插入数据:
    for(var i = 1; i < 10;i++)db.mydb.save({x:3,j:i})

    db.mydb.find()
    如果屏幕没有全部显示可以使用it命令显示下一屏
    2.2"_id"
    存储在Mongodb中的每一个文档都会有一个默认主键_id,名称固定
    可以是任何类型,默认是ObjectId ,必须唯一
    如果不用这个类型,必须显示写出 db.mydb.insert({"_id":"0001",name:"zhangsan"})

    2.3查询操作
    db.mydb.find()
    var cursor = db.mydb.find();
    while(cursor.hasNext()) printjson(cursor.next())
    ===============================
    类似与js 脚本
    db.mydb.find().forEach(printjson);

    ================
    在Mongodb的脚本当中
    var cursor = db.mydb.find()
    可以把cursor当做一个数组来操作
    printjson(cursor[0])
    printjson(cursor[1]);
    ======================
    var arr = db.mydb.find().toArray();
    arr[0];
    arr[1];
    注意:这些特性只是在Mongodb shell里使用,而不是所有其它应用程序都支持。
    Mongodb 游标对象不是没有快照,如果有其他用户在集合里第一次后者最后一次调用next(),你可能得不到游标里的数据,所以要明确锁定你查询的游标
    2.4 简单的条件查询
    db.mydb.find({x:4}).forEach(printjson)
    db.mydb.find({x:4,j:90}).forEach(printjson);
    2.5 findOne()语法
    只返回游标中的第一条数据,或者返回null即是空数据
    printjson(db.mydb.findOne({x:4}));
    printjson(db.mydb.findOne({x:1000}));1000不存在返回null
    2.6通过limit限制结果集的数量
    db.mydb.find().limit(3);
    2.7修改记录
    db.mydb.update({name:"zhangsan"},{$set:{name:"zhangsan_new"}})

    db.mydb.update({属性1:"值",属性2:"值"...},{$set:{属性:新值,属性:新值}})
    3.常用的工具集
    bsondump:讲bson格式的文件转存为json格式数据
    mongo:客户端命令行工具,其实也是一个js解释器,支持js语法
    mongod:数据库服务器
    mongodump/mongorestore 数据库备份和回复工具
    mongoexport/mongoimport 数据导入导出工具
    mongofiles:GridFs管理工具,实现二进制文件的存取
    mongos:分片路由,如果使用sharding功能,应用程序连接的是mongos而不是mongod
    mongostat:实时性能监控工具
    4.客户端GUI
    MongoVUE http://www.mongovue.com 可视化工具
    PHP写的工具 RockMongo http://code.google.com/p/rock-php/
    MongoHub 专门针对Mac系统的图形管理界面

    -------------------------------------------------------------------------------------------------------------------------------
    C.
    Mongodb 高级查询
    1.条件操作符
    < ,<=,>,>=
    db.collection.find({"field":{$gt:value}})//大于
    db.mydb.find({"age":{$gt:30}});
    db.collection.find({"field":{$lt:value}})//小于
    db.collection.find({"field":{$gte:value}})//大于等于
    db.collection.find({"field":{$lte:value}})//小于等于
    多条件
    db.collection.find({"field1":{$gt:value1,$lt:value2}})
    db.mydb.find({"age":{$gte:30,$lte:32}});
    db.mydb.find({"age":{$gte:30,$lte:32},"name":"lisi"});
    2.$all 匹配所有
    这个操作符合sql语法的in类似,不同的是,in只需要满足()中的某个即可,
    而$all必须满足[]内的所有值:
    db.mydb.insert({name:"zhaoliu",age:[30,32,34]});
    db.mydb.find({"age":{$all:[30,32]}});
    3.$exists 判断字段是否存在
    查询含有age属性的文档
    db.mydb.find({age:{$exists:true}})
    查询不含有age属性的文档
    db.mydb.find({age:{$exists:false}})
    4.NULL值处理
    db.mydb.find({"age":{$in:[null],$exists:true}}); 查询含有age属性,并且值是null的

    查询的是没有age属性和有age属性值为null的文档
    db.mydb.find({"age":{$in:[null]}});
    5.$mod取模运算
    age属性除以10余数是2的文档取出
    db.mydb.find({age:{$mod:[10,2]}}); age属性%10 ==2的
    6.$ne 不等于
    年龄不是30的,全部查询出来 包含了不含age属性的文档,也包含了age属性是null的文档
    db.mydb.find({age:{$ne:30}})
    查询有年龄属性并且值不是30的。
    db.mydb.find({age:{$ne:30,$exists:true}});
    7.$in 与sql标准语法的用途是一样的,即要查询的是一系列枚举范围内.
    db.mydb.find({age:{$in:[30,23]}})

    8.$nin 不包含
    db.mydb.find({age:{$nin:[30,23]}})
    db.mydb.find({age:{$nin:[30,23],$exists:true}})
    9.$size 数组元素的个数
    db.mydb.find({age:{$size:3}})
    db.mydb.find({age:{$size:1}})
    db.mydb.insert({age:[100]});
    db.mydb.find({age:{$size:1}})
    10.正则表达式匹配
    查询不匹配name=z*带头的记录
    db.mydb.find({name:{$not:/^z.*/}})
    db.mydb.find({name:{$not:/^z.*/,$exists:true}});
    11.JavaScript查询和$where查询
    查询j 大于20的数据
    db.mydb.find({j:{$gt:20}})
    db.mydb.find({$where:"this.j>20"});
    db.mydb.find("this.j>20")
    =======================
    f=function(){return this.j>20;}
    db.mydb.find(f);
    12.count查询记录条数
    db.mydb.find().count()
    db.mydb.find({j:{$gt:90}}).count()
    13.skip限制返回文档的起点
    从第3条记录开始,返回5条记录
    db.mydb.find().skip(3).limit(5);
    14.sort
    db.mydb.find({age:{$exists:true}}).sort({age:1})升序
    db.mydb.find({j:{$exists:true}}).sort({j:-1});
    ----------------------------------------------------------------------------------
    D:
    mongodb高级应用
    存储过程
    capped Collection使用
    GridFs实现海量数据存储
    Mongodb的MapReduce实现
    1.游标

    1>
    for(var a=db.person.find();a.hasNext();){
    printjson(a.next());
    }
    2>
    var a = db.person.find();
    while(a.hasNext()){
    printjson(a.next());
    }
    3>
    db.person.find().forEach(function(u){ printjson(u)});

    2.存储过程
    mongodb的存储过程利用javascript书写
    sql自定义函数
    function addNumbers(x,y){
    return x+y;
    }
    sql自定义函数转换成存储过程db.system.js.save();
    1)定义存储过程
    db.system.js.save({"_id":"addNumbers",value:function(x,y){ return x+y;}});
    --->_id:对应相当有函数名 value:对应函数体
    这样形成了mongodb的存储过程
    2)查看存储过程:
    db.system.js.find();
    3)执行存储过程
    db.eval('语句');
    如:
    db.eval('addNumbers(2,3)');

    注意:eval()是个特殊函数,可以不定义存储过程,直接内部嵌套函数使用
    db.eval(function(){ return 3+3;});
    -----------------------------------------------------
    db.system.js.save({"_id":"getCount",value:function(){ return db.person.count();}});
    调用
    db.eval('getCount()');

    注意:js的语法与mongodb的基本操作

    3.capped collection
    性能比较出色
    1)-种特殊集合,固定大小的集合,数据满了后按lru(最近最少使用)和按着插入顺序对老化数据移除
    2)建立是预先指定大小,数据满后,再增加数据,将最老数据替换掉
    3)可以插入和更新,不能查过集合的大小否则更新失败
    4)不可以删除,可以通过drop删除集合中所有行,删除后,集合需要重建
    5)32位机器上,一个capped collection最大为483.5m
    64位机器上无限制

    ****用途
    (1)loggging 做日志,将系统日志写入, 可以减少人员维护(自动清理lru),同时capped collection可以查看最近的插入数据(自动维护查询顺序),capped collection有最大容量限制
    (2)cached
    (3)auto archiving 将统计的中间结果记录到capped collection中,便于统计提取
    发挥最大性能
    利用写入特性,写入多,读取少,最少不要建立索引,否则影响插入速度
    利用自然排序也就是维护插入顺序
    使用时候注意事项
    建立时候设定maxsize,和 初始size,因为capped collection使用时候,总是先检查size再检查max
    可以利用validate查看使用了多少,以便决定设定多大
    创建cappped collection语法
    db.createCollection("capcol",{cappped:true,size:100000,max:100});
    创建普通:collection
    db.createCollection("mu");
    删除集合中的元素
    db.collectionName.drop();

    注意:
    默认情况下系统会自动为collection创建索引,但是不会对capped collection创建索引


    4.GridFs
    是mongodb的一种存储大型文件的规范
    内部提供了将大型文件进行存储,将文件分成若干个小块(小文档进行存储)
    可以存放图片或视频文件
    注意:在互联网中一般用针对性的分布式文件系统存放文件、视频等hdfs gfs tfs
    GridFs存放和查看文件
    GridFs利用两个集合存放文件,默认前缀为fs

    1)files 存放元数据对象
    2)chunks存放相关系统二进制块
    fs.files fs.chunks
    命令
    mongodbfiles put d:\\filename
    mongodbfiles list
    db.fs.files.find();

    mongofiles put d:\\ddd.pdf
    mongofiles list

    获取文件
    mongofile get filename

    mongofiles get d:\\ddd.pdf
    客户端查看:
    show collections;
    可以显示 fs.chunks,fs.files
    db.fs.files.find();查看字段说明
    filename:文件存放名称
    chunkSize:分块大小
    uploadDate:入库时间
    md5:加密方式
    connected to: 127.0.0.1
    added file: { _id: ObjectId('54f48b837ea57845ede86935'), filename: "d:\\ddd.pdf"
    , chunkSize: 261120, uploadDate: new Date(1425312644357), md5: "21c7b1d4d246f779
    20f45f5ed855f23c", length: 49307054 }
    ============================================
    E:Mongodb管理
    1.MapReduce
    很像关系数据库中的分组操作
    Mongodb使用Map/Reduce进行并行统计
    Mongodb使用MapReduce需要使用两个函数,一个Map函数还有一个就是Reduce函数。
    Map函数是通过调用emit(key,value)遍历collection中所有记录,然后将key与value传递
    给Reduce函数进行处理。这两个函数都可以使用JS实现
    通过db.runCommand或者是mapReduce命令来执行一个操作

    map函数----->分解产生key values
    reduce函数--->合并接受key values参数进行操作
    a.准备数据
    db.students.insert({classid:1,age:14,name:"Tom"});
    db.students.insert({classid:1,age:14,name:"Tom"});
    db.students.insert({classid:1,age:14,name:"Tom"});
    db.students.insert({classid:2,age:9,name:"Tony"});
    db.students.insert({classid:2,age:13,name:"Harry"});
    db.students.insert({classid:2,age:19,name:"Vincent"});
    db.students.insert({classid:1,age:14,name:"Bill"});
    db.students.insert({classid:2,age:17,name:"Bruce"});
    b.map函数
    //相当于this.classid的值作为key,1作为对象的values
    m = function(){emit(this.classid,1)};
    c.reduce函数
    r = function(key,values){
    var x = 0;
    values.forEach(function(v){x+=v});
    return x;
    }
    d.执行
    res = db.runCommand({
    mapreduce:"students",
    map:m,
    reduce:r,
    out:"students_res"
    });

    以此作为进一步处理的函数
    f = function(key,value){return {classid:key,count:value};}
    res = db.runCommand({
    mapreduce:"students",
    map:m,
    reduce:r,
    out:"students_res",
    finalize:f
    });

    加入一些条件
    res = db.runCommand({
    mapreduce:"students",
    map:m,
    reduce:r,
    out:"students_res",
    finalize:f,
    query:{age:{$lt:10}}});

    另外一个案例
    book1 = {name:"Understanding Java",pages:100};
    book2 = {name:"Understanding Json",pages:200};
    book3 = {name:"Understanding XML",pages:300};
    book= {name:"Understanding webService",pages:400};
    book={name:"Understanding Axis2",pages:150};

    map函数
    var map = function(){
    if(this.pages>=250)
    category = "Big Books";
    else
    category = "Small Books";
    emit(category,this.name);
    };
    var reduce = function(key,values){
    var sum = 0;
    values.forEach(function(doc){
    sum += 1;
    });
    return {books:sum};
    };
    执行
    db.books.mapReduce(map,reduce,{out:"book_results"});
    查看db.book_results.find();


    2. 数据导出mongoexport
    mongoexport -d test -c books -o d:\\books.dat ---->json格式
    -d 指定数据库 -c 集合 -o 文件

    mongoexport -d test -c books -csv -o d:\\books_csv.dat ---->csv格式

    3.导入
    mongoimport -d test -c books d:\\books.dat --->json格式
    mongoimport -d test -c books --type csv --headerline --file d:\\books_csv.dat--->导入csv格式数据
    ------------------------------------------------------------------------------------------

    f.
    osql第十八讲-Mongodb服务器管理
    1.备份与恢复
    如何创建一个数据库 use 数据库名称 如果数据库存在直接打开,如果不存在创建并打开
    use testdb
    备份 mongodump -d 数据库
    mongodump -d testdb
    会直接在当前目录下创建已给dump目录,用于存放备份出来的文件
    可以指定备份存放的目录
    mongodump -d testdb -o mydump

    恢复
    删除数据库 进入数据库 use 数据库名 db.dropDatabase();
    mongorestore -d 数据库名称 dump/数据库名称
    mongorestore -d testdb dump/testdb

    mongorestore -d testdb 自定义文件夹的名字/testdb

    可以不用先删除数据库用的时候指定-drop 参数即可 先删除表再向表中插入数据
    mongorestore -d testdb -drop dump/testdb


    2.访问控制
    前面Mongodb启动后,都可以直接操作,而且是任意操作。这样会带来不安全。
    我们可以:
    绑定IP内网地址访问mongodb服务
    设置监听端口
    使用用户名和口令

    绑定IP
    启动的时候添加参数 --bind_ip
    如:启动时添加参数 --bind 192.168.0.3 --->只能该ip访问
    mongod --bind_ip 127.0.0.1 --dbpath=d:\mongodb\data就只能本机访问了。

    设定端口默认端口是27017
    mongod --bind_ip 127.0.0.1 --port 28018 --dbpath=d:\mongodb\data
    mongo 127.0.0.1:28018

    用户名和密码
    默认对所有的库具有root权限,所有操作都可以进行。
    可以通过指定参数来设置。
    只需要启动--auth --->启动了登陆验证模块 默认启动之后操作都还可以进行。
    在最初的时候Mongodb都默认有一个admin数据库(是空的)
    admin.system.users中保存了比其它数据库中设置的用户权限更大的信息。
    当admin.system.users中没有添加任何用户时,即使Mongodb启动了验证
    模块依然可以进行任何操作。所以需要往该集合中增加文档。

    建立系统root用户
    db.addUser("root","1234");

    db.auth("root","1234");

    mongo -u root -p
    输入密码1234
    连接成功
    以后启动时,如果加了--auth 连接时必须通过用户名密码,否则能连接,不能进行其他操作


    Mongodb也支持为某个特定的数据库来设置用户。
    给test加个只读用户
    db.addUser("用户名","密码",true)
    用该用户登录 能进行只读操作

    3.命令操作
    db.user.count();
    mongo test --eval "printjson(db.user.count())"

  • 相关阅读:
    tomcat 配置ssi
    oracle exp imp 导入 正在跳过表 plsql 导入表 成功终止 数据 被导入
    oracle 创建数据表空间和用户
    移动端开发来个总结吧
    ssl四次握手
    面试-布局
    typeof的原理?
    马上面试了就,复习一下排序
    关于webview无法设置页面标题
    关于let的生命提升
  • 原文地址:https://www.cnblogs.com/huboking/p/4330326.html
Copyright © 2011-2022 走看看