MongoDB 数据库引用
                           
天天向上
发布: 2025-03-09 09:23:00

原创
188 人浏览过

在 MongoDB 中,引用(References)是一种用于在不同的文档或集合(Collections)之间建立关系的方法。与传统关系型数据库(RDBMS)中的外键不同,MongoDB 的引用是通过文档 ID(ObjectId)或其他唯一标识符来链接数据,实现文档之间的关联。


1. 为什么使用引用?

使用引用的主要原因:

  • 减少数据冗余:多个文档可以引用同一个数据,避免数据重复存储。
  • 提高数据一致性:更新数据时,只需修改被引用的数据,而不需要更新多个文档。
  • 支持复杂的多对多(N:M)关系:引用使得文档之间可以灵活地建立各种关系。

2. MongoDB 引用的两种方式

MongoDB 提供两种主要的引用方式:

  1. 手动引用(Manual References):通过存储 _id 或其他唯一字段,手动管理数据之间的关系。
  2. DBRef 方式(Database References):MongoDB 内置的引用格式,包含集合名称和 ObjectId,但使用较少。

3. 手动引用(推荐方式)

手动引用是 MongoDB 最常用的方式,直接存储外部文档的 _id,然后在查询时手动关联。

示例:用户(Users)与订单(Orders)

① 创建 users 集合

{
  "_id": ObjectId("65f20aefab3f5e001c9b1234"),
  "name": "Alice",
  "email": "alice@example.com"
}

② 创建 orders 集合,存储用户 ID

{
  "_id": ObjectId("65f20aefab3f5e001c9b5678"),
  "user_id": ObjectId("65f20aefab3f5e001c9b1234"),
  "product": "Laptop",
  "price": 1200
}

orders 文档中,字段 user_id 存储了 users 集合中的 _id,用于引用 Alice 的信息。

③ 查询:查找用户订单

db.orders.find({ user_id: ObjectId("65f20aefab3f5e001c9b1234") })

④ 关联查询:使用 $lookup 进行 JOIN

db.users.aggregate([
  {
    $lookup: {
      from: "orders",     // 关联的集合
      localField: "_id",  // users 集合中的字段
      foreignField: "user_id", // orders 集合中的字段
      as: "user_orders"   // 存放查询结果的字段
    }
  }
])

查询结果

{
  "_id": ObjectId("65f20aefab3f5e001c9b1234"),
  "name": "Alice",
  "email": "alice@example.com",
  "user_orders": [
    {
      "_id": ObjectId("65f20aefab3f5e001c9b5678"),
      "user_id": ObjectId("65f20aefab3f5e001c9b1234"),
      "product": "Laptop",
      "price": 1200
    }
  ]
}

💡 手动引用的优点

  • 查询速度较快,支持 $lookup 进行联表查询。
  • 适用于一对多(1:N)多对多(N:M)的关系。
  • 便于手动优化索引,提升查询效率。

4. 使用 DBRef(不推荐)

MongoDB 提供了一种标准的DBRef(Database References)格式来存储引用,但它的查询效率较低,因此不推荐使用。

DBRef 的存储格式:

{
  "$ref": "users", 
  "$id": ObjectId("65f20aefab3f5e001c9b1234")
}

查询时,MongoDB 需要额外的 db.dereference() 方法,影响性能,因此不推荐使用。


5. MongoDB 引用 vs. 内嵌文档

方式适用场景优点缺点
内嵌文档关系紧密,查询频繁查询速度快数据冗余,难以扩展
手动引用关系松散,数据共享减少冗余,支持 $lookup需要额外查询

6. 总结

  1. MongoDB 不支持外键约束,但可以通过引用(References)在文档之间建立关系。
  2. 推荐使用手动引用,即在文档中存储 _id,并使用 $lookup 进行查询。
  3. 尽量避免 DBRef,因为它的查询效率较低,不如手动引用高效。
  4. 选择引用还是内嵌文档?
  • 数据查询紧密使用内嵌文档
  • 数据可复用使用手动引用
  • N:M 关系使用手动引用

更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *