• nosql之MongoDB


    大数据时代的3v
    海量数据 volume:sql 上千万慢 mysql 34千万慢(都过亿了 就凉凉)而 orecle 集群太贵

    多样数据variety:多种多样的数据:建立一个表的时候 可以给这个表里面插任何数据, 如json 建立一个表的时候 可以给这个表里面插任何数据, 如json 在关系型数据库不行

    实时数据-velocity:读写数据-并发高 要实时

    互联网需求的3高
    高并发:关系型数据访问的数据是直接硬盘读取 并发高造成io高会报错 数据库连接数量会达到瓶颈(一般遇到sql拒绝就是访问数量超出or访问时间超长)
        原因基本就是:就是处理请求太慢了,数据直接取操作硬盘,所以就可以用内存-redis mongodb(根据业务选择中间件) 解决高并发
    高可扩:适用中间件搭建集群简单,不行就扩展,放在mysql不好实现
    高性能:合理利用起来就是高性能了

    这里可以看出nosql的强大之处,但是具体数据库选择是RDBMS还是NoSql 是看项目的

    MongoDB

    1.是分布式的-(像redis,kafka),数据存储于硬盘,但是经常读取的数据会弄到内存中去 内存数据映射-提高查询效率

    2.分布式优点

      可靠性(容错):一台服务器崩溃不影响到其他服务器,如mysql数据库一挂,整个网站都GG

      可扩展:根据需求增加更多机器,原先只能加硬件

      资源共享:如用户数据,订单数据,财务数据,各个系统之间共享

      灵活性:分布式下容易安装,实施和调试新的服务

      更快的速度:分布式计算系统可以有多台计算机的计算能力,中间件有更快的速度就是利用刷盘机制

      开放:本地和远程都可以访问该服务

      更高的性能和更好的性价比

    3.分布式缺点

    故障排除:出现问题排除和诊断更麻烦

    网络:传输问题,高负载,信息丢失。 因为是各个进程间通信 网络波动都影响-nosql,丢数据比例比RDBMS更大

    安全:开放系统的特性让分布式计算系统安全和共享更高

    mongodb刷盘机制(高效的原理)

    1.mysql数据存储是直接存到Data file(dsik硬盘)里面的 所以小数据没啥问题,大量数据就响应慢,但数据不会丢失

    2.而mongodb 存到ram缓冲区之后直接返回给客户端(说我保存成功了,响应快) 然后每100ms(可配置时间)把缓冲区的数据存到日志文件硬盘里面,最后os flush/60s(可配置) 然后存到硬盘

    通俗解释,mysql发消息直接到数据库,好处就是消息不会丢失,但是并发慢

        mongodb相当于中间加了一层redis,高并发好,但是因为多了一层所以数据丢失性也高

    3.提高mongdb读的性能(数据预热),本身有一个机制经常查的数据会放到内存中 所以可以写一个作业定时查一下经常查的数据

     

     

     

     如何解决海量数据下的16MB文档限制?

      1.提前存储的时候把关联关系做好,就不需要在业务中合并

      2.联查-通关数据冗余, 文档里面存 (子文档1的PID,子文档2的PID)  查出来之后聚合在业务中    文档相当于sql的表

     

    如何使用

    docker如何下载安装 mongodb

      指令运行:docker run -itd --name mongo -p 27017:27017 mongo

    mongodb可视化查询

    1.navicat premium

    2.网页可视化管理工具 

    docker run -it --rm \
    --name mongo-express \
    -p 8081:8081 \
    -e ME_CONFIG_OPTIONS_EDITORTHEME="ambiance" \
    -e ME_CONFIG_MONGODB_SERVER="192.168.3.214" \
    -e ME_CONFIG_MONGODB_PORT="27017" \
    -e ME_CONFIG_BASICAUTH_USERNAME="admin" \
    -e ME_CONFIG_BASICAUTH_PASSWORD="admin" \
    mongo-express
    
    运行成功后
    
    http://自己的本地ip:8081
    用户名密码都是admin
    View Code

    mongodb查询操作

    1.Mongodb基本操作
    查询数据库
    show databases
    切换数据库
    use test
    查询当前数据库下面的集合
    show collections
    创建集合
    db.createCollection("集合名称")
    删除集合
    db.集合名称.drop()
    删除数据库
    db.dropDatabase() //首先要通过use切换到当前的数据库
    View Code

    2.Mongodb增删改查(CURD)

    id 系统会自动加一个
    时间戳+机器码 生成
    增(insert)
    查询数据库
    show databases
    切换数据库
    use test
    查询当前数据库下面的集合
    show collections
    创建集合
    db.createCollection("集合名称")
    删除集合
    db.集合名称.drop()
    删除数据库
    db.dropDatabase() //首先要通过use切换到当前的数据库
    123456789
    10
    11
    12
    查(find)
    排序&分页
    新增一条
    db.userinfo.insert({name:"贾宝",age:25,gander:"",address:'贾府'})
    新增多条
    db.userinfo.insert([{name:"贾宝",age:25,gander:"",address:'贾府'}
    ,{name:"林黛玉",age:16,gander:"",address:'林 府'}])
    可不可以快速插入10条数据
    for(var i=1;i<=10;i++) {
     db.userinfo.insert({name:"clay"+i,age:i})
     } 
    123456789
    10
    11
    查询所有的数据
    db.集合名称.find({})
    查询top条数
    db.集合名称.find({}).limit(条数)
    条件查询
     db.userinfo.find({name:"clay1",age:1},
    {name:1,_id:0})
    View Code
    3.排序&分页
    db.c1.insert({_id:1,name:"a",sex:1,age:1})
    db.c1.insert({_id:2,name:"a",sex:1,age:2})
    db.c1.insert({_id:3,name:"b",sex:2,age:3})
    db.c1.insert({_id:4,name:"c",sex:2,age:4})
    db.c1.insert({_id:5,name:"d",sex:2,age:5})
    db.c1.find()
    正序
    db.c1.find({}).sort({age:1})
    降序
    123456789
    10
    运算符 作用
    $gt 大于
    $gte 大于等于
    $lt 小于
    $lte 小于等于
    $ne 不等于
    $in in
    $nin not in
    运算符
    改(update)
    db.集合名.update(条件, 新数据)
     {修改器: {键:值}}
     db.c1.find({}).sort({age:-1})
    分页查询 跳过两条查询两条
     db.c1.find({}).sort({age:1}).skip(2).limit(2) 
    11
    12
    13
    View Code
    4.运算符
    //年龄大于1
    db.c1.find({age:{$gt:1}})
    //年龄是 3,4,5的
    db.c1.find({age:{$in:[3,4,5]}})
    View Code

    5.update

    db.集合名.update(条件, 新数据)
    {修改器: {键:值}} 

    修改器  作用
    $inc    递增
    $rename 重命名列
    $set   修改列值
    $unset  删除列

    准备数据
     db.c1.insert({name:"8888",age:1,addr:'address',f
    lag:true})
     db.c1.update({name:"8888"}, {name:"99"})
     db.c1.update({name:"8888"}, 
     {
      $set:{name: "zs44"},
      $inc:{age:10},
      $rename:{addr:"address"} ,
      $unset:{flag:""}
       }
     )
     db.c1.find({name:"zs44"})
    View Code

    6.delete

    //全部移除
    db.userinfo.deleteMany({})
    db.userinfo.deleteMany({age:1})
    123
    View Code

    7.聚合查询

    顾名思义就是把数据聚起来,然后统计
    语法
      db.集合名称.aggregate([
       {管道:{表达式}}
         ....
    ])  
    
    常用管道
    $group 将集合中的文档分组,用于统计结果
    $match 过滤数据,只要输出符合条件的文档
    $sort 聚合数据进一步排序
    $skip 跳过指定文档数
    $limit 限制集合数据返回文档数
    常用表达式
    $sum 总和 $sum:1同count表示统计
    $avg 平均
    $min 最小值
    $max 最大值
    
    查询例子
    
    use test4
    db.c1.insert({_id:1,name:"a",sex:1,age:1})
    db.c1.insert({_id:2,name:"a",sex:1,age:2})
    
    统计男生、女生的总年龄
    db.c1.aggregate([
    {
     $group:{
    _id: "$sex",
    rs: {$sum: "$age"}
     }
    }
    ])
    
    统计男生、女生的总人数
    db.c1.aggregate([
    {
     $group:{
    _id: "$sex",
    rs: {$sum:1}
     }
    }
    ])
    求学生总数和平均年龄
    db.c1.aggregate([
    {
     $group:{
    _id: null,
    total_num: {$sum:1},
    total_avg: {$avg: "$age"}
     }
    }
    ])
    查询男生、女生人数,按人数升序
    db.c1.aggregate([
    {$group:{_id: "$sex",rs: {$sum: 1}}},
    {$sort:{rs: -1}}
    ])
    View Code
    8.自增id
    #创建序列
    db.counters.insert({_id:"productid",sequence_value:0}) 
    9.创建 Javascript 函数 
    现在,我们创建函数 getNextSequenceValue 来作为序列名的输入, 指定的序列会自动增长 1 并返回最新序列值。在本文的实例中序列名为 productid
    >function getNextSequenceValue(sequenceName){
       var sequenceDocument = 
    db.counters.findAndModify(
         {
             query:{_id: sequenceName },
             update: {$inc:{sequence_value:1}},
             "new":true
         });
       return sequenceDocument.sequence_value;
    }
    View Code
    使用 Javascript 函数
    接下来我们将使用 getNextSequenceValue 函数创建一个新的文档, 并设置文档 _id 自动为返回的序列值:
    >db.products.insert({
       "_id":getNextSequenceValue("productid"),
       "product_name":"Apple iPhone",
       "category":"mobiles"})
    >db.products.insert({
       "_id":getNextSequenceValue("productid"),
       "product_name":"Samsung S3",
       "category":"mobiles"})
    View Code
    就如你所看到的,我们使用 getNextSequenceValue 函数来设置
    _id 字段。
    为了验证函数是否有效,我们可以使用以下命令读取文档:
    >db.products.find()
    以上命令将返回以下结果,我们发现 _id 字段是自增长的:
    事务
    use test
    db.createCollection("userinfo") s=db.getMongo().startSession()
    s.startTransaction()
    s.getDatabase("test").userinfo.insert({name:"a"})
    s.commitTransaction()
    View Code
    数据失效机制
    mongodb失效的机制大概是这样的
    为集合创建一个indexes(索引)
    db.testCollection.ensureIndex( { "Date": 1 }, {expireAfterSeconds: 10 } )
    然后确保每次插入数据的时候有该列,mongodb将会自动为你删除
    该列
    db.testCollection.insert({"Date" : newDate(),"name":"zs","age":18}){ "_id" : 1, "product_name" : "Apple iPhone","category" : "mobiles"}{ "_id" : 2, "product_name" : "Samsung S3","category" : "mobiles" }
     
    use test
    db.createCollection("userinfo")
    s=db.getMongo().startSession()
    s.startTransaction()
    s.getDatabase("test").userinfo.insert({name:"a"})
    s.commitTransaction()
    设置的失效列必须为索引并且为日期格式
  • 相关阅读:
    HDU1213How Many Tables并查集
    Redis新的存储模式diskstore
    GPFS文件系统笔记
    redis持久化
    360安全卫士qurl.f.360.cn分析
    [原创]解决DataSet的GetXml()方法空列不返回问题
    在多台服务器上简单实现Redis的数据主从复制
    史航416随笔
    史航416实验1总结
    史航416第二次作业总结
  • 原文地址:https://www.cnblogs.com/LZXX/p/15905794.html
Copyright © 2020-2023  润新知