成就/徽章系统

2022-08-30 15:44:12

我一直在浏览这个网站寻找答案,但我仍然有点不确定如何在其数据库结构和实现中规划类似的系统。

在PHP和MySQL中,很明显,一些成就是立即获得的(当采取专门行动时,在SO的情况下:填写所有配置文件字段),尽管我知道SO会在一定时间后更新并分配徽章。有这么多用户和徽章,这不会造成性能问题(就规模而言:用户和徽章的数量都很高)。

因此,我假设数据库结构将像这样简单:

Badges     |    Badges_User      |    User
----------------------------------------------
bd_id      |    bd_id            |  user_id
bd_name    |    user_id          |  etc
bd_desc    |    assigned(bool)   |  
           |    assigned_at      |

但正如有些人所说,最好采用增量样式方法,以便拥有1,000,000个论坛帖子的用户不会降低任何功能的速度。

那么,它是另一个可以增量的徽章表,还是只是上面badges_user表中的“进度”字段?

感谢您的阅读,请专注于所需系统的可扩展性(例如数千名用户和20至40个徽章)。

编辑:为了解决一些困惑,我assigned_at作为日期/时间,授予徽章的标准最好放在为每个徽章准备的查询/功能中,不是吗?(更好的灵活性)


答案 1

我认为您建议的结构(根据注释没有“分配”字段)将起作用,只需添加一个额外的表,例如“Submissions_User”,其中包含对user_id的引用和用于计算提交的递增字段。然后,您所需要的只是一个“事件侦听器”,就像这篇文章一样,我认为您将被设置。

编辑:对于成就徽章,请在每次提交时运行事件侦听器(当然仅适用于提交内容的用户),并当场颁发任何相关徽章。对于基于时间的徽章,我每晚都会运行一个CRON工作。循环访问一次完整的用户列表,并根据需要授予徽章。


答案 2

关于您包含的草图:删除badges_user上的布尔列。这在那里是没有意义的:这种关系是根据谓词“用户user_id assigned_at获得徽章bd_id”来定义的。

至于你的整体问题:首先将架构定义为关系型的,而不考虑速度(这将使你摆脱一半的潜在性能问题,可能以换取不同的性能问题),正确索引它(什么是正确的取决于查询模式),然后如果它很慢,从中派生一个(仍然是关系性的)设计,这是更快的。就像您可能需要预先计算一些聚合一样,等等。


推荐