MongoDB 的文档模型是什么?和关系型数据库有什么区别?
简化版
MongoDB 使用文档模型存储数据,一条记录是一个 BSON 文档,结构类似 JSON,可以包含嵌套对象和数组。它和关系型数据库最大的区别是:MongoDB 更强调按业务访问模式组织聚合数据,而关系型数据库更强调表、行、列、外键和规范化关系。
详细版
MongoDB 的基本层级是:
| MongoDB | 类比关系型数据库 | 说明 |
|---|---|---|
| database | database | 数据库 |
| collection | table | 集合,不强制固定 schema |
| document | row | 文档,一条业务记录 |
| field | column | 字段,可以是嵌套结构 |
MongoDB 文档可以这样长:
{
_id: ObjectId("..."),
name: "Tom",
address: {
city: "Beijing",
street: "Road 1"
},
tags: ["vip", "new"]
}
它的优势是结构灵活、天然表达嵌套数据、读写一整个业务对象方便;不足是跨文档关联、复杂事务、强约束治理不如关系型数据库直观。
完整版教学
一、文档模型解决什么问题
很多业务数据本来就是一个完整对象。比如一篇文章包含标题、作者、标签、评论摘要、统计信息。如果用关系型数据库,可能拆成文章表、标签表、文章标签关系表、评论表。
MongoDB 倾向于把经常一起读取、一起更新的数据放在一个文档里。这样一次查询就能拿到业务对象,减少多表 JOIN 的需求。
这就是文档数据库的核心思想:数据结构服务于访问模式。
二、BSON 不是普通 JSON 文本
MongoDB 文档看起来像 JSON,但实际存储格式是 BSON。BSON 支持更多数据类型,比如:
- ObjectId;
- Date;
- Decimal128;
- Binary;
- 嵌套文档;
- 数组。
所以不能简单说 MongoDB 就是“存 JSON 文件”。它是数据库,有索引、查询语言、复制、分片、事务和恢复机制。
三、集合不强制固定 schema
MongoDB collection 中不同文档可以有不同字段:
{ name: "Tom", age: 18 }
{ name: "Jerry", email: "jerry@example.com" }
这给业务快速迭代带来便利,尤其适合字段变化频繁、扩展属性多的场景。
但灵活不等于不要设计。没有约束和规范时,字段命名混乱、类型不一致、历史数据难治理,后期会非常痛苦。实际项目通常仍要在应用层或 JSON Schema validation 中约束关键字段。
四、MongoDB 和关系型数据库不是谁替代谁
关系型数据库擅长:
- 强一致事务;
- 复杂 JOIN;
- 规范化建模;
- 强约束;
- 报表型 SQL 分析。
MongoDB 擅长:
- 半结构化数据;
- 聚合对象存储;
- 快速迭代字段;
- 高吞吐文档读写;
- 水平扩展场景。
选型时不要只说 MongoDB 性能高或关系库太老,而要看数据关系、查询模式、事务要求和团队维护能力。
五、文档设计要围绕访问模式
MongoDB 建模时常问:
- 业务查询经常一次取哪些数据?
- 数据是否经常一起更新?
- 子数据是否会无限增长?
- 是否需要跨对象强一致?
- 是否需要按某些字段建立索引?
如果一个用户有少量地址,嵌在用户文档里很自然;如果一个用户有百万条订单,不能全部嵌进用户文档。
六、文档模型也需要治理 schema 演进
MongoDB 不强制每个集合固定 schema,但生产系统不能放任字段随便长。字段类型一旦混乱,查询和索引都会变难:同一个 age 字段有的文档是数字,有的是字符串,范围查询和排序就会出现不可预期结果。
| 治理点 | 推荐做法 | 目的 |
|---|---|---|
| 关键字段 | 应用层校验或 JSON Schema validation | 保证必填和类型稳定 |
| 扩展字段 | 放入明确的 extra 或属性数组 | 避免顶层字段失控 |
| 版本演进 | 增加 schemaVersion 或兼容读取 | 支持灰度迁移 |
举例说,用户资料可以允许 profile.extra 扩展兴趣标签,但 _id、phone、status、createdAt 这类核心字段必须稳定。灵活 schema 的价值是支持变化,不是放弃数据质量。
七、常见误区与追问
| 对比维度 | MongoDB 文档模型 | 关系型模型 |
|---|---|---|
| 数据组织 | 按业务对象聚合 | 按表、行、列和关系拆分 |
| 约束方式 | 更依赖应用和可选校验 | 数据库约束更强 |
| 关联查询 | 尽量减少高频 JOIN | JOIN 是常见能力 |
| 适合数据 | 半结构化、嵌套对象 | 强关系、强事务数据 |
记忆钩子:MongoDB 不是“无结构”,而是“结构跟着访问模式走”。能一起读的一起放,会无限长的拆出去。
- 误区:MongoDB 就是存 JSON 文件。 MongoDB 使用 BSON,有索引、复制、分片、事务和查询优化机制,不是普通文件存储。
- 误区:schema 灵活等于不用建模。 没有字段规范、类型约束和版本治理,后期会出现查询混乱和数据难清洗。
- 误区:文档越大越能体现 MongoDB 优势。 文档边界过大时会带来大小限制、网络传输、更新放大和数组增长问题。
- 追问:为什么 MongoDB 建模要看访问模式? 因为它鼓励把经常一起读取和更新的数据放入同一文档,减少跨集合组装。
- 追问:什么时候关系型数据库更合适? 强事务、复杂 JOIN、多表约束、规范化报表分析明显时,关系型数据库通常更直接。
- 追问:BSON 比 JSON 多什么? BSON 支持 ObjectId、Date、Decimal128、Binary 等数据库类型,也便于二进制编码和内部处理。
八、加强记忆
MongoDB 文档模型的核心是“把业务对象作为文档存储”。它不是没有结构,而是结构更贴近业务读取方式;关系型数据库先想表关系和范式,MongoDB 先想文档边界、嵌套结构和访问模式。