跳至主要内容

初学者使用 MongoDB 必知的 7 大概念

了解集合、文档、索引、查询等内容,为 NoSQL 数据库打下坚实基础。
Moses Anumadu
Moses Anumadu

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续继续即表示您接受我们的 使用条款,我们的 隐私政策 ,并且您的数据存储在美国。

MongoDB 是一种 NoSQL 数据库,采用灵活的文档式方法,将数据存储在组织为集合的类 JSON 文档中。简单来说,使用 MongoDB 时,您的数据看起来很像 JSON。这让它易读、易于映射到代码,并且具有良好的可扩展性。MongoDB 现代而且与关系型数据库的理念不同。关系型数据库通过表中的行来存储数据。这种方式有其优势,但一个主要挑战是需要借助额外的表来创建关系。MongoDB 通过引入灵活的模式,将数据存储在集合而非表中,来解决这一问题。这意味着与某个对象相关的数据可以与该对象存放在一起。在本教程中,我们将探索初学者在使用 MongoDB 时应了解的七个概念。话不多说,开始吧。

理解 NoSQL 与文档数据库

大多数人提到数据库时,会想到使用行、表和关系来存储数据的 SQL。对于许多应用来说,这非常合适,尤其是当应用数据是结构化的时候。但当数据无法整齐地装进表结构时,它可能会显得束手束脚。

这正是 NoSQL 发挥作用的地方。NoSQL 的意思是“not only SQL”(不仅仅是 SQL)。它涵盖了一系列背离僵化表模型、提供更大灵活性的数据库。与其强迫所有数据进入预定义的列中,您可以按照应用的实际工作方式来组织数据。

MongoDB 是一种 文档数据库,这是最流行的 NoSQL 数据库类型之一。它不使用行和表,而是将数据作为集合中的 文档 存储。每个文档看起来很像 JSON,包含键值对、数组,甚至嵌套对象。这让表示现实世界的数据变得非常容易。一个很好的例子是用户档案:地址和偏好可以放在同一条记录中,而无需拆分到多个表。下面我们看看在 MongoDB 中,包含地址和偏好的用户档案在一条记录中的样子。

{
"_id": "u123",
"name": "Moses Anu",
"email": "[email protected]",
"addresses": [
{ "type": "home", "city": "Abuja" },
{ "type": "work", "city": "Lagos" }
],
"preferences": {
"language": "English",
"theme": "dark"
}
}

MongoDB 架构基础

要高效地使用 MongoDB,需要理解 MongoDB 数据库中的数据组织方式。与以表和行组织数据的 SQL 数据库不同,MongoDB 使用集合与文档。

  • Database(数据库):可以把它看作一切的容器。就像在 MySQL 中可以有多个数据库一样,MongoDB 也提供多个数据库的灵活性,用于不同的项目或应用。
  • Collection(集合):每个数据库内部包含多个集合。可以把集合想象成具有高度灵活模式的表,因为 MongoDB 不强制严格的模式。您可以在同一集合中存放含有不同字段的文档。
  • Document(文档):这才是“魔法”发生的地方。文档是一个类 JSON 的对象(底层实际为 BSON),用于承载数据。文档可以包含嵌套对象和数组,使其在现代应用中更自然易用。我们将在下一段进一步讨论 BSON。

为更好地理解 MongoDB 架构,我们来看一个示例。假设我们用 MongoDB 构建一个简单的电商应用,数据结构可能如下所示。

  • 有一个名为 shopDB 的数据库。
  • 其中有一个名为 products 的集合。
  • 在该集合中,文档 用于表示每个商品,包含名称、价格、类别等详情。

灵活的模式

为更好地理解灵活模式的概念,以上面的示例来说,一个商品可以有 discount(折扣)字段,而另一个则没有。MongoDB 不会强制每个商品拥有完全相同的字段。这种灵活性是开发者喜欢 MongoDB 的重要原因之一,尤其是在快速迭代的应用中。

BSON 与数据类型

如果您曾使用过 JSON,MongoDB 会让您倍感自然。实际上,MongoDB 并不会将数据以纯 JSON 存储,而是使用 BSON。BSON 的全称是 Binary JSON(二进制 JSON)。

