在MongoDB中存储面向列的表以便最佳地查询数据的最佳方法是什么

时间:2015-09-15 11:40:59

标签: mongodb meteor

我有一个大表,其中的列是user_id,user_feature_1,user_feature_2,....,user_feature_n

因此每行对应一个用户及其功能。

我将这个表存储在MongoDB中,将每个列的值存储为数组,例如:

{
   'name': 'user_feature_1',
   'values': [
   15,
   10,
   ...
   ]
}

我正在使用Meteor从MongoDB中提取数据,这种存储方式有助于快速轻松地检索整个列的图形绘制值。

然而,这种存储方式有一个主要缺点;我不能存储大于16mb的数组。

有几种可能的解决方案,但其中没有一种似乎足够好:

  1. 使用gridFS存储每个列的值。我不确定meteor是否支持gridFS,它不支持切片数据,也就是说,我可能需要获得列的前1000个值。

  2. 以行面向格式存储表格。 E.g。

    {     ' user_id':1,     ' user_feature_1':10,     ' user_feature_2':0.9,
        ....     ' user_feature_n':42  }

  3. 但我认为这种存储数据的方式对于查询要素列的值是低效的

    或MongoDB根本不适合,sql是要走的路?但是Meteor不支持sql

    更新1: 我发现这篇有趣的文章谈论mongodb中的数组是低效的。 https://www.mongosoup.de/blog-entry/Storing-Large-Lists-In-MongoDB.html

    以下说明来自http://bsonspec.org/spec.html

    数组 - 数组的文档是一个普通的BSON文档,其中包含键的整数值,从0开始并按顺序继续。例如,数组[' red',' blue']将被编码为文档{' 0':' red',& #39; 1':'蓝色'}。键必须按数字升序排列。

    这意味着如果值和键是浮点型(16mb / 128bits),我们可以在文档中存储最多100万个值

2 个答案:

答案 0 :(得分:1)

还有第三种选择。每个用户和功能的单独文档:

{ u:"1", f:"user_feature_1", v:10 },
{ u:"1", f:"user_feature_2", v:11 },
{ u:"1", f:"user_feature_3", v:52 },
{ u:"2", f:"user_feature_1", v:4  },
{ u:"2", f:"user_feature_2", v:13 },
{ u:"2", f:"user_feature_3", v:12 },

您将不会出现文档增长问题,您可以同时查询“用户x的所有值”和“功能x的所有值”,而无需访问任何不相关的数据。

答案 1 :(得分:1)

16MB / 64bit float = 2,000,000 uncompressed datapoints。什么样的图表需要每列至少200万点 ???而是尝试:

  • 在s3服务器上保存图片
  • 使用像hadoop这样的map-reduce解决方案(可能是你最好的选择)
  • 如果他们当前正在浮动,则将数字减少到小的数量
  • 在客户端上动态计算数据(如果可能,首选)
  • 使用压缩算法,这样您就可以保存子集&插入其余的

也就是说,在这个用例中,基于文档的数据库将胜过SQL数据库,因为SQL数据库的行为与Philipp建议完全相同。无论哪种方式,您都不能向客户端发送多个16MB文件,如果客户端没有让您忘记用户体验,那么您将破坏服务器成本:-)。