MongoDB是一个基于分布式文件存储的开源数据库系统,由C++语言编写。它旨在为WEB应用提供可扩展的高性能数据存储解决方案。以下是对MongoDB的详细介绍

简介

基本概述

  • 类型:MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
  • 数据存储:MongoDB使用BSON(Binary JSON)格式存储数据,这种格式支持存储复杂的数据类型,类似于JSON对象,但具有更高的存储效率和性能。
  • 数据模型:MongoDB采用文档导向的数据模型,文档是一个键值对的集合,类似于关系型数据库中的行,但更为灵活。文档可以包含嵌入式文档、数组和其他复杂类型。

主要特点

  1. 高性能:MongoDB使用内存映射文件和预分配空间等技术优化数据读写性能,支持快速的插入、更新和查询操作。
  2. 可扩展性:MongoDB支持水平扩展和自动分片,可以方便地增加服务器和处理大规模数据。
  3. 模式自由:MongoDB不需要事先定义表格结构,可以存储各种类型的数据,支持嵌入式文档和引用两种数据关联方式。
  4. 强大的查询语言:MongoDB提供丰富的查询操作符和聚合管道功能,支持复杂的查询和分析需求。
  5. 高可用性:MongoDB通过复制集(Replica Set)提供数据的冗余和故障恢复能力,主从复制可以提高系统的可用性和容错性。

应用场景

  • 网站实时数据处理:MongoDB非常适合实时的插入、更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
  • 缓存:由于性能很高,MongoDB适合作为信息基础设施的缓存层,在系统重启之后,由它搭建的持久化缓存层可以避免下层的数据源过载。
  • 高伸缩性的场景:MongoDB非常适合由数十或数百台服务器组成的数据库,其路线图中已经包含对MapReduce引擎的内置支持。

概念对比

SQL术语/概念 MongoDB术语/概念 解释/说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins 表连接,MongoDB不支持
primary key primary key 主键,MongoDB自动将_id字段设置为主键

优势对比

MongoDB与MySQL作为两种不同类型的数据库系统,各自具有独特的优势和适用场景。MongoDB作为一种非关系型数据库(NoSQL),与关系型数据库MySQL相比,在以下几个方面展现出明显的优势:

1. 数据模型灵活性

  • MongoDB:使用文档型存储模型,类似于JSON格式,每个文档可以有不同的字段,支持嵌套结构和动态模式。这种灵活性使得MongoDB非常适合处理半结构化和非结构化数据,能够轻松应对数据结构的变化。
  • MySQL:遵循关系模型,数据以表格的形式存储,有固定的列和行结构。虽然通过外键可以实现数据间的关联,但数据结构的变更相对复杂。

2. 高性能和扩展性

  • MongoDB:支持水平扩展,内置分片机制,可以轻松地通过增加服务器来扩展存储和处理能力,实现近乎线性的性能提升。同时,MongoDB的内存映射文件技术和高效的查询语言使得数据读写速度快,特别适合处理海量数据和高并发场景。
  • MySQL:虽然也支持一定程度的扩展,但在处理海量数据时,若未进行合理的索引优化或分区分片,可能会出现性能下降。

3. 查询能力

  • MongoDB:提供了丰富的查询语言,包括文本搜索、地理位置搜索等功能,可以灵活地满足各种查询需求。其聚合框架还提供了强大的数据汇总和分析功能。
  • MySQL:使用标准的SQL语言,提供了丰富的查询功能和高级特性,如复杂的JOIN操作、子查询等。但在处理非结构化或半结构化数据时,可能不如MongoDB灵活。

4. 高可用性和可靠性

  • MongoDB:具有内置的复制和故障转移功能,可以保证数据的高可用性和可靠性。同时,MongoDB还提供了透明数据加密、自动备份、数据恢复等功能,进一步增强了其优势。
  • MySQL:同样具有高可靠性和稳定性,能够在处理高负载的情况下保持高性能。但相比MongoDB,其高可用性和数据保护机制可能需要额外的配置和管理。

5. 工具和生态系统

  • MongoDB:拥有丰富的工具和驱动程序,支持各种编程语言和开发环境,可以方便地集成到现有的应用程序中。同时,MongoDB还提供了专业的数据管理服务(如MongoDB Atlas)和数据传输服务(如DTS),支持管理多种数据库和数据源之间的数据交互。
  • MySQL:拥有庞大的社区支持和广泛的工具生态系统,包括图形界面工具、备份和恢复工具、监控工具等。这些工具和资源为MySQL的广泛应用提供了有力支持。

