2012-09-02 50 views
3

我想了解MongoDB文档中数组和哈希的内部分配和放置(其中,我理解的是通过数组实现的)。MongoDB数据模式性能

在我们的域中,我们拥有的逻辑分组中的数千和数十万个键 - 值对中的任何位置的文档(认为嵌套散列)。

我们代表的按键嵌套有一个点,例如,x.y.z,这在插入的MongoDB将自动成为类似:

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

最常见的操作是增加值,这是我们用做一个原子$inc,通常1000+值一次只有一个更新命令。新密钥会随着时间而增加,但不会频繁,例如每天100次。

它发生在我的另一种表示将不会使用名字点,但一些其他的分隔符,创建平面文件,例如,

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

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

  • 空间开销上盘

  • 性能$inc更新

  • 的新密钥插入

回答

2

MongoDB中的磁盘上存储的文件是BSON格式的性能。还有就是BSON格式的详细描述在这里: - http://bsonspec.org/#/specification

虽然没有使用短键名(因为,你可以通过查看规格看到一些节省磁盘空间,将键值名称嵌入到文档中),在我看来,这两种设计在使用磁盘空间方面几乎没有差别 - 使用分隔符( - )使用的额外字节可以通过不必拥有字符串单独键值的终止符。

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

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

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

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

+1

阅读BSON规范,它看起来像数组和文档不能有任何填充以供将来使用。你是否以同样的方式阅读?这似乎有点奇怪:在100K文档中添加单个密钥时,他们可能需要修改磁盘上的许多块,因为可能需要将多达100K的数据移动几个字节。 – Sim

+0

你对规范是正确的。 MongoDB可以为文档分配额外的空间(填充因子),超过了规范允许的范围:http://www.mongodb.org/display/DOCS/Padding+Factor另外,当您最初创建时,您可以使用手动填充因子该文档:http://www.mongodb.org/display/DOCS/Padding+Factor#PaddingFactor-ManualPadding –

+0

在MongoDB中,当文档超过其插槽时,只移动该文档:文档周围的文档保持不变。当一个文件被移动时,它被移动到一个足够大的新记录中,以保持它的新大小(加上任何填充因子)。额外的I/O来自重新索引,而不是移动其他文档。 –