成就/徽章系统
我一直在浏览这个网站来寻找答案,但我仍然有点不确定如何在其数据库结构和实现中规划类似的系统。
在 PHP 和 MySQL 中,很明显,一些成就是立即获得的(当采取专门行动时,在这种情况下:填写所有个人资料字段),尽管我知道 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 个论坛帖子的用户就不会减慢任何功能。
那么它会是另一个可以增量的徽章表,还是只是上面的 badages_user 表中的“进度”字段?
感谢您的阅读,请关注所需系统的可扩展性(例如数千个用户和 20 到 40 个徽章)。
编辑:为了消除一些混乱,我将分配的时间作为日期/时间,授予徽章的标准最好放置在每个徽章准备好的查询/函数中,不是吗? (更好的灵活性)
I have been browsing this site for the answer but I'm still a little unsure how to plan a similar system in its database structure and implementation.
In PHP and MySQL it would be clear that some achievements are earned immediately (when a specialized action is taken, in SO case: Filled out all profile fields), although I know SO updates and assigns badges after a certain amount of time. With so many users & badges wouldn't this create performance problems (in terms of scale: high number of both users & badges).
So the database structure I assume would something as simple as:
Badges | Badges_User | User
----------------------------------------------
bd_id | bd_id | user_id
bd_name | user_id | etc
bd_desc | assigned(bool) |
| assigned_at |
But as some people have said it would be better to have an incremental style approach so a user who has 1,000,000 forum posts wont slow any function down.
Would it then be another table for badges that could be incremental or just a 'progress' field in the badges_user table above?
Thanks for reading and please focus on the scalability of the desired system (like SO thousands of users and 20 to 40 badges).
EDIT: to some iron out some confusion I had assigned_at as a Date/Time, the criteria for awarding the badge would be best placed inside prepared queries/functions for each badge wouldn't it? (better flexibility)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为您建议的结构(根据评论没有“分配”字段)可以工作,添加一个附加表,例如“Submissions_User”,其中包含对 user_id 和 user_id 的引用。用于计算提交数量的递增字段。那么您所需要的只是一个“事件侦听器”,按照这篇文章我想你已经准备好了。
编辑:对于成就徽章,在每次提交时运行事件侦听器(当然仅适用于进行提交的用户),并当场授予任何相关徽章。对于基于时间的徽章,我每晚都会运行一个 CRON 作业。循环浏览一次完整的用户列表并根据情况授予徽章。
I think the structure you've suggested (without the "assigned" field as per the comments) would work, with the addition of an additional table, say "Submissions_User", containing a reference to user_id & an incrementing field for counting submissions. Then all you'd need is an "event listener" as per this post and methinks you'd be set.
EDIT: For the achievement badges, run the event listener upon each submission (only for the user making the submission of course), and award any relevant badge on the spot. For the time-based badges, I would run a CRON job each night. Loop through the complete user list once and award badges as applicable.
关于您包含的草图:删除 badages_user 上的布尔列。那里没有任何意义:该关系是根据谓词“用户 user_id 在signed_at 获得徽章 bd_id”来定义的。
至于您的总体问题:将模式定义为关系型,而不首先考虑速度(这将使您摆脱一半潜在的性能问题,可能会换取不同的性能问题),正确索引它(正确的取决于查询模式),然后如果它很慢,则从中派生出一个(仍然是相关的)设计,它会更快。就像您可能需要预先计算一些聚合等。
regarding the sketch you included: get rid of the boolean column on badges_user. it makes no sense there: that relation is defined in terms of the predicate "user user_id earned the badge bd_id at assigned_at".
as for your overall question: define the schema to be relational without regard for speed first (that'll get you rid of half of potential perf. problems, possibly in exchange for different perf. problems), index it properly (what's proper depends on the query patterns), then if it's slow, derive a (still relational) design from that that's faster. like you may need to have some aggregates precomputed, etc.
我会保留与您所拥有的类似的类型结构
,然后根据您想要跟踪的内容和@什么详细级别添加跟踪表...然后您可以相应地更新表并将其上的触发器设置为“奖励”徽章
您还可以从另一个方向跟踪统计数据并触发徽章奖励
Some other good points are made here
I would keep a similar type structure to what you have
And then add tracking table(s) depending on what you want to track and @ what detail level... then you can update the table accordingly and set triggers on it to "award" the badges
You can also track stats from the other direction too and trigger badge awards
Some other good points are made here
我认为这是适合使用多对多表 (Badges_User) 的情况之一。
但需要进行一些小改动,以便不存储未分配的徽章。
我假设
signed_at
是日期和/或时间。默认情况下,用户没有徽章。
这样,仅存储实际授予的徽章。
仅当用户获得徽章时才会创建 Badges_User 行。
问候
西格斯特德
I think this is one of those cases where your many-to-many table (Badges_User) is appropriate.
But with a small alteration so that unassigned badges isn't stored.
I assume
assigned_at
is a date and/or time.Default is that the user does not have the badges.
This way only badges actually awarded is stored.
A Badges_User row is only created when a user gets a badge.
Regards
Sigersted