什么是 BSON,MongoDB 为什么使用它?

BSON 就像 JSON 更聪明、更高效的“表亲”。它保留了开发者喜爱的可读键值结构,同时增添了几项“超能力”:

  • 支持比 JSON 更多的数据类型(如日期、十进制和原始二进制)。
  • 针对 快速编码/解码 做了优化,使 MongoDB 查询更快。
  • 以紧凑的 二进制格式 存储,更适合处理大量数据。

简而言之,BSON 既赋予 MongoDB 类 JSON 的灵活性,又 提供数据库所需的性能与精度。

常见 BSON 数据类型

MongoDB 支持多种数据类型,以下是最常见的一些及其示例:

  • String(字符串) :"name": "Alice"
  • Number(数字) : "age": 28
  • Boolean(布尔) : "isActive": true
  • Date(日期) : "createdAt": ISODate("2025-08-18T10:00:00Z")
  • Array(数组) : "skills": ["MongoDB", "Node.js", "React"]
  • 嵌入式文档:文档中的嵌套对象:
"address": { 
  "city": "Lagos", 
  "country": "Nigeria" 
}
  • ObjectId:MongoDB 用于唯一文档 ID 的特殊类型。ObjectId("64f5c9e8a5f76b1d2c3a4567")

以下是存储在 MongoDB 中的 BSON 格式用户档案文档示例:

{
  "_id": ObjectId("64f5c9e8a5f76b1d2c3a4567"),
  "name": "Moses",
  "age": 30,
  "isActive": true,
  "skills": ["Laravel", "MongoDB", "Vue"],
  "address": {
    "city": "Abuja",
    "country": "Nigeria"
  },
  "createdAt": ISODate("2025-08-18T10:00:00Z")
}

需要注意的几点:

  • _id 字段如果未手动设置,会自动生成一个 ObjectId。
  • 日期以 ISODate 存储,而非普通字符串。
  • 嵌套的 address 文档和 skills 数组体现了 MongoDB 相比扁平 SQL 行的灵活性。

模式设计原则

MongoDB 具有灵活的模式,使您可以随应用增长而演进数据模型。然而,没有恰当的模式设计,MongoDB 的灵活性很快就会变得混乱。即便 MongoDB 提供灵活的模式,也不意味着可以完全不要结构。下面我们来看看在使用 MongoDB 时应遵循的一些模式设计原则。

灵活模式 vs. 无模式

MongoDB 常被描述为无模式,但这有些误导。每个文档确实有模式——只是除非您选择添加校验规则,否则不会在数据库层强制执行。

例如,同一 users 集合中的两个文档,从技术上看可以完全不同:

// Document 1
{ "name": "Alice", "email": "[email protected]" }

// Document 2
{ "username": "Bob123", "age": 29 }

这种灵活性在快速原型阶段很有用,但在生产环境中,通常需要一定的一致性。这就是 JSON Schema 校验 的作用所在。您可以强制某些规则,以免数据变得凌乱且不可靠。

嵌入 vs. 引用文档

MongoDB 模式设计的另一项重要决策是如何建模关系。我们来看看在 MongoDB 文档中建模关系的一些方法。

嵌入(在文档内嵌套数据)

MongoDB 支持在集合中嵌入文档。该方法适用于需要一并访问的数据。例如一篇博客文章,将评论直接存储在文章文档内。下面是嵌入数据的示例。

{
  "title": "Intro to MongoDB",
  "comments": [
    { "user": "Alice", "text": "Great post!" },
    { "user": "Bob", "text": "Very helpful." }
  ]
}

以这种方式存储的数据性能更好,检索或处理所需的查询更少。但如果结构不当,也可能导致文档臃肿。

引用(在文档之间建立链接)

当相关数据规模很大或经常被复用时,建议在文档之间建立链接,这称为引用。

例如一篇有大量评论的博客文章。在这种情况下,我们可以只存储评论的 ID,而实际评论放在独立的集合中。如下所示:

// Blog post
{ "title": "Intro to MongoDB", "commentIds": [ObjectId("..."), ObjectId("...")] }
// Separate comment document
{ "_id": ObjectId("..."), "user": "Alice", "text": "Great post!" }

