2

我们想设计一个可扩展的数据库。如果我们有 N 个用户,有 10 亿用户响应,那么从下面的 2 个选项中,哪个是好的设计?我们希望根据用户 ID 和响应 ID 进行查询。

  1. 有 2 个集合,一个用于用户信息,另一个用于存储响应和用户 ID。每个响应都存储为一个文档,因此我们将拥有 10 亿个文档。
    用户收藏
    {
      “用户ID”:“用户ID1”,
      “密码”:“xyz”,
      ,
      “城市”:“纽约”,
    },
    {
      “用户ID”:“用户ID2”,
      “密码”:“abc”,
      ,
      “城市”:“纽约”,
    }


    响应集合
    {
      “用户ID”:“用户ID1”,
      "responseID": "responseID1",
      “响应”:“xyz”
    },
    {
      “用户ID”:“用户ID1”,
      "responseID": "responseID2",
      “回应”:“ABC”
    },
    {
      “用户ID”:“用户ID2”,
      "responseID": "responseID3",
      “响应”:“mno”
    }
  1. 有 1 个集合来存储以下信息。每个响应都由一个新键 (responseIDX) 表示。
    {
      “用户ID”:“用户ID1”,
      “responseID1”:“xyz”,
      "responseID2" : "abc",
      ,
      “响应N”;"mno",
      “城市”:“纽约”
    }
4

2 回答 2

1

如果您使用第一个选项,我会使用与 MongoDB 相对的关系数据库(如 MySQL)。如果您真心喜欢 MongoDB,请利用它来发挥您的优势。

{
   "userId": n,
   "city": "foo"
   "responses": {
       "responseId1": "response message 1",
       "responseId2": "response message 2"
   }
}

至于哪个会带来更好的性能,请运行一些基准测试。

于 2013-10-06T03:19:12.173 回答
1

在您列出的两个选项之间 - 我认为使用单独的集合会更好地扩展 - 或者可能是单独集合的组合并且仍然使用嵌入式文档。

嵌入式文档可以为您的架构设计带来好处 - 但当您拥有不断增长的嵌入式文档集(在您的情况下为响应)时,它就无法正常工作。这是因为文档增长 - 随着文档的增长 - 并且超出了为其在磁盘上分配的空间量,MongoDB 必须将该文档移动到新位置以适应新的文档大小。当它经常发生或在高并发环境中发生时,这可能会很昂贵并且会导致严重的性能损失。

此外,当您希望有选择地只返回响应的子集时,查询这些嵌入式文档可能会变得很麻烦,尤其是跨用户。如 - 您不能只返回匹配的嵌入文档。然而,使用位置运算符,可以获得第一个匹配的嵌入文档。

因此,我建议对响应使用单独的集合。

不过,如上所述,我还建议尝试使用其他方法将这些响应分组到该集合中。每天、每个用户、每个……您可能拥有的任何其他维度等的文档。

以允许多个嵌入文档的方式对它们进行分组,并补充您查询它们的方式。如果您能在仍然使用该集合中的嵌入式文档和最小化文档增长之间找到最佳平衡点,那么您将拥有更少的整体文档和更小的索引大小。显然,这需要进行基准测试和测试,因为上面列出的相同警告也适用。

最后(并且可选地),对于这种类型的数据集,考虑使用增量计数器,您可以在前端提供您可能需要的任何类型的聚合报告。尽管 MongoDB 中的聚合框架很棒——比如说,预先聚合用户的总响应计数比尝试通过在完整数据集上运行聚合查询来获得计数要方便得多。

于 2013-10-07T00:05:53.067 回答