总结

MongoDB相较于MySQL的优势主要体现在数据模型灵活性、高性能和扩展性、查询能力、高可用性和可靠性以及工具和生态系统等方面。然而,选择哪种数据库系统应根据具体的应用场景、数据特性和业务需求来决定。如果数据结构复杂多变、需要高并发读写、对扩展性要求高或对半结构化数据处理有需求,MongoDB可能更为合适;而如果业务场景高度依赖ACID事务、数据结构固定、需要进行复杂的SQL查询和数据分析或对存储空间有严格要求,MySQL可能是更好的选择。

MongoDB语法

库操作

  • 查看所有数据库

    1
    show dbs
  • 创建数据库
    在 MongoDB 中,创建数据库很简单,只需要使用 use 命令,如果数据库不存在,MongoDB 会在需要时自动创建它。

    1
    use myDatabase
  • 删除数据库

    1
    db.dropDatabase()

集合操作

  • 查看当前数据库中的集合

    1
    show collections
  • 创建集合
    在 MongoDB 中,创建集合也是隐式的,当你第一次插入文档时,如果集合不存在,MongoDB 会自动创建它。

    1
    db.createCollection("myCollection")
  • 删除集合

    1
    db.myCollection.drop()

文档操作

  • 插入文档

    1
    db.myCollection.insert({name: "John", age: 30})

    或者插入多个文档:

    1
    db.myCollection.insert([{name: "Jane", age: 25}, {name: "Doe", age: 22}])
  • 查询文档

    查询模板

    1
    db.mycollection.find([query],[fields])
    • query:可选,使用查询操作符指定查询条件,可理解为sql中where后面的内容
    • fields:可选,使用投影操作指定返回的键,可理解为sql中select后的字段
    1
    2
    db.myCollection.find({})  # 查询所有文档  
    db.myCollection.find({name: "John"}) # 查询特定条件的文档
  • 更新文档

    更新模板

    1
    2
    3
    4
    5
    6
    7
    8
    9
    db.myCollection.update(
    <query>,
    <update>,
    [
    upsert: <boolean>,
    multi: <bollean>,
    writeConcern: <document>
    ]
    )
    • query:update的查询条件,类似sql update查询内where后面的
    • update:update的对象和一些更新的操作符,可理解为sql中update后面set的内容
    • upsert:可选,这个参数的意思是,如果不存在update的记录,是否以一个新的对象插入,默认是false
    • multi:可选,默认是false,只更新找到的第一条记录,如果这个条件是true,就把按条件查出来的多条记录更新
    • writeConcern:可选,抛出异常的级别
    1
    2
    3
    4
    db.myCollection.update(  
    { name: "John" },
    { $set: { age: 31 } }
    )

    或者更新多个文档:

    1
    2
    3
    4
    db.myCollection.update(  
    { },
    { $set: { newField: "value" } }
    )
  • 删除文档

    删除模板

    1
    2
    3
    4
    5
    6
    7
    db.mycollection.remove(
    <query>,
    {
    justOne: <boolean>,
    writeConcern: <document>
    }
    )
    • query:可选,删除文档的条件
    • justOne:可选,如果设为true或1,则只删除一个文档,如果不设置该参数,则使用默认值false,则删除所有匹配的文档
    • writeConcern:可选,抛出异常的级别
    1
    2
    db.myCollection.remove({name: "John"})  
    db.myCollection.remove({age: {$lt: 25}})

索引

  • 创建索引

    1
    db.myCollection.createIndex({name: 1})
  • 查看索引

    1
    db.myCollection.getIndexes()
  • 删除索引

    1
    db.myCollection.dropIndex({name: 1})

SpringDataMongoDB

1. 添加依赖

首先,需要在项目的构建文件(如Maven的pom.xml或Gradle的build.gradle)中添加Spring Data MongoDB的依赖项。以Maven为例,可以添加如下依赖:

1
2
3
4
<dependency>  
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

这个依赖包含了Spring Data MongoDB的核心功能,以及MongoDB Java驱动的依赖。

2. 配置MongoDB

接下来,在Spring Boot的配置文件(如application.propertiesapplication.yml)中配置MongoDB的连接参数。以下是一个application.yml配置示例:

1
2
3
4
5
6
7
8
9
10
11
spring:  
data:
mongodb:
uri: mongodb://username:password@localhost:27017/mydatabase
# 或者分开配置
# host: localhost
# port: 27017
# database: mydatabase
# username: username
# password: password
# authenticationDatabase: admin # 如果需要认证的话