这样组织数据可以让文档更小,避免重复,并提高代码的可维护性。不过,它需要多次查询(也可在聚合中使用 $lookup 进行连接)。

避免常见的模式设计错误

过度嵌入:由于 MongoDB 具有灵活模式,容易把所有东西都塞进一个巨大的文档中。这并不可取,会导致性能不佳。MongoDB 对单个文档强制 16MB 的大小上限,旨在确保开发者合理地将数据结构化为多个文档。

忽视索引:在使用 MongoDB 时不要忽视索引。如果查询与模式设计不匹配,最终会导致查找缓慢。始终以访问模式为导向进行设计。

把 MongoDB 当作 SQL 来用:将数据拆分为较小的文档没有问题。但请理解 MongoDB 的灵活模式,不要把它当作关系型数据库。如果照搬关系型模式(大量小而规范化的表/集合),就会丧失文档建模的优势。

花时间规划您的模式。周到的模式设计将极大影响应用的性能。

数据校验

MongoDB 很灵活。如果不加以注意,这很容易导致数据缺乏结构、杂乱无章。这就是数据校验 发挥作用的地方。

可以把校验看作是为集合设定基本规则。它确保任何插入或更新的文档都遵循特定规则,比如要求必须有 email 字段,或者确保“age”始终是一个数字。

在 MongoDB 中使用 JSON Schema 校验

MongoDB 支持用于校验的 JSON Schema。JSON Schema 是一种描述文档结构的标准方式。可以强制执行的规则包括:

  • 必填字段。
  • 数据类型(字符串、数字、日期等)。
  • 取值范围或字符串模式。

在 MongoDB 中,数据校验能带来两全其美的效果:MongoDB 的灵活模式加上 保护栏,帮助我们保持数据整洁。

强制规则以保持数据整洁

假设我们有一个 users 集合。我们希望确保:

  • 每个用户都有 name(字符串)。
  • 每个用户都有 email(字符串,且看起来像电子邮箱)。
  • 如果存在 age,则必须是大于或等于 18 的数字。

我们可以通过 JSON Schema 校验器来强制执行这些规则:

db.createCollection("users", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "email"],
      properties: {
        name: {
          bsonType: "string",
          description: "must be a string and is required"
        },
        email: {
          bsonType: "string",
          pattern: "^.+@.+\\..+$",
          description: "must be a valid email address"
        },
        age: {
          bsonType: "int",
          minimum: 18,
          description: "must be an integer greater than or equal to 18"
        }
      }
    }
  }
})

MongoDB 会确保只有通过校验的数据才会被保存到集合中。

CRUD 操作

使用 MongoDB 的核心在于四个基本操作: 创建、读取、更新 和 删除,统称为 CRUD。

掌握 CRUD,几乎就能构建任意应用。MongoDB 通过一组直观的方法让这一切变得简单。下面逐一介绍。

Create(创建)

要向 MongoDB 的集合添加新文档,使用 insertOne() 方法。例如,我们可以用下面的代码在 user 集合中创建一个新的用户文档。

db.users.insertOne({
  name: "Alice",
  email: "[email protected]",
  age: 25
})

MongoDB 会为每个创建的文档自动生成唯一的 _id。

Read(读取)

从集合读取数据很直接。我们使用 find()。可以获取所有文档,或使用条件进行过滤。下面的代码可以从用户集合中查找所有用户。

// Find all users
db.users.find()

我们可以使用唯一键进行过滤——例如 email。

// Find one user by email
db.users.find({ email: "[email protected]" })

find() 始终返回一个游标(您可以对其进行迭代)。如果只想要单个匹配,可以使用 indOne()。

Update(更新)

创建数据后,通常需要对其进行修改。要修改数据,使用 ``` updateOne()``` 方法。我们需要指定筛选条件以及要应用的更改。

// Update Alice’s age
db.users.updateOne(
  { email: "[email protected]" },
  { $set: { age: 26 } }
)

$set 运算符仅更新指定字段,其他字段保持不变。

Delete(删除)

