存储/计算用户分数的最佳方法是什么?

7 mysql sql database database-design

我希望为一个网站设计一个数据库,用户可以通过该数据库获得执行某些活动的积分(声誉),并且正在努力应对数据库设计.

我打算保留用户所做事情的记录,这样他们可能会为他们提交的项目获得25分,每个他们所做的30条评论获得1分,还有10个奖励积分非常棒!

很明显,所有的数据都会存在,但似乎很多或者要查询每个用户的总得分,我想在他们的用户名旁边显示(以一个级别的形式).例如,对提交的项目表的查询以获取该用户的每个项目的分数,对评论表的查询等.如果需要对页面上提到的每个用户完成所有这些....大量的查询!

我曾经考虑过在用户表中保留一个分数,这看起来要快得多,但是我已经知道存储可以从其他数据计算的数据是很糟糕的!

我已经看到很多网站做类似的事情(甚至堆栈溢出也类似)所以我认为必须有一个"最佳实践".任何人都可以建议它可能是什么?

任何建议或意见都会很棒.谢谢!

Ed *_*fer 4

我认为这绝对是一个很好的问题。我必须构建与此具有类似行为的系统 - 特别是当包含分数的表被经常访问时(就像在您的场景中一样)。这是我给你的建议:

首先,创建一些如下所示的表(我正在使用 SQL Server 最佳实践,但可以按照您认为合适的方式命名它们):

UserAccount          UserAchievement
 -Guid (PK)           -Guid (PK)
 -FirstName           -UserAccountGuid (FK)
 -LastName            -Name
 -EmailAddress        -Score
Run Code Online (Sandbox Code Playgroud)

完成此操作后,继续创建一个如下所示的视图(不,我还没有验证此 SQL,但这应该是一个好的开始):

SELECT [UserAccount].[FirstName]      AS FirstName,
       [UserAccount].[LastName]       AS LastName,
       SUM([UserAchievement].[Score]) AS TotalPoints
FROM [UserAccount]
INNER JOIN [UserAchievement]
     ON [UserAccount].[Guid] = [UserAchievement].[UserAccountGuid]
GROUP BY [UserAccount].[FirstName],
         [UserAccount].[LastName]
ORDER BY [UserAccount].[LastName] ASC
Run Code Online (Sandbox Code Playgroud)

我知道您提到了对性能和大量查询的一些担忧,但如果您构建这样的视图,您将不需要多个视图。我建议不要将其设为物化视图;相反,只需对表建立索引,以便所需的查找(本质上是 UserAccountGuid)能够在整个表中进行快速求和。

我还要补充一点——如果您的 UserAccount 表变得很大,您可以考虑使用稍微更智能的查询,该查询将包含您需要汇总的帐户名称。当您只在页面上显示 3-10 个用户的信息时,这将使得您可以不向您的网站返回大量数据集。我必须更多地考虑如何优雅地做到这一点,但我建议远离“IN”语句,因为这将调用表的线性搜索。