对不起,这很长,所有的散文。我正在创建我的第一个真正游戏化的Web应用程序,可以使用一些帮助来思考如何构建数据。
用户需要先完成几个类别中的任务才能升级。我有Users
,Tasks
和Categories
表,以及一个加入三个表的UserTasks
表。 (“用户3在类别8中添加了任务42。现在他们已经完成了它。”)这一切都很好并且工作得非常好。
我不确定跟踪每个级别的各个类别进度的最佳方法。 “业务”规则是:
因此,挑战在于跟踪每个用户在每个类别中向下一级别的进度。我想到了一些潜在的方法:
UserProgress
表,每个用户的每个类别都有一行,以及它们拥有的点数。 (基本上是#1的多对多版本。)userLevel
列添加到UserTasks
表,并使用该列通过某种SUM语句推导出它们的进度。他们当前的级别将是User表中的一个简单的int。
(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,但我会喜欢任何意见,建议或其他想法。
答案 0 :(得分:1)
我将投票给第3名。
任何时候我都可以聚合现有数据而不是单独存储“运行总计”,我抓住机会。对于像StackOverflow这样的大型网站,由于性能原因,这可能是不可行的,但对于中小型网络游戏,它应该可以很好地工作。
通过避免保持“运行总计”,您通常可以避免在多个地方执行相同(或类似)的操作。举一个非常简单的示例,在论坛中,如果post_count
是手动更新而不是计算为COUNT
,那么删除帖子也需要更新post_count
}。你拥有的这种情况越多,你对bug或“WTF”的潜力就越大。你的游戏玩家注意到两个或更多数字并不完全相加的时刻。
除了表单性能之外,使用简单聚合的一个主要缺点是,您有时不希望希望现有的总数受到您所做的更改的影响。我从来没有碰到这样的情况,但我确信它们存在。
答案 1 :(得分:0)
我绝对不会选择1.我想提供第4种方法。
如果我理解正确,用户在给定的类别/级别中需要得分为5才能访问下一个类别,但在那里可以获得总共10个积分,其中额外的5个积分不计入下一个类别。最简单的方法是制作一个这样的表:
| user_id | category_id | score | (primary key = user_id, category_id)
不要害怕存储总分,如果“从表中选择得分,其中user_id =?和category_id =?”,您可以查看查找表/公式。足够高了。
通过这种方式,您可以获得非常简单的查询,非常简单且可扩展的数据库设计(添加新类别或更改评分没有问题)。
如果您希望在以后的某个日期使用分数,只需使用sql的sum函数来获取用户的总分,然后将其与所需的总计分数相比较,并将其减去给定的分类。