双刃剑MongoDB的学习和避坑
MongoDB 是一把双刃剑,它对数据结构的要求并不高。数据通过key-value的形式存储,而value的值可以是字符串,也可以是文档。所以我们在使用的过程中非常方便。正是这种方便给我们埋下了一颗颗地雷。当内嵌的文档太深,或者内嵌文档有相同的属性名。你会被炸得很惨。本章节通过 MongoDB简介,Shell编程,SpringBoot整合MongoDB,工作中注意事项,四个方面介绍MongoDB的使用。让你轻松入门,轻松避坑。还在等什么,赶快来学习吧!
技术:MongoDB,SpringBoot,SpringDataMongoDB
说明:本章重点介绍MongoDB的使用,对非关系型数据库的介绍会比较简单。完整代码和相关sql请移步github,ths!
源码:https://github.com/ITDragonBlog/daydayup/tree/master/MongoDB
MongoDB 是非关系型数据库中,最接近关系型数据库的,文档型数据库。它支持的查询功能非常强大。
MongoDB 是为快速开发互联网Web应用而设计的数据库系统。他的数据模型是面向文档的,这种文档是一种类似于JSON的结构,准确来说是一种支持二进制的BSON(Binary JSON)结构。
非关系性数据库 也被称为 NoSQL(Not only sql),主要有四大类:键值存储数据库、列存储数据库、文档型数据库、图形数据库。之前介绍的Redis属于键值存储数据库。
关系与非关系型数据库关系型数据库的优点:
1 支持事务处理,事务特性:原子性、一致性、隔离性、持久性。
2 数据结构清晰,便于理解,可读性高。
3 使用方便,有标准的sql语法。
关系型数据库的缺点:
1 读写性能相对较差,为保证事务的一致性,需要一定的开销。在高并发下表现的尤为突出。
2 表结构固定,不易于表后期的扩展,所以前期对表的设计要求较高。
非关系型数据库的优点:
1 读写性能高,没有保障数据的一致性。
2 表结构灵活,表结构并不是固定的,通过key-value存储数据,value又可以存储其他格式的数据。
两者的优缺点其实是向反的,一件事物不会凭空出现,都是在原有的基础上做了补充和优化,两者的侧重点各有不同。就像MySQL保障了数据的一致性,却影响了读写的性能。MongoDB放弃数据的强一致性,保障了读写的效率。在合适的场景使用合适的数据库,是需要我们考虑的。
1 对于需要高度事务特性的系统,比如和钱有关的,银行系统,金融系统。我们要考虑使用关系型数据库,确保数据的一致性和持久性。
2 对于那些数据并不是很重要,访问量又很大的系统,比如电商平台的商品信息。我们可以使用非关系型数据库来做缓存,充分提高了系统查询的性能。
这里对银行和金融我想抱怨两句:
第一:投资理财千万不要选择小平台金融公司,收益再高都是虚假的,多半都是圈钱跑路的,钱的教训。
第二:某些银行APP显示的金额不是实时的。16年某生银行卡转入40万,但在我的总资产界面并没有转入的金额,吓得我一身冷汗。颤抖着双手给客服打了几个电话才知道,某生银行APP的总资产界面数据是统计前一天的。直到第二天,金额才显示正确。从此我再也没有用某生的银行卡。某商的信用卡也是一样,还了钱金额并没有减下来。不知道现在有没有改。
有在银行工作的朋友,能否告诉我这样设计的原因是啥?难道用户体验不重要?还是要体现客服的价值?反正,这锅我们程序员不背。
Mongodb Shell 编程 查询数据Mongodb的查询功能十分强大,有find() 和 findOne()。支持的查询条件有:$lt、$lte、$gt、$gte、$ne、$or、$in、$nin、$not、$exists、$and、正则表达式等。
db.collection.find() 根据查询条件返回所有文档
db.collection.findOne() 根据查询条件返回第一个文档
查询建议:
1 查询所有数据,建议使用分页查询。
2 查询key建议用引号,对象的属性可以省略引号,内嵌的对象属性不能省略。比如下面的name可以省略,但address.province则不能。
3 尽量少用$or, $in 查询,效率很低。
// 查询所有(不推荐,一般使用分页查询) db.itdragonuser.find(); {"_id":ObjectId("5a9bbefa2f3fdfdf540a1be7"),"name":"ITDragon","age":25,"address":{"province":"广东省","city":"深圳"},"ability":["JAVA"]} // 等于查询 db.itdragonuser.find({"name":"ITDragon"}); // 模糊查询 db.itdragonuser.find({"name":/ITDragon/}); // 或者查询 db.itdragonuser.find({$or:[{"address.province":"湖北"},{"address.province":"湖南"}]}); // 包含查询(包含了JAVA或者HTML) db.itdragonuser.find({"ability":{$in:["JAVA","HTML"]}}); // 不包含查询(JAVA和HTML都不包含) db.itdragonuser.find({"ability":{$nin:["JAVA","HTML"]}}); // 范围查询$gt , $lt , $gte , $lte , $ne db.itdragonuser.find({"age":{$gt:25}}); // 正则表达式查询(查询以WeiXin结尾的数据) db.itdragonuser.find({"name":/WeiXin$/}); // 按照条件统计数据 db.itdragonuser.count({"name":/ITDragon/}); // 过滤重复内容(打印不重复的name值) db.itdragonuser.distinct("name"); // sort:排序(1表示升序 -1表示降序),skip:跳过指定数量,limit:每页查询数量 db.itdragonuser.find().sort({"age":1}).skip(2).limit(3); // 字段投影,(0表示不显示,1表示显示) db.itdragonuser.find({},{_id:0,name:1,address:1,aliblity:1});