本周去见了高中同学, 还是蛮开心的。原本打算的是写MySQL数据库事务的实现或者MySQL优化系列的文章,然而还没有想到如何组装这些常识。

索性这周换个方向,写写NOSQL。思考到有些同学对JSON还不是很理解,这里咱们先介绍MongDB的基本概念,再接着讲述为什么要引入MongDB,再解说该如何应用。

是什么? what

MongoDB is a document database designed for ease of application development and scaling 《MongDB官网》

MongDB是一个为高扩展性、高可用性而设计的文档数据库。

留神到MongDB是一个文档数据库,文档数据库与咱们常见的关系型数据库有什么区别呢?咱们首先来看这个文档,也就是document到底是什么含意?

MongoDB中的记录是一个文档,它是由字段和值对组成的数据结构。MongoDB文档相似于JSON对象。字段的值能够包含其余文档,数组和文档数组。

对于什么是JSON? 参看我写的文章: 傻傻弄不分明的JSON?

所以MongDB的记录是一个相似于一个JSON对象的文档,MongDB将文档存储在汇合中,汇合相似于关系数据库中的表。存取关系相似于上面的图:

下面咱们提到MongDB的记录是一个相似于JSON的文档,之所以是相似于,是因为MongDB采取的是BSON,BSON = Binary JSON, 也就是二进制模式的JSON,但同时又裁减了JSON,具备JSON中不具备的数据类型,像日期类型(Date type)、二进制数据类型(BinData type)。

为什么要引入MongDB?

那为什么要引入MongDB呢? 或者说MongDB绝对于关系型数据库有哪些劣势呢?

十年前,当 Dwight 和我开始这个起初成为 MongoDB 的我的项目的时候,咱们相对没有想到它明天的样子。咱们只有一个信念:让开发者更高效。MongoDB 诞生于在宏大简单的业务部署中应用关系型数据库给咱们带来的丧气。咱们着手建造一个咱们本人想用的数据库。这样,每当开发者想写一个利用时,他们能够专一于利用自身,而不必围着数据库转。 MongoDB 的十年,一个创始人的回顾

所以就是在某些畛域,MongDB能够让开发者更高效。

知乎上有一个问题: MongoDB 等 NoSQL 与关系型数据库相比,有什么优缺点及实用场景?上面的有一个MongDB的开发者做了答复,这里我简略摘录一下他的答复:

  • 文档(JSON)模型与面向对象的数据表达方式更类似更天然。与关系型数据库中的表构造不同,文档(JSON)中能够嵌入数组和子文档(JSON),就像程序中的数组和成员变量一样。这是关系型数据库三范式不容许。但理论中咱们常常看到一对多和一对一的的数据。比方,一篇博客文章的Tag列表作为文章的一部分十分直观,而把Tag与文章的从属关系独自放一张表里就不那么天然。SQL语音能够很准确地形式化。然而三大范式强调的数据没有任何冗余,并不是明天程序员们最关怀的问题,他们用着不便不不便才是更重要的问题。
这里咱们就得出MongDB绝对于关系型数据库的第一个劣势,在某些场景下MongDB比关系型数据库不便,留神是在某些场景下。
  • 性能

    三大范式带来的jojn,有的时候为了满足一个查问,不得不join多表,但join多表的代价是随着数据的晋升,查问速度会变得很慢,更简略的拜访模式能够让开发者更容易了解数据库的性能体现,举一个典型的场景就是,我join了十张表,在这样的状况下,我该如何加索引能力取得最优对的查问速度。

  • 灵便

    如果须要加字段,从数据库到应用层可能都须要改一遍,只管有些工具能够把它自动化,但这依然是一个简单的工作。 MongDB没有Schema,就不须要改变数据库,只须要在应用层做必要的改变。(这句话能够这么了解,认真看下面画的MongDB存取数据的图,汇合中当初存取的学生都有三个字段,事实上MongDB容许文档领有不同的字段)

自定义属性也是一个问题,比方LCD显示器和LED显示的产品个性就不一样,数据的这种个性被称为多态,放在关系型数据库中,产品这个表应该怎么设计? 一般来说最简略的计划是将每个可能的属性都变成独自一列,但如果显示器厂商每年推出一个新个性,那么这个表就要常常的改变,扩展性不强。还有一种更加极其的场景是,一个通讯录容许用户随便增加新的联系方式,一种计划是将这种自定义联系方式放在一列,用json存储。

MongDB的灵便还体现在非结构化和半结构化的数据上, MongDB提供全文索引,也反对地理位置查问和索引。例如一位用户想晓得方圆五公里哪里有公共卫生间,这是「天文范畴查问」。而后他搜寻最近的单车。摩拜单车正是应用 MongoDB 实现这样的「间隔排序查问」。强烈建议应用地理位置索引减速查问,因为我能了解这位用户的情绪。

  • 可扩展性

    MongDB原生自带分片,对应的就是关系型数据库的分库分表。

  • 哪些场景下MongDB不适宜
MongDB的开发者周思远举了一个场景,他在一个我的项目中须要地铁列车时刻表,官网提供的是一个满足行业标准的SQL格局的数据,也就是依照三大范式分成了好几张表。而后他花了一早晨把数据库导入到了MongDB中。然而他说如果再来一次,他可能会间接选取关系型数据库,因为如果源数据格式就是SQL数据,没法管制,数据量小;穿插援用关系丰盛,查问模式丰盛,利用又不须要高性能,那么关系型数据页也是一个求实的抉择。

