首页 > 解决方案 > MongoDB 是否将文档中的 DBRefs 作为 16MB 阈值的完整大小文档?

问题描述

例如,我有一个名为 Country 的文档,其中包含指向另一个名为 Cities 的文档的多个 DBRef。例如,如果每个 City 文档的大小为 8MB,我只能在 Country 文档中存储两个 DBRef,或者 DBRef 只是一个引用而不是引用文档的完整大小?

标签: mongodb

解决方案


比较存储关系数据的两种不同方式:

  1. 嵌入数据
  2. 参考数据

嵌入数据:

国家集合 (城市信息作为国家文档中的子文档数组嵌入)

{
    "_id" : ObjectId("5e336c2bc0a47e0a958a2b9c"),
    "name" : "France",
    "cities" : [
        {
            "name" : "Paris",
            "population" : 2190327
        },
        {
            "name" : "Marseille",
            "population" : 862211
        }
    ]
}
{
    "_id" : ObjectId("5e336c85c0a47e0a958a2b9d"),
    "name" : "Germany",
    "cities" : [
        {
            "name" : "Berlin",
            "population" : 3520031
        },
        {
            "name" : "Hamburg",
            "population" : 1787408
        },
        {
            "name" : "Munich",
            "population" : 1450381
        }
    ]
}

参考数据

(城市单独收集)

城市集合

{
    "_id" : ObjectId("5e336cfdc0a47e0a958a2b9e"),
    "name" : "Paris",
    "population" : 2190327
}
{
    "_id" : ObjectId("5e336cfdc0a47e0a958a2b9f"),
    "name" : "Marseille",
    "population" : 862211
}
{
    "_id" : ObjectId("5e336d11c0a47e0a958a2ba0"),
    "name" : "Berlin",
    "population" : 3520031
}
{
    "_id" : ObjectId("5e336d11c0a47e0a958a2ba1"),
    "name" : "Hamburg",
    "population" : 1787408
}
{
    "_id" : ObjectId("5e336d11c0a47e0a958a2ba2"),
    "name" : "Munich",
    "population" : 1450381
}

国家集合

{
    "_id" : ObjectId("5e336c2bc0a47e0a958a2b9c"),
    "name" : "France",
    "cities" : [
        DBRef("cities", ObjectId("5e336cfdc0a47e0a958a2b9e"), "mydatabase"),
        DBRef("cities", ObjectId("5e336cfdc0a47e0a958a2b9f"), "mydatabase")
    ]
}
{
    "_id" : ObjectId("5e336c85c0a47e0a958a2b9d"),
    "name" : "Germany",
    "cities" : [
        DBRef("cities", ObjectId("5e336d11c0a47e0a958a2ba0"), "mydatabase"),
        DBRef("cities", ObjectId("5e336d11c0a47e0a958a2ba1"), "mydatabase"),
        DBRef("cities", ObjectId("5e336d11c0a47e0a958a2ba2"), "mydatabase")
    ]
}

评估

比较这两者时,我们可以看到文档的大小不同。使用参考文献时,国家文件的大小较小。这个例子充其量只是学术性的,但考虑子文档是否很大......

文档大小(以字节为单位)

嵌入式文档:

Object.bsonsize(db.countries.findOne({name: "France"}))
144

Object.bsonsize(db.countries.findOne({name: "Germany"}))
189

参考版本

Object.bsonsize(db.countries.findOne({name: "France"}))
166


Object.bsonsize(db.countries.findOne({name: "Germany"}))
224

结论

好吧,这个练习的重点是显示嵌入的文档比引用的文档重,但是子文档太小(在这个例子中)导致这个实验显示相反的结果!嵌入文档比引用小,因为 ObjectIds 很重(相对)。考虑嵌入的子文档是否很大。这会以另一种方式影响实验。您可以试验不同的数据集以查看大小差异,以帮助确定最佳模式方法。大小限制只是模式设计的一个方面。DBRef 查找比嵌入式文档慢得多,因为每个子文档本质上就是一个查询本身。此外,考虑将 ObjectID 嵌入为原始数据点而不是实际 DBRef 的想法——这可能会产生更小更快的方法。

请添加评论或问题,我将很乐意讨论!


推荐阅读