目录

前言

一、什么是 MongoDB?

核心特性:

二、核心概念(与关系型数据库对比)

三、数据模型:文档与 BSON

1. 文档结构

2. 支持的数据类型

3. 集合(Collection)

四、基本操作(CRUD)

1. 创建(Create)

2. 读取(Read)

3. 更新(Update)

4. 删除(Delete)

五、索引:提升查询性能

1. 索引类型

2. 索引操作

3. 注意事项

六、分布式特性:高可用与扩展

1. 副本集(Replica Set):高可用保障

2. 分片(Sharding):水平扩展

七、事务支持

八、适用场景与不适用场景

适用场景:

不适用场景:

总结

前言

MongoDB 是目前最流行的开源 NoSQL 数据库之一,以其灵活的文档模型、强大的可扩展性和高性能被广泛应用于各类场景。以下从核心概念、数据模型、操作方式到高级特性进行详细讲解。

一、什么是 MongoDB?

MongoDB 是一个文档型 NoSQL 数据库(非关系型数据库),由 MongoDB Inc. 开发,2009 年首次发布。它摒弃了关系型数据库的表结构和固定 schema,采用灵活的文档模型存储数据,更适合处理非结构化或半结构化数据。

核心特性:
  • 文档导向:数据以 “文档” 为基本单位,类似 JSON,结构灵活。
  • 无固定 Schema:同一集合(类似表)中的文档可以有不同字段,无需预先定义结构。
  • 分布式友好:原生支持副本集(高可用)和分片(水平扩展),轻松应对大数据量和高并发。
  • 丰富的查询能力:支持复杂查询、聚合、索引等,功能接近关系型数据库。
  • 多语言支持:提供 Java、Python、Node.js 等主流语言的驱动,易于集成开发。

二、核心概念(与关系型数据库对比)

MongoDB 的术语与关系型数据库(如 MySQL)有对应关系,但本质不同,理解这些对应关系能快速入门:

关系型数据库 MongoDB 说明
数据库(Database) 数据库(Database) 逻辑上的独立数据集合,一个 MongoDB 实例可包含多个数据库。
表(Table) 集合(Collection) 存储文档的容器,类似表,但集合内文档结构可不同。
行(Row) 文档(Document) 一条数据记录,以 BSON 格式(类似 JSON)存储。
列(Column) 字段(Field) 文档中的键值对,对应 JSON 中的 “键”。
主键(Primary Key) _id 字段 每个文档默认包含的唯一标识,自动生成(ObjectId 类型),也可手动指定。
索引(Index) 索引(Index) 用于加速查询,支持单字段、复合、地理空间等多种类型。

三、数据模型:文档与 BSON

MongoDB 的核心是文档(Document),它是数据的最小单位,采用 BSON(Binary JSON)格式存储。BSON 是 JSON 的二进制扩展,支持更多数据类型(如日期、二进制数据等),且更易被机器解析。

1. 文档结构

文档是键值对的集合,类似 JSON 对象,示例:

{
  "_id": ObjectId("650a8b3d1f2d7e3a4c8d9e0f"),  // 自动生成的唯一标识
  "name": "张三",
  "age": 28,
  "isStudent": false,
  "hobbies": ["篮球", "音乐"],  // 数组类型
  "address": {                  // 嵌入文档(嵌套结构)
    "city": "北京",
    "district": "海淀区"
  },
  "createTime": ISODate("2023-09-21T08:30:00Z")  // 日期类型
}

2. 支持的数据类型

BSON 支持比 JSON 更丰富的类型,常见包括:

  • 基本类型:字符串(String)、整数(Int32/Int64)、布尔(Boolean)、null。
  • 复杂类型:数组(Array)、嵌入文档(Embedded Document)。
  • 特殊类型:ObjectId(文档唯一标识)、日期(Date)、二进制数据(Binary)、正则表达式(Regex)等。

3. 集合(Collection)

集合是文档的容器,特点:

  • 无固定 schema:同一集合中的文档可以有不同字段(例如,一个文档有 age 字段,另一个可以没有)。
  • 动态创建:无需预先定义,插入第一个文档时自动创建集合。

四、基本操作(CRUD)

MongoDB 提供丰富的操作接口,以下是核心的增删改查(CRUD)操作示例(基于 MongoDB Shell,类似命令行工具)。

1. 创建(Create)

使用 insertOne() 插入单条文档,insertMany() 插入多条文档:

// 插入单条
db.users.insertOne({
  name: "李四",
  age: 30,
  address: { city: "上海" }
});

// 插入多条
db.users.insertMany([
  { name: "王五", age: 25, hobbies: ["读书"] },
  { name: "赵六", age: 35, isStudent: true }
]);

2. 读取(Read)

使用 find() 查询文档,支持条件过滤、投影(指定返回字段)、排序、分页等。

  • // 查询所有文档(返回游标,需遍历)
    db.users.find();
    
    // 条件查询:年龄大于 28 的用户
    db.users.find({ age: { $gt: 28 } });  // $gt 表示“大于”
    
  • 投影(只返回指定字段):

    // 只返回 name 和 age 字段(_id 默认返回,需显式排除)
    db.users.find({ age: { $gt: 28 } }, { name: 1, age: 1, _id: 0 });
    
  • 排序与分页:

    // 按 age 降序排序,跳过前 1 条,返回 2 条
    db.users.find()
      .sort({ age: -1 })  // -1 降序,1 升序
      .skip(1)
      .limit(2);
    