最后,可以使用 deleteOne() 或 deleteMany() 删除文档。下面是 deleteOne 的示例。

// Delete Alice’s record
db.users.deleteOne({ email: "[email protected]" })

请注意,删除是不可恢复的。

仅凭这四个操作,您就可以构建从待办事项到电商平台的各类应用。

安全最佳实践

安全绝不应在 数据库方面被“事后考虑”。下面我们来看看每位初学者都应该了解的核心最佳实践。

身份验证与授权

默认情况下,全新安装的 MongoDB 可能不会强制启用身份验证。这意味着任何 能连接上的人都可能访问您的数据。如果不加以防范,这是巨大的风险。为了确保 MongoDB 不被暴露,我们可以实施身份验证与授权。

  • 身份验证(Authentication)确保只有合法用户能够连接。
  • 授权(Authorization)确保即便是已通过身份验证的用户,也只能执行被允许的操作。

例如,不要到处使用 root/admin 用户登录,应该为特定任务创建专用用户。

// Create a new user with read-only access
db.createUser({
  user: "reportViewer",
  pwd: "strongPassword123",
  roles: [ { role: "read", db: "salesDB" } ]
})

现在,该用户只能读取 salesDB 的数据,而不能写入或删除。

基于角色的访问控制(RBAC)

MongoDB 使用角色来管理用户能做什么。内置角色包括:

  • Read:只能查看数据。
  • ReadWrite:可以查看并修改数据。
  • DbAdmin:可以管理索引、统计和性能分析。
  • Root:拥有完全控制权限。避免在日常工作中使用!

遵循最小权限原则,只授予用户完成工作所需的权限,同时保障 MongoDB 的安全。

避免公网暴露

最常见的初学者错误之一,是让 MongoDB 监听默认端口(27017)并绑定到 0.0.0.0(所有网络接口)。

这意味着您的数据库向整个互联网开放。为防止这种情况,您应采取以下措施:

  • 仅将 MongoDB 绑定到 localhost 或私有/内部 IP。
  • 使用防火墙(或云安全组)限制访问。
  • 如需远程访问,请始终通过 VPN 或 SSH 隧道连接。
# Example: /etc/mongod.conf

net:

  port: 27017

  bindIp: 127.0.0.1   # Only accessible locally

遵循这些实践,您的 MongoDB 部署将更能抵御意外泄露或恶意攻击。

结语

凭借其灵活性与强大能力,MongoDB 已成为现代应用首选数据库之一。无论您是在鼓捣副项目,还是管理大规模系统,扎实掌握基础都能为您节省大量时间并提升效率。本文我们探讨了初学者在使用 MongoDB 时应了解的七个关键概念,包括:

  • 理解 NoSQL 与文档数据库。
  • MongoDB 架构基础。
  • BSON 与数据类型。
  • 模式设计原则。
  • 数据校验。
  • CRUD 操作。
  • 安全最佳实践。

充分理解以上概念,将为您使用 MongoDB 打下坚实基础。更多详情,请查阅 MongoDB 文档 和 DataCamp 的 Introduction to MongoDB in Python 课程。

FAQs

NoSQL 与 SQL 数据库有什么区别?

像 MongoDB 这样的 NoSQL 数据库以灵活、面向文档的格式存储数据,而 SQL 数据库使用具有固定模式的结构化表。

MongoDB 的架构如何工作?

MongoDB 采用分布式、可扩展的架构,包含副本集以实现高可用,以及分片以实现水平扩展。

什么是 BSON,MongoDB 为什么使用它?

BSON(二进制 JSON)是 MongoDB 的数据格式,旨在高效存储类 JSON 文档,并支持额外的数据类型。

为什么在 MongoDB 中模式设计很重要?

尽管 MongoDB 被称为无模式,周密的模式设计仍能确保高效查询、减少冗余并提升应用性能。

作为初学者,我该如何保护我的 MongoDB 数据库?

您可以启用身份验证、使用基于角色的访问控制、强制启用 TLS/SSL 连接,并定期更新 MongoDB 以防范漏洞。

Moses Anumadu

作者

Moses Anumadu

软件工程师

主题