有一组注册管理员,比如100k。每个管理员每天24次给出价值smth,如23.123
。我需要保存这个值和时间。然后我需要计算一段时间内价值的变化,例如4jun2014 - 19jul2014:为了做到这一点,我必须找到3jun2014的最后一个值和19jul2014的最后一个值。
首先,我试图估算一个registrator存储的数据大小。时间+值必须小于100个字节。 1年是&lt; 100 * 24 * 365 = 720kB的数据,因此我可以在我的文档中轻松存储10年的数据(因为7.2M <16M限制)。我决定不将注册数据存储在registeredData
集合中,而是将嵌入在registrator对象中的registrator数据存储为树时间数据 - &gt; year-&gt; month-&gt;天:
{
code: '3443-12',
timedata: {
2013: {
6: {
13: [
{t:1391345679, d:213.12},
{t:1391349679, d:213.14},
]
}
}
}
}
因此很容易获得当天的价值:只需获得find({code: "3443-12"})[0].timedata[2013][6][13]
。
当我获得新数据时,我只是将其推入现有文档的数组中,最终从零增长到7Mb。
问题
{t:1391345679, d:213.12}
行的存储大小是多少,是否小于100字节?
为此目的组织数据库是否正确?
100k文档,5Mb大小= 500G。 MongoDB是否快速处理数据库大小远远超过RAM大小?
更新
我决定将时间存储为时间戳,而不是从一天开始的时间以秒为单位:0 - 86399:{t: 86123, d: 213.12}
。
答案 0 :(得分:1)
我已经测试了它并且它小于100 B,在行动中,它是48 B:
var num=100000;
for(i=0;i<num;i++){
db.foo.insert({t:1391345679, d:213.12})
};
db.foo.stats().avgObjSize // => Outputs 48
答案 1 :(得分:1)
看起来你正在做的是一种黑客,以避免规范你的数据(mb用于交易目的?),迟早你可能遇到问题(例如需求变化,数据变化的大小,新字段是介绍等。)我不知道您的架构和域,但如果您使用denomarmalized模型,您必须确保文档不会超过16MB的大小限制。话虽如此,我建议schema design article。
数目:
- 您在实体之间拥有“包含”关系。见模型 与嵌入式文档的一对一关系。
- 实体之间有一对多的关系。在这些关系中“很多”或 子文档总是出现或在上下文中查看 “一个”或父文件。请参阅模型一对多关系 嵌入式文件。
在您的情况下,您的文档将在创建后增长,这可能会影响写入性能并导致数据碎片化。您可以使用padding factor来控制此操作。
- 关于性能:它取决于您创建索引的方式。更重要的是,您的访问模式。对于经常执行的每个查询,请查看explain()
的输出,以查看已检查的文档数。
答案 2 :(得分:1)
关于你的上一个问题,&#34; MongoDB是否快速处理数据库大小远远超过RAM大小?&#34;答案是可以的,但这取决于许多因素。
当工作集适合MongoDB可用的内存时,MongoDB效果最佳。如果不是这样,你往往会看到相当快速的性能下降。工作集的大小是数据库模式,构建的索引和数据访问模式的函数。
假设您的数据库中有数年的数据,但通常只会触及过去几天的数据。然后你的工作集很可能是将最后几天的数据保存在内存中所需的内存,加上足够的内存索引,你可以正确地更新和读取它们。
或者,如果您在一年内随机访问数据且数量较多并且更新量较大,则可能需要处理更大的工作集。
作为比较点,我有一个生产MongoDB实例,其中包含大约5亿个文档,占用大约2 TB的磁盘存储空间。副本集主服务器上的总内存为128GB(总存储量的1/16),并且我们没有遇到任何性能问题。
所有这一切的关键是你随着时间的推移访问了多少数据。 MongoDB性能的杀手就是内存争用,当你分页数据来为新请求提供服务时,只能重新打开那些旧数据。如果你不能将索引保存在内存中,情况会更糟。