3. 更新(Update)

使用 updateOne() 更新单条文档,updateMany() 更新多条,需配合更新操作符(如 $set$inc 等)。

  • 示例:

    // 更新 name 为“李四”的用户,年龄增加 1($inc 自增)
    db.users.updateOne(
      { name: "李四" },  // 查询条件
      { $inc: { age: 1 } }  // 更新操作
    );
    
    // 给所有年龄小于 30 的用户添加“学生”标签
    db.users.updateMany(
      { age: { $lt: 30 } },
      { $set: { isStudent: true } }
    );
    
     

    常用更新操作符:

    • $set:修改字段值
    • $inc:数值自增 / 减
    • $push:向数组添加元素
    • $unset:删除字段

4. 删除(Delete)

使用 deleteOne() 删除单条,deleteMany() 删除多条:

// 删除 name 为“赵六”的文档
db.users.deleteOne({ name: "赵六" });

// 删除所有年龄大于 40 的文档
db.users.deleteMany({ age: { $gt: 40 } });

五、索引:提升查询性能

索引是加速查询的关键,MongoDB 支持多种索引类型,核心作用是减少查询时扫描的文档数量。

1. 索引类型

  • 单字段索引:对单个字段创建索引,最常用。

    // 为 age 字段创建升序索引
    db.users.createIndex({ age: 1 });
    
  • 复合索引:对多个字段联合创建索引,遵循 “最左前缀原则”(查询条件包含左侧字段时才生效)。

    // 对 name(升序)和 age(降序)创建复合索引
    db.users.createIndex({ name: 1, age: -1 });
    
  • 地理空间索引:用于地理位置查询(如 “附近的商店”)。

    // 为 location 字段(存储经纬度)创建 2D 球面索引
    db.shops.createIndex({ location: "2dsphere" });
    
  • 文本索引:用于全文搜索(如搜索文档中包含 “MongoDB” 的内容)。

    javascript

    db.articles.createIndex({ content: "text" });
    

2. 索引操作

  • 查看集合索引:db.users.getIndexes()
  • 删除索引:db.users.dropIndex({ age: 1 })

3. 注意事项

  • 索引会加快查询,但会减慢写入(插入 / 更新 / 删除),因为索引需要同步更新。
  • 避免过度索引:每个索引都会占用存储空间,建议只为高频查询字段创建索引。

六、分布式特性:高可用与扩展

MongoDB 原生支持分布式部署,解决大规模数据和高可用需求。

1. 副本集(Replica Set):高可用保障

副本集是一组维护相同数据的 MongoDB 实例,用于实现高可用数据冗余

  • 结构:1 个主节点(Primary)+ 多个从节点(Secondary)+ 1 个仲裁节点(Arbiter,可选)。

    • 主节点:处理所有写操作和客户端查询。
    • 从节点:复制主节点的数据,主节点故障时自动选举新主节点。
    • 仲裁节点:不存储数据,仅参与选举(降低部署成本)。
  • 作用:

    • 数据备份:从节点复制主节点数据,避免单点故障丢失数据。
    • 自动故障转移:主节点故障后,从节点自动选举新主节点,业务不中断。

2. 分片(Sharding):水平扩展

当数据量过大(如 TB 级),单台服务器无法承载时,分片可将数据拆分到多台服务器(分片节点),实现水平扩展。

  • 核心概念:

    • 分片键(Shard Key):用于拆分数据的字段(如用户 ID、时间),需提前规划(一旦确定不可修改)。
    • 分片集群组件:
      • 分片节点(Shard):存储实际数据(通常是副本集,保证高可用)。
      • 路由节点(Mongos):接收客户端请求,转发到对应分片。
      • 配置节点(Config Server):存储集群元数据(如分片键范围)。
  • 作用:分散数据存储压力,支持海量数据和高并发访问。

七、事务支持

MongoDB 4.0 及以上版本支持多文档事务,可保证多个操作的原子性(要么全部成功,要么全部失败),弥补了早期 NoSQL 数据库在事务上的短板。

八、适用场景与不适用场景

适用场景:
  • 大数据量、高写入场景:如日志存储、用户行为追踪(灵活 schema 适合频繁变更的数据)。
  • 快速迭代的业务:如互联网产品(无需预先定义表结构,适应需求快速变化)。
  • 需要地理空间查询:如地图应用(支持地理空间索引)。
  • 高可用与扩展需求:如电商平台(副本集保证不宕机,分片支持海量订单)。
不适用场景:
  • 强事务与复杂关联:如银行核心系统(虽然支持事务,但复杂多表 join 不如关系型数据库高效)。
  • 固定 schema 且结构简单:如简单的配置表(关系型数据库更轻量)。


总结

MongoDB 以灵活的文档模型打破了关系型数据库的固定 schema 限制,同时通过副本集分片实现高可用与水平扩展,再加上完善的查询能力和事务支持,成为 NoSQL 数据库中的佼佼者。

它特别适合处理非结构化数据、快速迭代的业务和大规模数据场景,但在强事务和复杂关联场景中,仍需权衡与关系型数据库的选择。

Logo

惟楚有才,于斯为盛。欢迎来到长沙!!! 茶颜悦色、臭豆腐、CSDN和你一个都不能少~

更多推荐