首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >命名键与数字键- mongo

命名键与数字键- mongo
EN

Stack Overflow用户
提问于 2014-01-27 13:22:26
回答 3查看 2.5K关注 0票数 2

假设我们有一个单独用于缓存的Mongo实例。集合只是以下几个数组的转储

代码语言:javascript
代码运行次数:0
运行
复制
_id
key
value
expiration

不过,我们项目组的人。把它当作

代码语言:javascript
代码运行次数:0
运行
复制
_id
0
1
2

我们的后端(PHP)知道0= "key",1= "value",2=“期满”。他说:“最好这样做,所以我们不会在蒙古族的每一张唱片里都存储一个长密钥名。”

这对我来说是有意义的,因为每个文档都是单独存储的。然而,使用任何管理工具或试图在应用程序之外操作我们的数据几乎是不可能的。就像看1和0一样。所以我去测试了一下。

我做了一个小蒙古语集合命名的钥匙和数字。做完这件事之后。我对他们两个都运行了一个db.foo.stats()

他们匹配的每一个统计数据。所以我想我的问题是。如果我们有一个名为VeryLongKeyDescriptiveText的密钥,并将其存储在1000个记录中。这与存储0的物理大小和相应的值相同吗?(我的测试结果是肯定的,但我不明白蒙戈是怎么做到的)。

我的测试是两个集合(控制和测试)。使用以上两个键值设置。每个集合当前有3个文档,其中包括一个名称、一些base64 loren文本和一个到期的Unix时间戳。这两个集合都有相同的确切数据,除了测试中的键是(0,1,2)而不是(键,值,到期)。以下是stats()的两个输出:http://pastebin.com/tTt7VzwQ

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-02-13 18:13:36

如果扩展测试用例以创建更大的文档,存储差异就会变得更加明显。请考虑以下几点:

代码语言:javascript
代码运行次数:0
运行
复制
function createIntFields(j) {
  var document = {};
  for (i = 0; i < j; i++) {
    document[i] = i;
  }
  return document;
}

function createStringFields(j) {
  var document = {};
  for (i = 0; i < j; i++) {
    document["thisIsAVeryLongFieldNamePrefix" + i] = i;
  }
  return document;
}

db.int.drop();
for (i = 0; i < 1000; i++) { db.int.insert(createIntFields(i)); }

db.string.drop();
for (i = 0; i < 1000; i++) { db.string.insert(createStringFields(i)); }

统计数据确实有很大不同(我删除了一些无关的输出字段):

代码语言:javascript
代码运行次数:0
运行
复制
> db.int.stats();
{
    "ns" : "test.int",
    "count" : 1000,
    "size" : 9395008,
    "avgObjSize" : 9395,
    "storageSize" : 11182080,
    "numExtents" : 6,
    "lastExtentSize" : 8388608
}
> db.string.stats();
{
    "ns" : "test.string",
    "count" : 1000,
    "size" : 32098752,
    "avgObjSize" : 32098,
    "storageSize" : 37797888,
    "numExtents" : 8,
    "lastExtentSize" : 15290368
}

为了解释您看到的小文档大小,我们可以参考Mathias的存储内部表示,特别是滑梯#25。每个记录(例如,本例中的文档)对于记录长度、范围和next/prev指针有16字节的开销。此外,文档的最小有效负载为32字节.因此,即使我们用非常小的文档填充一个集合:

代码语言:javascript
代码运行次数:0
运行
复制
db.foo.drop();
for (i = 0; i < 1000; i++) { db.foo.insert({_id:i}); }

统计数据显示,平均文档大小为48:

代码语言:javascript
代码运行次数:0
运行
复制
> db.foo.stats()
{
    "ns" : "test.foo",
    "count" : 1000,
    "size" : 48032,
    "avgObjSize" : 48,
    "storageSize" : 172032,
    "numExtents" : 3,
    "lastExtentSize" : 131072
}

当文档有效负载超过32字节时,二人的力量分配就开始了,所以您仍然可以看到以圆形块分配的文档。在我的一些测试中,我注意到112是一个共同的平均大小(96 + 16)。

票数 2
EN

Stack Overflow用户

发布于 2014-01-27 14:06:19

的确,这两种观点在数据库大小上的差异通常不成比例,实际上,在短字段名和长字段名之间的1000条记录中,可能只有1MB的差异。

有时,如果您一致地使用长字段名,并且它们相当长,您将开始看到真正的问题。

对此问题的识别也可以与文档内容大小联系起来。我的意思是,如果你的文件已经很大了,那么你不会注意到太多的变化。

他们匹配了所有的数据。

我要说的是,幸运的是短字段名与长字段名的大小相同。

你确定数据是相同的,除了一个有短和一个有长字段名吗?

我实在看不出expiration2的大小在物理上是如何可能的,我可以看到key0是如何相对相同的字节数的。

票数 3
EN

Stack Overflow用户

发布于 2014-01-27 13:32:44

我的第一个想法是,他们已经实现了字段名的压缩或标记,但问题似乎仍未解决(截至2014年1月)。由于填充的缘故,它们的尺寸可能是一样的。由于性能原因,集合中的文档是填充的,因此它们通常可以在不需要移动的情况下进行适当的调整。您可以在没有任何填充的情况下尝试压实集合,以查看您现在是否看到了差异。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21382031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档