这里配置了MongoDB的URI,或者分开配置了主机名、端口号、数据库名称、用户名和密码等信息。

3. 创建实体类

使用MongoDB的注解来定义实体类,并将其映射到MongoDB的集合(collection)。常用的注解包括@Document@Field@Id等。以下是一个简单的实体类示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import org.springframework.data.annotation.Id;  
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "users")
public class User {
@Id
private String id;

@Field("name")
private String name;

@Field("age")
private Integer age;

// 省略getter和setter方法
}

4. 创建Repository接口

创建一个继承自MongoRepository(或其他Spring Data MongoDB提供的Repository接口)的接口,用于访问和操作实体类对应的MongoDB数据。Spring Data MongoDB会为这个接口提供一套基本的CRUD方法。

1
2
3
4
5
import org.springframework.data.mongodb.repository.MongoRepository;  

public interface UserRepository extends MongoRepository<User, String> {
// 可根据需要添加自定义查询方法
}

5. 使用Repository进行操作

在需要使用MongoDB操作的地方,通过注入Repository接口对象来调用相应的方法。例如,在Service层中使用Repository来保存和查询数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Service;

@Service
public class UserService {

@Autowired
private UserRepository userRepository;

public User saveUser(User user) {
return userRepository.save(user);
}

public User getUserById(String id) {
return userRepository.findById(id).orElse(null);
}

// 省略其他方法
}

6. 使用MongoTemplate

除了使用Repository接口外,Spring Data MongoDB还提供了MongoTemplate类,它提供了更灵活的数据访问能力。可以在需要的时候注入MongoTemplate来实现更复杂的查询和操作。

增加(Insert)

使用 MongoTemplateinsert 方法可以将对象插入到 MongoDB 的集合中。如果对象包含了一个 _id 字段,并且该字段的值已经存在于集合中,那么该操作会抛出一个异常。如果不希望自动生成 _id,可以在实体类中设置 @Id 注解的 autoGenerated 属性为 false(注意:通常我们让 MongoDB 自动管理 _id)。

1
2
3
public void insertUser(User user) {  
mongoTemplate.insert(user, "users");
}

这里 "users" 是 MongoDB 中的集合名称。

删除(Delete)

删除操作可以通过 remove 方法或 findAllAndRemove 方法来完成。remove 方法可以根据查询条件删除一个或多个文档。

1
2
3
4
5
6
7
8
9
10
11
// 根据ID删除  
public void deleteUserById(String id) {
Query query = new Query();
query.addCriteria(Criteria.where("id").is(id));
mongoTemplate.remove(query, User.class, "users");
}

// 删除所有
public void deleteAllUsers() {
mongoTemplate.removeAll(User.class, "users");
}

更新(Update)

更新操作通常使用 updateFirstupdateMulti 方法。updateFirst 会更新查询到的第一个文档,而 updateMulti 会更新所有匹配的文档。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 更新第一个匹配的文档  
public void updateUserFirstName(String id, String firstName) {
Query query = new Query();
query.addCriteria(Criteria.where("id").is(id));
Update update = new Update();
update.set("firstName", firstName);
mongoTemplate.updateFirst(query, update, User.class, "users");
}

// 更新所有匹配的文档
public void updateAllUsersAge(int newAge) {
Query query = new Query();
// 这里可以添加更具体的查询条件
Update update = new Update();
update.set("age", newAge);
mongoTemplate.updateMulti(query, update, User.class, "users");
}

查询(Query)

查询操作非常灵活,MongoTemplate 提供了多种查询方法,如 findOnefindAllfind 等,它们可以接受 Query 对象作为参数来定义查询条件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 根据ID查询单个文档  
public User findUserById(String id) {
return mongoTemplate.findById(id, User.class, "users");
}

// 查询所有文档
public List<User> findAllUsers() {
return mongoTemplate.findAll(User.class, "users");
}

// 使用Query对象进行复杂查询
public List<User> findUsersByAge(int age) {
Query query = new Query();
query.addCriteria(Criteria.where("age").is(age));
return mongoTemplate.find(query, User.class, "users");
}

在使用 MongoTemplate 进行查询时,你可以通过 QueryCriteria 类来构建复杂的查询条件,包括分页、排序等高级功能。

总的来说,MongoTemplate 提供了丰富的API来执行 MongoDB 的增删改查操作,使得开发者能够以更灵活和强大的方式来操作 MongoDB 数据库。