LabHub
学习 学习路径 课程

MongoDB — 文档数据库的判断

schema 没有消失,只是换了地方

在 LabHub 中继续学习

一句话总结

文档数据库并不是“没有 schema 的数据库”,而是由应用程序持有 schema 的数据库。schema 并没有消失,只是换了位置。

概念图: 由应用程序持有 schema 的数据库 · 几个月后聚合查询返回异常结果时 · 一次查询会一起取回哪些内容 · 按照读取形态来存储数据

为什么需要理解这一点——不要误读“灵活”

初次使用 MongoDB 时,最常见的期待是“不必预先定义列,因此可以更快开发”。这句话没错,但它付出的代价去了哪里,往往很难看见。

在 RDB 中,如果把字符串写入 qty,数据库会当场拒绝;在文档数据库中,它可能被正常写入。直到几个月后聚合查询返回异常结果时,人们才发现问题。到了那时,已经无法知道哪份文档从何时开始出错。

因此,实际项目使用的文档数据库通常也有 schema:要么通过 $jsonSchema 约束,要么在应用层(Mongoose、Pydantic)过滤。两者至少要有一个。

真正不同的地方是什么

差异不在于有没有 schema,而在于一次查询会一起取回哪些内容

在 RDB 中,订单与商品项位于两张表里,通过 join 组合;在文档数据库中,可以把商品项嵌入订单文档。

{ _id: 1, customer: "김", lines: [ { name: "가방", qty: 2 }, { name: "신발", qty: 1 } ] }

如果订单页面所需的数据正好就是这种形态,一次查询即可完成,不需要 join,也没有 N+1。文档数据库的价值在于按照读取形态来存储数据

在实际项目中

所以判断标准可以收敛为一个问题:它们是否总被一起读取,又是否会分开修改?

如果商品项总是随订单一起读取,而且不会脱离订单单独修改,就适合嵌入。反过来,如果像商品信息那样被多个订单共同引用,修改后又必须对所有订单生效,就应该保留引用并单独管理。若采用嵌入,修改商品名称时就必须找到并更新所有包含它的文档。

面试官问“是否使用过 MongoDB”时,真正想听的就是这些:不是查询语法,而是你把边界嵌入到哪里、从哪里断开,以及为什么这样决定。