MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。java
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。git
MongoDB最大的特色就是无Schema限制,灵活度很高。数据格式是BSON,BSON是一种相似JSON的二进制形式的存储格式,简称Binary JSON 它和JSON同样,支持内嵌的文档对象和数组对象。github
Mysql | MongoDB |
---|---|
Database(数据库) | Database(数据库) |
Table(表) | Collection(集合) |
Row(行) | Document(文档) |
Column(列) | Field(字段) |
MongoDB 将数据存储为一个文档,BSON格式。由key 和 value组成。spring
{ "_id" : ObjectId("5e141148473cce6a9ef349c7"), "title" : "批量更新", "url" : "http://cxytiandi.com/blog/detail/8", "author" : "yinjihuan", "tags" : [ "java", "mongodb", "spring" ], "visit_count" : NumberLong(10), "add_time" : ISODate("2019-02-11T07:10:32.936+0000") }
MongoDB自带副本集和分片,天生就适用于大数量场景,无需开发人员经过中间件去分库分表,很是方便。sql
不少时候,咱们须要存储一些操做日志,可能只须要存储好比最近一个月的,通常的作法是按期去清理,在MongoDB中有固定集合的概念,咱们在建立集合的时候能够指定大小,当数据量超过大小的时候会自动移除掉老数据。mongodb
爬下来的数据有网页,也有Json格式的数据,通常都会按照表的格式去存储,若是咱们用了MongoDB就能够将抓下来的Json数据直接存入集合中,无格式限制。数据库
在社交场景中使用 MongoDB 存储存储用户地址位置信息,经过地理位置索引实现附近的人,附近的地点等。后端
不一样的商品有不一样的属性,常见的作法是抽出公共的属性表,而后和SPU进行关联,若是用MongoDB的话那么SPU中直接就能够内嵌属性。数组
MongoDB的功能点不少,可是大部分场景下咱们只用了最简单的CRUD操做。下面隆重的介绍下MongoDB的功能点,就像你去相亲同样,很差好介绍本身的优势又怎能让你对面的菇凉心动呢?安全
CRUD也就是增删改查,这是数据库最基本的功能,查询还支持全文检索,GEO地理位置查询等。
单个文档插入到集合中
多个文档插入到集合中
单个或者多个文件插入到集合中
查询数据
更新单条
更新多条
删除单条文档
删除多条文档
聚合操做用于数据统计方面,好比Mysql中会有count,sum,group by等功能,在MongoDB中相对应的就是Aggregation聚合操做。
聚合下面有两种方式来实现咱们须要对数据进行统计的需求,一个是aggregate,一个是MapReduce。
下图展现了aggregate的执行原理:
聚合内置了不少函数,使用好了这些函数咱们就能够统计出咱们想要的数据。
$project:修改输入文档的结构。能够用来重命名、增长或删除域,也能够用于建立计算结果以及嵌套文档。
$match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操做。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
$geoNear:输出接近某一地理位置的有序文档。
$unwind:将文档中的某一个数组类型字段拆分红多条,每条包含数组中的一个值。
下图展现了MapReduce的执行原理:
总共4条数据,query指定了查询条件,只处理status=A的数据。
map阶段对数据进行分组聚合,也就是造成了第三部分的效果,根据cust_id去重统计。
reduce中的key也就是cust_id, values也就是汇总的amount集合。而后进行sum操做,最终的结果经过out输出到一个集合中。
MongoDB最开始是不支持事务的,在MongoDB中,对单个文档的操做是原子性操做。因此再设计的时候可使用嵌入的文档和数组来描述数据之间的关系,这样就不用跨多个文档和集合进行操做,也就经过了单文档原子性消除了许多实际用例对多文档事务的须要。
任何事物都是有限制的,某些场景仍是不能彻底经过内嵌的方式来描述数据的关系,仍是会存在多个集合,对于使用MongoDB的用户来讲,若是能支持事务就很方便了。
不负众望,MongoDB 4.0 版本的发布,为咱们带来了原生的事务操做。
索引不用我多说了,做用你们都知道。单索引,组合索引,全文索引,Hash索引等。
db.collection.createIndex({user_id: 1, add_time: 1}, {background: true})
建立索引特别要注意的是将background设置为true,在建索引的过程会阻塞其它数据库操做,background可指定之后台方式建立索引,默认为false。这但是血的教训呀,切记切记。
MongoDB中的安全须要重视,目前启动不知道有没有强制的限制,之前启动的时候能够不指定认证的方式,也就是不须要密码便可访问,而后不少人都直接用的默认端口,暴露在公网上,给不法分子有隙可乘,出现了数据被删,须要用比特币来找回数据的案例比比皆是。
仍是要开启安全认证,内置了不少角色,不一样的角色可操做的内容不同,控制的比较细。
副本集是一组相同数据集的MongoDB实例,同时在多个节点存储数据,提升了可用性。主节点负责写入,从节点负责读取,提升总体性能。
副本集由下面的组件构成:
Primary:主节点接收全部的写操做。
Secondaries:从节点会从主节点进行数据的复制,维护跟主节点相同的数据。用于查询操做。
Arbiter:仲裁节点自己不存储数据,只参与选举。
分片是MongoDB绝对的亮点,将数据水平拆分到多个节点。MongoDB的分片是全自动的,咱们只须要配置好分片的规则,它就能自动维护数据并存储到不一样节点。MongoDB使用分片来支持大数据量的存储和高吞吐量的操做。
下图是Mongodb的分片集群架构图:
MongoDB分片集群由如下组件够成:
Shard:每一个shard的数据都是独立完整的一份。而且能够做为副本集部署。
mongos:mongos是查询路由器,在客户端和服务端中间的一层,请求会直接到mongos,由mongos路由到具体的Shard。
Config Servers:存储集群全部节点、分片数据路由信息。
GridFS是MongoDB的一个子模块,主要用于在MongoDB中存储文件,至关于MongoDB内置的一个分布式文件系统。
本质上仍是讲文件的数据分块存储在集合中,默认的文件集合分为fs.files和fs.chunks。
fs.files是存储文件的基本信息,好比文件名,大小,上传时间,md5等。fs.chunks是存储文件真正数据的地方,一个文件会被分割成多个chunk块进行存储,通常为256k/个。
若是你的项目中用到了MongoDB,那么你可使用GridFS来构建一个文件系统,这样就不用去购买第三方的存储服务了。
GridFS的好处是你不用单独去搭建一个文件系统,直接使用Mongodb自带的便可,备份,分片都依赖MongoDB,维护起来也方便。
下图是我本身总结的一些知识点,做为一个后端开发来讲,能掌握下面的内容就已经不错了,毕竟咱们又不是要去抢DBA的饭碗,若是你们业余时间要学习的话能够按照下面的点进行学习,几年前我录制了一套视频,在个人网站上,大部份内容都覆盖到了。
加入MongoDB的依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
配置MongoDB的信息:
spring.data.mongodb.database=test spring.data.mongodb.host=localhost spring.data.mongodb.port=27017 // 用户名,密码省略.......
直接注入MongoTemplate就能够操做MongoDB:
@Autowired private MongoTemplate mongoTemplate;
建立一个实体类,对应MongoDB的集合
@Data @Document(collection = "article_info") public class Article { @Id @GeneratedValue private Long id; @Field("title") private String title; @Field("url") private String url; @Field("author") private String author; @Field("tags") private List<String> tags; @Field("visit_count") private Long visitCount; @Field("add_time") private Date addTime; }
最终存储到数据中的格式以下:
{ "_id" : ObjectId("5e141148473cce6a9ef349c7"), "title" : "批量更新", "url" : "http://cxytiandi.com/blog/detail/8", "author" : "yinjihuan", "tags" : [ "java", "mongodb", "spring" ], "visit_count" : NumberLong(10), "add_time" : ISODate("2019-02-11T07:10:32.936+0000") }
Article article = new Article(); article.setTitle("MongoTemplate 的基本使用 "); article.setAuthor("yinjihuan"); article.setUrl("http://cxytiandi.com/blog/detail/1"); article.setTags(Arrays.asList("java", "mongodb", "spring")); article.setVisitCount(0L); article.setAddTime(new Date()); mongoTemplate.save(article);
数据库语法
db.article_info.save({ "title": "批量更新", "url": "http://cxytiandi.com/blog/detail/8", "author": "yinjihuan", "tags": [ "java", "mongodb", "spring" ], "visit_count": NumberLong(10), "add_time": ISODate("2019-02-11T07:10:32.936+0000") })
Query query = Query.query(Criteria.where("author").is("yinjihuan")); Update update = Update.update("title", "MongoTemplate") .set("visitCount", 10); mongoTemplate.updateMulti(query, update, Article.class);
数据库语法
db.article_info.updateMany( {"author":"yinjihuan"}, {"$set": { "title":"MongoTemplate", "visit_count": NumberLong(10) } } )
Query query = Query.query(Criteria.where("author").is("yinjihuan")); mongoTemplate.remove(query, Article.class);
数据库语法
db.article_info.remove({"author":"yinjihuan"})
Query query = Query.query(Criteria.where("author").is("yinjihuan")); List<Article> articles = mongoTemplate.find(query, Article.class);
数据库语法
db.article_info.find({"author":"yinjihuan"})
File file = new File("/Users/yinjihuan/Downloads/logo.png"); InputStream content = new FileInputStream(file); // 存储文件的额外信息,好比用户ID,后面要查询某个用户的全部文件时就能够直接查询 DBObject metadata = new BasicDBObject("userId", "1001"); ObjectId fileId = gridFsTemplate.store(content, file.getName(), "image/png", metadata);
https://github.com/yinjihuan/spring-cloud/tree/master/Spring-Cloud-Book-Code-2/ch-17/mongodb
下载地址:
https://studio3t.com/download/
最后推荐一个我本身写的小框架:Spring Boot中加强Mongodb的配置,多数据源,链接池
https://github.com/yinjihuan/spring-boot-starter-mongodb-pool
感兴趣的能够关注下个人微信公众号 猿天地,更多技术文章第一时间阅读。个人GitHub也有一些开源的代码 https://github.com/yinjihuan