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
mongodb查询操作
查询数据库 show databases 切换数据库 use test 查询当前数据库下面的集合 show collections 创建集合 db.createCollection("集合名称") 删除集合 db.集合名称.drop() 删除数据库 db.dropDatabase() //首先要通过use切换到当前的数据库
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})
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
//年龄大于1 db.c1.find({age:{$gt:1}}) //年龄是 3,4,5的 db.c1.find({age:{$in:[3,4,5]}})
5.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"})
6.delete
//全部移除 db.userinfo.deleteMany({}) db.userinfo.deleteMany({age:1}) 123
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}} ])
>function getNextSequenceValue(sequenceName){ var sequenceDocument = db.counters.findAndModify( { query:{_id: sequenceName }, update: {$inc:{sequence_value:1}}, "new":true }); return sequenceDocument.sequence_value; }
>db.products.insert({ "_id":getNextSequenceValue("productid"), "product_name":"Apple iPhone", "category":"mobiles"}) >db.products.insert({ "_id":getNextSequenceValue("productid"), "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()
本文来自博客园,作者:12不懂3,转载请注明原文链接:https://www.cnblogs.com/LZXX/p/15905794.html