我对这句话的了解是站在建模利用数据的角度不同,在某些场景下,关系型数据库提供的SQL在统计数据、查问、剖析方面依然具备弱小的劣势。

怎么用?

有了,what和why之后,咱们就能够开始用起来了,也就是开始装置应用,比拟侥幸的是MongDB有个国人保护的中文操作手册:

介绍的相当具体,也有装置教程,也有收费试用:

所以对于我这种我抉择了面试试用,点进去,我抉择的开发场景是开发微服务,你也能够抉择在本地装置,这篇手册上的装置教程写的还是蛮具体的,这里我就放个地址,不做具体介绍了。https://docs.mongoing.com/ins...

然而这种在云端的数据库,装置MongDB的shell可能略微比拟麻烦一点,我在windows上装置了良久感觉都没胜利,这里能够用MongDB的GUI,下载地址如下:

https://downloads.mongodb.com...

会填JSON就行

Java 操纵MongDB

当初咱们就尝试用起来,我在初遇篇讲的就是一些根本个性,CRUD之类的。 首先连贯数据库必定须要驱动:

<dependency>    <groupId>org.mongodb</groupId>    <artifactId>mongo-java-driver</artifactId>    <version>3.12.5</version></dependency>

增删改查,跟数据库打交道的根本步骤个别都是获取连贯,而后发送语句,在MongDB的java驱动中,增删改查都和Document、Bson这两个类有关系:

咱们新增对象的时候就是new Document, 像外面丢值。Filter则用来结构条件对象,用于查问:

Filters.ne 是不等于Filters.gt 大于Filters.and(Filters.eq("age",2222)),Filters.eq("name","aaa") 连等于Filters.gte 大于等于Filters.lt 小于Filters.lte 小于等于Filters.in()Filters.nin() not in

Filters 实质上来说就是来帮你传递了操作符,咱们借助于Document也能实现也能实现一样的成果:

 new Document("name","张三") = Filters.eq("name","张三") new Document("age",new Document("$eq",24))  = Filters.eq("name","张三") new Document("age",new Document("$ne",24))  = Filters.ne("name","张三")    

咱们次要借助于MongoCollection来实现对MongDB中的增删查改,增次要和Document有关系。改 删 查能够应用Filters和Document来实现。

@Testvoid contextLoads() throws Exception {    ConnectionString connectionString = new ConnectionString("mongodb+srv://study:a872455@cluster0.exlk2.mongodb.net/myFirstDatabase?retryWrites=true&w=majority");    MongoClientSettings settings = MongoClientSettings.builder()            .applyConnectionString(connectionString)            .build();    MongoClient mongoClient = MongoClients.create(settings);    insertDocumentDemo(mongoClient);}public void insertDocumentDemo(MongoClient mongoClient) throws  Exception {    MongoDatabase database = mongoClient.getDatabase("test");    database.getCollection("study");    MongoCollection<Document> study = database.getCollection("study");    // study 这张表的存的有 number name id, 如果是关系型数据库,咱们要增加属性,须要先在表中加字段,    // 当初 在MongDB中咱们间接增加    Map<String,Object> map = new HashMap<>();    map.put("number","bbb");    map.put("name","aaa");    map.put("id","1111");    map.put("age",2222);    Document document = new Document(map);    study.insertOne(document);}

后果:

public void deleteDocument(MongoClient mongoClient){        MongoDatabase database = mongoClient.getDatabase("test");        database.getCollection("study");        MongoCollection<Document> study = database.getCollection("study");        // eq 是等于运算符,Filters.eq("age",2222) 示意查出定位的是age = 2222的对象        study.deleteOne(Filters.eq("age",2222));}
  • public void updateDocument(MongoClient mongoClient){        MongoDatabase database = mongoClient.getDatabase("test");        database.getCollection("study");        MongoCollection<Document> study = database.getCollection("study");        study.updateOne(Filters.eq("age",2222),new Document("$set",new Document("name","22222"))); }
public void selectDocument(MongoClient mongoClient){        MongoDatabase dataBase = mongoClient.getDatabase("test");        MongoCollection<Document> studyTable = dataBase.getCollection("study");        // age 能够是一个数组, 所有的值都得是2222        Bson condition = Filters.all("age", 2222);        FindIterable<Document> documentList = studyTable.find(condition);}

最初总结一下

某种程度上咱们的水平都是从事实数据采取数据通过解决之后送入数据库,而后依据用户申请再将数据库中的数据取出,然而事实世界的数据结构是不拘一格的,关系型数据库也无力不能逮的场景,像是咱们在上文探讨过的为为什么引入MongDB,还有一种场景就是形容数据之间的分割,比方组织架构,人际关系图,在数据量比拟大的时候,关系数据库就面临着查问速度迟缓的问题,为了形容这种非线性的关系,图数据库应运而生。不同的数据库都是在应答不同的数据形容场景。

参考资料

  • MongoDB中文手册|官网文档中文版 https://docs.mongoing.com/
  • MongoDB 等 NoSQL 与关系型数据库相比,有什么优缺点及实用场景? https://www.zhihu.com/questio...
  • BSON 官网 https://bsonspec.org/#/
  • java操作mongodb——查问数据 https://www.cnblogs.com/simpl...