2

我有一个要求是建立一个问题调查系统。简单地说,它需要问题,预定义答案和用户的答案记录。

  • 问题需要一个问题ID,问题文本
  • 答案需要一个答案ID,答案文本
  • 用户的回答记录需要记录id,用户id,问题id,回答id,日期,操作系统,ip,浏览器信息,是live

对于用户记录,我需要保留所有历史记录,这就是为什么我需要一个“实时”列。因此,只有每个用户的最新答案是正确的。当用户再次回答同一个问题时,该用户所有存在的回答记录将是历史记录(is live = false)。

看似简单的结构。但是当我得到超过 100,000 个问题,超过 100 万用户,并且每个用户对每个问题有超过 20 个答案记录时,那么记录是超过 100,000 * 1,000,000 * 20 = 2,000,000,000,000 条记录。然后就成了一个大问题。

我还需要描述我需要如何使用这些数据。我需要提供另一个系统,它可以使用用户记录通过定义问题回答标准来定位一组用户。例如:

  1. (Q1=A1 && Q2=A3 && Q3=A5 && (Q4=A8 || Q5=A9)) 标准 1
  2. (Q1!=A1 && Q2=A3) 标准 2
  3. (Q4=A8 || Q5!=A9) 标准 3

在我定义标准之后:

  1. 我需要提供一个 api 来获取所有符合条件的用户 id (api1)
  2. 我需要提供一个 api 来获取用户的所有标准 (api2)

api需要快速和实时。而且api会被频繁调用。

所以想象一下,当一张表中有 200,000,000,000 条记录时。api 调用会很慢,甚至会杀死 db。

所以,我有一些不好的解决方案,我只是在这里列出,以便我们讨论:

  1. 每个问题都有一个表来保存该问题的所有用户记录。
  2. 每个用户都有一个表来保存该用户的所有问题记录。
  3. 1 和 2

但我可以看到那里的解决方案不是很好和有效。所以想在这里讨论一下。不管是哪种技术(sql、nosql、hadoop 等...)

请把你的想法放在这里。

4

1 回答 1

2

我会尝试使用 mongoDB,只使用一个“用户”集合将答案存储在数组中:

{userId: 1, 
 name: "nick",
 ...,
 "answers": [
    { questionId:1,
      answerId: 1,
      date: Date(...),
      ...,
      isLive: 1},
    { questionId:1
      answerId: 2,
      date: Date(...),
      ...,
      isLive: 0}
 ]
}

然后我会在属性“answers.isLive”上使用多键索引来确保高速访问“实时”答案。

“answers.questionId”和“answers.answerId”上的另一个多键索引应确保按照您的标准检索数据的高性能。

对于像你这样的数字,我会考虑从一开始就对你的收藏进行分片。

于 2013-01-04T15:43:23.160 回答