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 集合中的两个文档,从技术上看可以完全不同:
{ "name" : "Alice" , "email" : "[email protected] " }
{ "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,而实际评论放在独立的集合中。如下所示:
{ "title" : "Intro to MongoDB" , "commentIds" : [ ObjectId("..." ), ObjectId("..." )] } 技术支持
{ "_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()。可以获取所有文档,或使用条件进行过滤。下面的代码可以从用户集合中查找所有用户。
db.users.find()技术支持
我们可以使用唯一键进行过滤——例如 email。
db.users.find({ email: "[email protected] " } )技术支持
find() 始终返回一个游标(您可以对其进行迭代)。如果只想要单个匹配,可以使用 indOne()。
Update(更新)
创建数据后,通常需要对其进行修改。要修改数据,使用 ``` updateOne()``` 方法。我们需要指定筛选条件以及要应用的更改。
db.users.updateOne(
{ email: "[email protected] " } ,
{ $set: { age: 26 } }
)技术支持
$set 运算符仅更新指定字段,其他字段保持不变。
Delete(删除)
最后,可以使用 deleteOne() 或 deleteMany() 删除文档。下面是 deleteOne 的示例。
db.users.deleteOne({ email: "[email protected] " } )技术支持
请注意,删除是不可恢复的。
仅凭这四个操作,您就可以构建从待办事项到电商平台的各类应用。
安全最佳实践
安全绝不应在 数据库方面被“事后考虑”。下面我们来看看每位初学者都应该了解的核心最佳实践。
身份验证与授权
默认情况下,全新安装的 MongoDB 可能不会强制启用身份验证。这意味着 任何 能连接上的人都可能访问您的数据。如果不加以防范,这是巨大的风险。为了确保 MongoDB 不被暴露,我们可以实施身份验证与授权。
身份验证(Authentication) 确保只有合法用户能够连接。
授权(Authorization) 确保即便是已通过身份验证的用户,也只能执行被允许的操作。
例如,不要到处使用 root/admin 用户登录,应该为特定任务创建专用用户。
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 课程 。
MongoDB 是一种 NoSQL 数据库,采用灵活的文档式方法,将数据存储在组织为集合的类 JSON 文档中。简单来说,使用 MongoDB 时,您的数据看起来很像 JSON。这让它易读、易于映射到代码,并且具有良好的可扩展性。MongoDB 现代而且与关系型数据库的理念不同。关系型数据库通过表中的行来存储数据。这种方式有其优势,但一个主要挑战是需要借助额外的表来创建关系。MongoDB 通过引入灵活的模式,将数据存储在集合而非表中,来解决这一问题。这意味着与某个对象相关的数据可以与该对象存放在一起。在本教程中,我们将探索初学者在使用 MongoDB 时应了解的七个概念。话不多说,开始吧。
理解 NoSQL 与文档数据库
大多数人提到数据库时,会想到使用行、表和关系来存储数据的 SQL。对于许多应用来说,这非常合适,尤其是当应用数据是结构化的时候。但当数据无法整齐地装进表结构时,它可能会显得束手束脚。
这正是 NoSQL 发挥作用的地方。NoSQL 的意思是“not only SQL”(不仅仅是 SQL)。它涵盖了一系列背离僵化表模型、提供更大灵活性的数据库。与其强迫所有数据进入预定义的列中,您可以按照应用的实际工作方式来组织数据。
MongoDB 是一种 文档数据库,这是最流行的 NoSQL 数据库类型之一。它不使用行和表,而是将数据作为集合中的 文档 存储。每个文档看起来很像 JSON,包含键值对、数组,甚至嵌套对象。这让表示现实世界的数据变得非常容易。一个很好的例子是用户档案:地址和偏好可以放在同一条记录中,而无需拆分到多个表。下面我们看看在 MongoDB 中,包含地址和偏好的用户档案在一条记录中的样子。
MongoDB 架构基础
要高效地使用 MongoDB,需要理解 MongoDB 数据库中的数据组织方式。与以表和行组织数据的 SQL 数据库不同,MongoDB 使用集合与文档。
为更好地理解 MongoDB 架构,我们来看一个示例。假设我们用 MongoDB 构建一个简单的电商应用,数据结构可能如下所示。
灵活的模式
为更好地理解灵活模式的概念,以上面的示例来说,一个商品可以有 discount(折扣)字段,而另一个则没有。MongoDB 不会强制每个商品拥有完全相同的字段。这种灵活性是开发者喜欢 MongoDB 的重要原因之一,尤其是在快速迭代的应用中。
BSON 与数据类型
如果您曾使用过 JSON,MongoDB 会让您倍感自然。实际上,MongoDB 并不会将数据以纯 JSON 存储,而是使用 BSON。BSON 的全称是 Binary JSON(二进制 JSON)。
什么是 BSON,MongoDB 为什么使用它?
BSON 就像 JSON 更聪明、更高效的“表亲”。它保留了开发者喜爱的可读键值结构,同时增添了几项“超能力”:
简而言之,BSON 既赋予 MongoDB 类 JSON 的灵活性,又 提供数据库所需的性能与精度。
常见 BSON 数据类型
MongoDB 支持多种数据类型,以下是最常见的一些及其示例:
"name": "Alice""age": 28"isActive": true"createdAt": ISODate("2025-08-18T10:00:00Z")"skills": ["MongoDB", "Node.js", "React"]ObjectId("64f5c9e8a5f76b1d2c3a4567")以下是存储在 MongoDB 中的 BSON 格式用户档案文档示例:
需要注意的几点:
_id字段如果未手动设置,会自动生成一个ObjectId。ISODate存储,而非普通字符串。address文档和skills数组体现了 MongoDB 相比扁平 SQL 行的灵活性。模式设计原则
MongoDB 具有灵活的模式,使您可以随应用增长而演进数据模型。然而,没有恰当的模式设计,MongoDB 的灵活性很快就会变得混乱。即便 MongoDB 提供灵活的模式,也不意味着可以完全不要结构。下面我们来看看在使用 MongoDB 时应遵循的一些模式设计原则。
灵活模式 vs. 无模式
MongoDB 常被描述为无模式,但这有些误导。每个文档确实有模式——只是除非您选择添加校验规则,否则不会在数据库层强制执行。
例如,同一
users集合中的两个文档,从技术上看可以完全不同:这种灵活性在快速原型阶段很有用,但在生产环境中,通常需要一定的一致性。这就是 JSON Schema 校验 的作用所在。您可以强制某些规则,以免数据变得凌乱且不可靠。
嵌入 vs. 引用文档
MongoDB 模式设计的另一项重要决策是如何建模关系。我们来看看在 MongoDB 文档中建模关系的一些方法。
嵌入(在文档内嵌套数据)
MongoDB 支持在集合中嵌入文档。该方法适用于需要一并访问的数据。例如一篇博客文章,将评论直接存储在文章文档内。下面是嵌入数据的示例。
以这种方式存储的数据性能更好,检索或处理所需的查询更少。但如果结构不当,也可能导致文档臃肿。
引用(在文档之间建立链接)
当相关数据规模很大或经常被复用时,建议在文档之间建立链接,这称为引用。
例如一篇有大量评论的博客文章。在这种情况下,我们可以只存储评论的 ID,而实际评论放在独立的集合中。如下所示:
这样组织数据可以让文档更小,避免重复,并提高代码的可维护性。不过,它需要多次查询(也可在聚合中使用 $lookup 进行连接)。
避免常见的模式设计错误
过度嵌入:由于 MongoDB 具有灵活模式,容易把所有东西都塞进一个巨大的文档中。这并不可取,会导致性能不佳。MongoDB 对单个文档强制 16MB 的大小上限,旨在确保开发者合理地将数据结构化为多个文档。
忽视索引:在使用 MongoDB 时不要忽视索引。如果查询与模式设计不匹配,最终会导致查找缓慢。始终以访问模式为导向进行设计。
把 MongoDB 当作 SQL 来用:将数据拆分为较小的文档没有问题。但请理解 MongoDB 的灵活模式,不要把它当作关系型数据库。如果照搬关系型模式(大量小而规范化的表/集合),就会丧失文档建模的优势。
花时间规划您的模式。周到的模式设计将极大影响应用的性能。
数据校验
MongoDB 很灵活。如果不加以注意,这很容易导致数据缺乏结构、杂乱无章。这就是数据校验 发挥作用的地方。
可以把校验看作是为集合设定基本规则。它确保任何插入或更新的文档都遵循特定规则,比如要求必须有 email 字段,或者确保“age”始终是一个数字。
在 MongoDB 中使用 JSON Schema 校验
MongoDB 支持用于校验的 JSON Schema。JSON Schema 是一种描述文档结构的标准方式。可以强制执行的规则包括:
在 MongoDB 中,数据校验能带来两全其美的效果:MongoDB 的灵活模式加上 保护栏,帮助我们保持数据整洁。
强制规则以保持数据整洁
假设我们有一个 users 集合。我们希望确保:
我们可以通过 JSON Schema 校验器来强制执行这些规则:
MongoDB 会确保只有通过校验的数据才会被保存到集合中。
CRUD 操作
使用 MongoDB 的核心在于四个基本操作: 创建、读取、更新 和 删除,统称为 CRUD。
掌握 CRUD,几乎就能构建任意应用。MongoDB 通过一组直观的方法让这一切变得简单。下面逐一介绍。
Create(创建)
要向 MongoDB 的集合添加新文档,使用
insertOne()方法。例如,我们可以用下面的代码在user集合中创建一个新的用户文档。MongoDB 会为每个创建的文档自动生成唯一的
_id。Read(读取)
从集合读取数据很直接。我们使用
find()。可以获取所有文档,或使用条件进行过滤。下面的代码可以从用户集合中查找所有用户。我们可以使用唯一键进行过滤——例如 email。
find()始终返回一个游标(您可以对其进行迭代)。如果只想要单个匹配,可以使用indOne()。Update(更新)
创建数据后,通常需要对其进行修改。要修改数据,使用 ``` updateOne()``` 方法。我们需要指定筛选条件以及要应用的更改。
$set运算符仅更新指定字段,其他字段保持不变。Delete(删除)
最后,可以使用
deleteOne()或deleteMany()删除文档。下面是deleteOne的示例。请注意,删除是不可恢复的。
仅凭这四个操作,您就可以构建从待办事项到电商平台的各类应用。
安全最佳实践
安全绝不应在 数据库方面被“事后考虑”。下面我们来看看每位初学者都应该了解的核心最佳实践。
身份验证与授权
默认情况下,全新安装的 MongoDB 可能不会强制启用身份验证。这意味着任何 能连接上的人都可能访问您的数据。如果不加以防范,这是巨大的风险。为了确保 MongoDB 不被暴露,我们可以实施身份验证与授权。
例如,不要到处使用 root/admin 用户登录,应该为特定任务创建专用用户。
现在,该用户只能读取
salesDB的数据,而不能写入或删除。基于角色的访问控制(RBAC)
MongoDB 使用角色来管理用户能做什么。内置角色包括:
遵循最小权限原则,只授予用户完成工作所需的权限,同时保障 MongoDB 的安全。
避免公网暴露
最常见的初学者错误之一,是让 MongoDB 监听默认端口(27017)并绑定到 0.0.0.0(所有网络接口)。
这意味着您的数据库向整个互联网开放。为防止这种情况,您应采取以下措施:
localhost或私有/内部 IP。遵循这些实践,您的 MongoDB 部署将更能抵御意外泄露或恶意攻击。
结语
凭借其灵活性与强大能力,MongoDB 已成为现代应用首选数据库之一。无论您是在鼓捣副项目,还是管理大规模系统,扎实掌握基础都能为您节省大量时间并提升效率。本文我们探讨了初学者在使用 MongoDB 时应了解的七个关键概念,包括:
充分理解以上概念,将为您使用 MongoDB 打下坚实基础。更多详情,请查阅 MongoDB 文档 和 DataCamp 的 Introduction to MongoDB in Python 课程。