MST
星途 面试题库

面试题:MongoDB文档模型中嵌入文档与引用文档的适用场景有何不同

在MongoDB文档模型里,嵌入文档和引用文档是两种重要方式。请阐述在实际应用场景中,何时更适合使用嵌入文档,何时更适合使用引用文档,并举例说明。
13.2万 热度难度
数据库MongoDB

知识考点

AI 面试

面试题答案

一键面试

适合使用嵌入文档的场景及举例

  1. 紧密关联且数据量不大场景
    • 场景描述:当两个实体之间具有非常紧密的关系,并且嵌入的数据量相对较小,不会导致文档过大时,适合使用嵌入文档。例如在一个博客系统中,一篇博客文章与其评论之间的关系。评论是紧密围绕着特定文章的,并且一般一篇文章的评论数量不会过于庞大。
    • 示例:假设我们有一个blogPosts集合,每个博客文章文档结构如下:
{
    "_id": ObjectId("640c96f00b859e5c6c6a696b"),
    "title": "MongoDB文档模型示例",
    "content": "这是一篇关于MongoDB文档模型的文章...",
    "comments": [
        {
            "author": "user1",
            "text": "很棒的文章!",
            "date": ISODate("2023 - 03 - 10T12:00:00Z")
        },
        {
            "author": "user2",
            "text": "学习到了很多。",
            "date": ISODate("2023 - 03 - 11T14:30:00Z")
        }
    ]
}

这样在查询一篇博客文章时,能同时快速获取其所有评论,减少查询次数。

  1. 数据一致性要求高场景
    • 场景描述:如果对数据的一致性要求极高,希望在操作主文档时,相关联的数据能同时更新,嵌入文档是较好选择。例如在一个电商订单系统中,订单与其包含的商品明细。订单状态更新等操作时,商品明细也需要同步体现。
    • 示例orders集合中的文档:
{
    "_id": ObjectId("640c97500b859e5c6c6a696c"),
    "orderNumber": "20230310001",
    "customer": "customer1",
    "orderItems": [
        {
            "product": "Product A",
            "quantity": 2,
            "price": 10.0
        },
        {
            "product": "Product B",
            "quantity": 1,
            "price": 15.0
        }
    ],
    "totalPrice": 35.0,
    "orderStatus": "shipped"
}

修改订单状态时,订单商品明细也随之保存,确保数据一致性。

适合使用引用文档的场景及举例

  1. 数据量庞大且独立更新场景
    • 场景描述:当关联的数据量非常大,嵌入会导致主文档变得臃肿,并且关联数据可能会独立于主文档频繁更新时,适合使用引用文档。比如在一个社交媒体系统中,用户与他们发布的所有帖子。用户可能会持续发布大量帖子,且每个帖子可能会被频繁点赞、评论等操作更新。
    • 示例:我们有users集合和posts集合。users集合文档如下:
{
    "_id": ObjectId("640c97c00b859e5c6c6a696d"),
    "username": "user_abc",
    "email": "user_abc@example.com",
    "posts": [
        ObjectId("640c98000b859e5c6c6a696e"),
        ObjectId("640c98100000000000000000")
    ]
}

posts集合文档如下:

{
    "_id": ObjectId("640c98000b859e5c6c6a696e"),
    "title": "My first post",
    "content": "This is my first post on the platform...",
    "author": ObjectId("640c97c00b859e5c6c6a696d"),
    "likes": 10,
    "comments": [
        {
            "author": "user1",
            "text": "Great post!"
        }
    ]
}

这样避免了用户文档因包含大量帖子内容而变得过大,且帖子可独立更新。

  1. 多对多关系场景
    • 场景描述:当存在多对多关系时,引用文档更便于管理。例如在一个学校系统中,学生与课程之间的关系,一个学生可以选修多门课程,一门课程也可以有多个学生选修。
    • 示例students集合文档:
{
    "_id": ObjectId("640c98500b859e5c6c6a696f"),
    "name": "Student 1",
    "enrolledCourses": [
        ObjectId("640c98800b859e5c6c6a6970"),
        ObjectId("640c98900b859e5c6c6a6971")
    ]
}

courses集合文档:

{
    "_id": ObjectId("640c98800b859e5c6c6a6970"),
    "courseName": "Math",
    "students": [
        ObjectId("640c98500b859e5c6c6a696f"),
        ObjectId("640c98600b859e5c6c6a6972")
    ]
}

通过引用,可以清晰地表示这种多对多关系。