内嵌与引用
约 494 字大约 2 分钟
布欧-Lewyon
2026-05-15
首页 › MongoDB › 数据建模(在新窗口打开) › 内嵌与引用
内嵌文档
// 内嵌方式:地址直接放在用户文档中
{
_id: 1,
name: "Alice",
addresses: [
{ type: "home", city: "Beijing", street: "Chaoyang Rd" },
{ type: "work", city: "Shanghai", street: "Nanjing Rd" }
]
}何时内嵌
| 适合内嵌 | 不适合内嵌 |
|---|---|
| 子数据与父数据一起查询 | 子数据被多个父文档引用 |
| 一对关系(一对一,小一对多) | 多对多关系 |
| 子数据不单独查询 | 子数据独立查询和更新 |
| 子数据更新不频繁 | 子数据独立增长(如评论) |
引用
// 引用方式:用户订单分开存储
// users
{ _id: 1, name: "Alice" }
// orders(存 userId 引用)
{ _id: 100, userId: 1, amount: 200, createdAt: ISODate("2026-01-01") }
{ _id: 101, userId: 1, amount: 350, createdAt: ISODate("2026-01-15") }
// 查询时使用 $lookup 关联
db.orders.aggregate([
{ $match: { userId: 1 } },
{ $lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "user"
}}
])选择决策
核心原则:"在一起查询的数据,应该在一起存储"。
内嵌 vs 引用对比
| 对比 | 内嵌 | 引用 |
|---|---|---|
| 查询性能 | 一次查询拿到所有数据 | 需要 $lookup 或多次查询 |
| 原子性 | 文档级原子操作 | 需要事务 |
| 文档大小 | 不可超过 16MB | 无限制 |
| 数据冗余 | 无 | 可能有(关系维护) |
| 更新效率 | 更新父文档影响子数据 | 独立更新 |
小结
- 内嵌:子数据常与父数据一同查询、不独立增长时推荐。
- 引用:子数据独立增长、多对多关系、超过 16MB 时使用。
- 核心原则:"查询在一起,存储在一起"。
- 混合使用:部分内嵌 + 部分引用是常见的折中方案。
