抱歉这篇文章有点长而且很啰嗦。我正在创建我的第一个真正的游戏化Web应用程序,需要一些帮助来思考如何构建数据结构。
背景
用户需要在每个类别中完成任务才能升级。我有Users
、Tasks
和Categories
表,以及一个UserTasks
表,它连接了这三个表。(“用户3已经在类别8中添加了任务42。现在他们已经完成了它。”)这一切都很好,而且工作得非常好。
挑战
我不确定如何最好地跟踪每个类别中朝向每个等级的进度。业务规则如下:
- 您必须在每个类别中获得一定数量的积分才能升级。
- 如果您在Cat 8中获得所需的积分,但仍然有其他工作要完成该级别,则任何新的Cat 8积分都计入您的总分,但不会“滚动”到下一个级别。
- 类别的数量很少(目前为五个),但绝对不是固定的。
- 升级所需的积分将会因级别而异,可能是一个公式或查找表。
因此,挑战在于跟踪每个用户在每个类别中朝向下一个级别的进度。我想到了几种潜在的方法:
可能的解决方案
- 为每个类别添加一列到用户表中,并在每次用户升级时将它们全部重置为零。
- 使用单独的
UserProgress
表,每个用户每个类别都有一行,记录他们拥有的积分数。(基本上是#1的多对多版本。) - 在
UserTasks
表中添加userLevel
列,并使用某种SUM语句来推导他们的进度。
他们当前的等级将是User表中的一个简单整数。
优缺点
(1)似乎是最简单直接的方法,但也是最不灵活的。也许我可以使用基于类别ID的命名约定来帮助克服其中的一些问题。(例如使用像“select cats; for each cat, get the value from Users.progress_{cat.id}
”这样的代码。)这也是我失去最多数据的方法——我将不知道哪些积分计入了升级。我没有为此设想任何需求,所以也许我不在乎这个。
(2)看起来很复杂:每次添加或删除用户或类别时,都必须维护另一个表。我预见到同步方面的挑战。
(3)介于前两者之间——比#2更干净,但比#1不那么直观。为了找出用户的进度,我需要使用稍微复杂的SQL语句,例如:
SELECT categoryId, SUM(points) from UserTasks WHERE userId={user.id} & countsTowardLevel={user.level} groupBy categoryId
嗯...这似乎并不那么糟糕。我想我正在说服自己选择#3,但我很希望得到任何意见、建议或其他想法。