奖励系统的数据库设计 - 即时计算或使用单独/连接表?

时间:2014-02-07 00:07:23

标签: database-design scalability database-performance

可以将以下方案与StackExchange信誉系统进行比较。我想知道哪种方法在性能和可扩展性方面是最好的方法。

场景:我有一个游戏网站,我需要为用户颁发奖牌。每枚奖牌显然都有自己的要求。示例:播放一定数量的比赛;连胜;一场比赛的前1名;等

选项1:如果在注册新匹配时满足条件,则将记录存储在连接表(users_medals)上。这一开始会更简单快捷,但很难跟踪未来对条件的变化(例如:增加某些奖牌所需的胜利次数)。

选项2:每次用户浏览用户个人资料时,不要存储任何关系并执行所有计算。它可以轻松处理条件变化,但是用户和奖牌越多,向用户显示信息的速度就越慢,或者更糟糕的是用户列表。

2 个答案:

答案 0 :(得分:0)

首先,我同意已经获得奖牌的miraculixx应该留在用户身边。因此,您应该将获得的奖牌与用户记录一起保存在联合表中,或者使用我用来显着加速应用程序的方法:

  1. 有一张表存放奖牌名称+标准的表格
  2. 将获得的奖牌的Id存储在用户记录的一列中(逗号分隔,Json,Hstore,XML ...) - 这有点非规范化,但会显着提高查找速度。
  3. 也许可以在每个活动中添加另一个表格,以获得新的奖牌,因为您可能希望用户可以选择查看他们的历史记录,比较人们达到目标的速度等等。
  4. 我绝对不会选择您的路线2,因为随着您的用户群增加,您将遇到非常糟糕的性能问题。

    现在,当用户查看他们的个人资料时,您的应用会使用Id's奖章迭代列,并从您的小桌子中取出可能有几十个不同的奖牌并显示它们(毫秒),而不是计算奖牌他赚了(大桌子很慢)。您的用户可以提取历史记录,也可以创建统计信息等。

    如果您更改标准以达到某些目标,那么使用先前标准达到目标的现有用户将保留其奖牌,新用户需要满足新条件。如果你不想要这个就拿走已经达到的奖牌(人们会变得非常生气;-))

答案 1 :(得分:0)

恕我直言,提供可扩展但快速解决方案的最佳方法是缓存计算值。我会将内容分解为多个表(或任何在任何nosql数据库中调用的内容)但计算更改并保留它们 - 快速重要。唯一与用户相关的缺点是某些不一致性,它包含在术语eventual consistency中。取决于您的用户会容忍的内容。

我认为如何考虑这类问题和解决方案的最好例子是研究某人如何使用redis设计twitter解决方案,请参阅http://redis.io/topics/twitter-clone