MongDB学习笔记(一) 初遇篇

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: MongDB学习笔记(一) 初遇篇

是什么? what

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

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

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

MongoDB中的记录是一个文档,它是由字段和值对组成的数据结构。MongoDB文档类似于JSON对象。字段的值可以包括其他文档,数组和文档数组。

image.png

关于什么是JSON?  参看我写的文章: 傻傻弄不清楚的JSON?

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

image.png

上面我们提到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有个国人维护的中文操作手册:

image.png

介绍的相当详细,也有安装教程,也有免费试用:

image.png

所以对于我这种我选择了面试试用,点进去,我选择的开发场景是开发微服务,你也可以选择在本地安装,这篇手册上的安装教程写的还是蛮详细的,这里我就放个地址,不做详细介绍了。https://docs.mongoing.com/install-mongodb

但是这种在云端的数据库,安装MongDB的shell可能稍微比较麻烦一点,我在windows上安装了好久感觉都没成功,这里可以用MongDB的GUI,下载地址如下:

https://downloads.mongodb.com/compass/mongodb-compass-1.30.1-win32-x64.exe

image.pngimage.png

会填JSON就行

Java 操纵MongDB

现在我们就尝试用起来,我在初遇篇讲的就是一些基本特性,CRUD之类的。 首先连接数据库肯定需要驱动:

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

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

image.pngimage.png

我们新增对象的时候就是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来实现。

@Test
void 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);
}

结果:image.png

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);
}

最后总结一下

image.png

某种程度上我们的程度都是从现实数据采取数据经过处理之后送入数据库,然后根据用户请求再将数据库中的数据取出,但是现实世界的数据结构是形形色色的,关系型数据库也有力不能逮的场景,像是我们在上文讨论过的为为什么引入MongDB,还有一种场景就是描述数据之间的联系,比如组织架构,人际关系图,在数据量比较大的时候,关系数据库就面临着查询速度缓慢的问题,为了描述这种非线性的关系,图数据库应运而生。不同的数据库都是在应对不同的数据描述场景。

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
存储 NoSQL Linux
mongdb安装笔记
mongdb安装笔记
75 1
|
7月前
|
NoSQL Redis
【怒怼大厂面试官】听说你精通Redis?Redis数据同步懂吗
面试官:不用慌尽管说,错了也没关系。。。来说说Redis数据同步。是这样的,Redis有一个叫命令传播的概念,如果像面试官说的这种场景,再使用上面我提到的AOF缓冲区就有点浪费内存空间了。所以Redis会将主服务器的这条Del删除命令
【怒怼大厂面试官】听说你精通Redis?Redis数据同步懂吗
|
7月前
|
存储 SQL 关系型数据库
【怒怼大厂面试官】你先说说知道哪些MySQL的高级特性
面试官:上一期博客问了你MySQL主从复制,现在考考你MySQL高级特性吧。分区的一个主要目的是将数据按照一个较粗的粒度分在不同的区域,这样的话就有很多好处。
107 1
|
7月前
|
关系型数据库 MySQL
Mysql基础第十五天,汇总数据
Mysql基础第十五天,汇总数据
41 0
|
7月前
|
存储 小程序 前端开发
前端知识笔记(四十六)———什么是小程序,什么是数据库
前端知识笔记(四十六)———什么是小程序,什么是数据库
58 0
|
存储 Cloud Native 安全
“数据库内核从入门到精通 ”系列课开讲!
基于 2022 年教育部-阿里云产学合作协同育人教学内容和课程改革项目合作,云原生分布式开源数据库 PolarDB 系列示范课程建设项目陆续和高校展开。阿里云开发者社区、阿里云PolarDB开源社区、武汉大学联合出品「数据库内核从入门到精通」系列课程正式上线,阿里云数据库专家携手高校教师系统化解读数据库理论,开展数据库实践,带学员全面掌握数据库内核开发技能。
“数据库内核从入门到精通 ”系列课开讲!
|
NoSQL MongoDB
开心档-软件开发入门之MongoDB 原子操作
【摘要】 本章将会讲解mongodb不支持事务,所以,在你的项目中应用时,要注意这点。无论什么设计,都不要要求mongodb保证数据的完整性。
|
存储 SQL 缓存
一文带你吃透MySQL数据库!1
一文带你吃透MySQL数据库!
105 0
|
存储 SQL 关系型数据库
为了让你彻底弄懂 MySQL 事务日志,我通宵赶出了这份图解!
在当今社会,充斥着大量的数据。从众多APP上的账户资料到银行信用体系等个人档案,都离不开对大量数据的组织、存储和管理。而这,便是数据库存在的目的和价值。本文将为大家详细讲解 MySQL 事务日志的相关知识。
4478 0
为了让你彻底弄懂 MySQL 事务日志,我通宵赶出了这份图解!

相关实验场景

更多