MongoDB 简介

在动手装环境之前,我们先搞清楚 MongoDB 到底是什么、为什么会出现、它解决了关系数据库的哪些痛点。理解了背景,后面学语法才会"知其所以然"。

MongoDB 是什么?

MongoDB 是 2009 年由 MongoDB Inc.(原名 10gen)开源的文档型数据库,名字来自英文单词 "humongous"(巨大的)。它属于 NoSQL 阵营的一员——不用传统的表 + 行 + SQL,而是把数据存成一个个"文档"(document),每个文档本质上是一个 JSON 对象(技术上是 BSON,即二进制 JSON)。

一组相关文档放进同一个"集合"(collection),集合对应关系数据库里的"表"。整个数据库的层级是:数据库 → 集合 → 文档

为什么需要 NoSQL?MySQL 不够用吗?

MySQL 这类关系数据库四十多年来经久不衰,擅长处理结构化、关系清晰、事务强一致的数据(银行转账、订单)。但 Web 时代之后,出现了很多"不太乖"的数据:

MongoDB 给的答案是:直接把整个 JSON 对象存进数据库,不用拆表。看个对比就一目了然:

// 关系数据库:一篇文章相关数据拆成多张表,查询时 JOIN
posts:       id=1 | title=入门    | author_id=7
authors:     id=7 | name=小明     | email=x@x.com
comments:    id=1 | post_id=1     | text=赞
tags:        id=3 | name=MongoDB
post_tags:   post_id=1 | tag_id=3

// MongoDB:把相关数据打包进"一个文档"
// 取出来时一次拿全,无需 JOIN
{
  _id: ObjectId("65a1f2c8..."),
  title: "入门",
  author: { name: "小明", email: "x@x.com" },
  tags: ["MongoDB", "NoSQL"],
  comments: [
    { text: "赞", at: ISODate("2025-01-01T00:00:00Z") }
  ]
}

同样的"一篇文章 + 作者 + 评论 + 标签",关系数据库要 4~5 张表加 JOIN,MongoDB 一个文档搞定,取出来一次拿全。读得多、关系紧密、形状经常变的场景,MongoDB 大幅简化了开发。

核心概念:数据库、集合、文档

MongoDB 的层级结构和关系数据库有清晰的对应,但有个关键差异:集合不用预先建。你往一个不存在的集合里插入文档,它会自动创建。数据库也一样。

// MongoDB 的层级结构
// 一个 mongod 实例可以管理多个数据库
//   每个数据库里有多个集合(collection)
//     每个集合里存放若干文档(document)

// 切换/创建数据库(首次写入时自动创建)
use myblog

// 集合不用预先建,插入时自动生成
db.posts.insertOne({ title: "第一篇" })
db.users.insertOne({ name: "小明" })

// 查看当前数据库里有哪些集合
show collections

核心概念:_id 与 ObjectId

每个文档都必须有一个 _id 字段作为主键,全集合唯一。你不指定的话,MongoDB 自动生成一个 ObjectId

// 每个文档都必须有一个 _id,作为主键
// 你不指定时,MongoDB 自动生成一个 ObjectId
db.users.insertOne({ name: "小明" })
// 写入后文档实际是:
// { _id: ObjectId("65a1f2c8a1b2c3d4e5f6a7b8"), name: "小明" }

// ObjectId 是 12 字节,结构如下:
// | 4 字节时间戳 | 5 字节随机值 | 3 字节自增计数 |
// 所以前 4 字节就能反推创建时间,自带"大致有序"

// 也可以自己指定 _id(比如用业务主键)
db.users.insertOne({ _id: "u-1001", name: "小红" })

// 再插一次同 _id 会报错(主键冲突)
db.users.insertOne({ _id: "u-1001", name: "重复" })  // E11000 duplicate key

ObjectId 看似一串随机字符,其实结构很精巧:前 4 字节是创建时间戳,所以它"大致按时间递增",天然适合做排序键;中间 5 字节是机器/进程标识;最后 3 字节是计数器。这意味着即使没有全局协调,不同节点生成的 ObjectId 也几乎不会冲突——这对分布式系统非常重要。

核心特点:schema 灵活

MongoDB 同一个集合里的文档字段可以不一样。今天存三个字段,明天加一个,后天去掉一个,完全不用改表结构。

// 同一个集合里,文档字段可以不一样
db.posts.insertOne({ title: "A", views: 0 })
db.posts.insertOne({ title: "B", views: 5, cover: "b.jpg" })
db.posts.insertOne({ title: "C", content: "...", author: "小明" })

// 加新字段不用 ALTER TABLE,直接写就行
// 这对产品快速迭代、数据形状经常变的场景极其友好

这种灵活是把双刃剑:好处是迭代飞快,代价是应用层要自己保证数据一致性(后来 MongoDB 3.2+ 加入了 validator 可选规则,平衡了灵活与严谨)。生产环境通常配合 ODM 库(如 Mongoose)在应用层定义 schema,既享受灵活性又保留约束。

MongoDB vs MySQL 对比

典型应用场景

它还"重"得起来吗?

别以为 NoSQL 就等于"玩具"。MongoDB 早就是个企业级数据库了:

小结

这一篇你了解了 MongoDB 的定位:把 JSON 对象当数据存的文档数据库,schema 灵活、不用拆表 JOIN、扩展性强,适合内容、画像、日志等"非结构化、迭代快"场景。下一篇我们装环境——本地装 Server,或直接用云端的 Atlas,跑起第一个 mongosh 命令。

← 返回 MongoDB 教程目录

下一篇 MongoDB 环境安装

✈️💬