3

我试图了解 MongoDB 文档中数组和哈希的内部分配和放置(据我所知,这是通过数组实现的)。

在我们的领域中,我们的文档包含数千到数十万个键值对,其逻辑分组深度可达 5-6 级(想想嵌套散列)。

我们用一个点来表示键中的嵌套,例如 ,x.y.z在插入 MongoDB 时会自动变成如下所示:

{
    "_id" : "whatever",
    "x" : {
        "y" : {
            "z" : 5
        }
    }
}

最常见的操作是增加一个值,我们使用 atomic 执行此操作$inc,通常使用单个更新命令一次增加 1000+ 个值。随着时间的推移添加新密钥,但并不频繁,例如每天 100 次。

我想到另一种表示方法是不在名称中使用点,而是使用其他分隔符并创建一个平面文档,例如,

{
    "_id" : "whatever",
    "x-y-z" : 5
}

鉴于键值对的数量以及$inc更新和新键插入方面的使用模式,我正在寻找关于两种方法之间权衡的指导:

  • 磁盘空间开销

  • $inc更新性能

  • 新键插入的性能

4

1 回答 1

2

MongoDB 中文档的磁盘存储采用 BSON 格式。这里有 BSON 格式的详细描述:- http://bsonspec.org/#/specification

虽然使用短键名可以节省一些磁盘空间(因为您可以通过查看规范看到,键名嵌入在文档中),但在我看来,两者之间几乎没有净差异根据使用的磁盘空间进行设计——您使用分隔符 (-) 使用的额外字节通过不必为单独的键值使用字符串终止符而被买回。

两种格式的 $inc 更新应该花费几乎相同的时间,因为它们都将是内存中的操作。与从磁盘读取文档所需的时间相比,内存更新时间的任何改进都将是最小的舍入误差。

新键插入的性能也应该几乎相同。如果添加新的键/值对使新文档足够小以适合磁盘上的旧位置,那么所发生的就是更新内存版本并写入日志条目。最终,内存版本将被写入磁盘。

如果文档的增长超出了先前为其分配的空间,则新的键插入会带来更多问题。在这种情况下,服务器必须将文档移动到新位置并更新指向该文档的所有索引。这通常是一个较慢的操作,应该避免。但是,您正在讨论的架构更改不应影响文档移动的频率。再一次,我认为这是一次洗礼。

我的建议是使用最适合开发人员生产力的模式。如果您遇到性能问题,那么您可以就如何扩展系统或提高性能或两者兼而有之提出单独的问题。

于 2012-09-03T01:42:58.420 回答