首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“徽章”系统的数据库体系结构&任意标准(MySQL/PHP)

“徽章”系统的数据库体系结构&任意标准(MySQL/PHP)
EN

Stack Overflow用户
提问于 2009-06-26 13:44:31
回答 7查看 7.9K关注 0票数 50

快速提问:

总之,我有点困惑如何设计这样一个数据库,允许不确定地创建徽章规则,而不需要对数据库中以前存在的用户表进行结构更改。

存储徽章的标题、标准等。那张表会是什么样子?

  • badge_id (1)
  • badge_title (10K徽章)
  • badge_image (10k.jpg)
  • badge_criteria (posts >= 10000) ...

气喘吁吁-问题:

我想在我自己的个人项目上实施一个徽章系统,但我想寻求一些关于如何最好地做这样一件事的建议。我在这里读过一些关于徽章系统的问题,但是没有看到数据库体系结构得到太多的关注。

基于用户点的徽章(假设的"10k徽章“)看起来很直接。任何影响用户声誉的事件(向上、否决、回答-接受等)都会调用一种方法来检查用户的新声誉,并可能授予一个徽章。

这个系统听起来很直截了当,但是作为一个管理员的数据库,它是什么样子的呢?管理员想要在这条路上创建无数的徽章--其中有些可能基于不同的标准,而不仅仅是用户的声誉。

用户声誉很可能是用户记录本身中的一个值。但是理想情况下,当您创建新的徽章时,您不想避免向用户表中添加新的字段吗?例如,“编辑100个条目”徽章-您不会在“用户表”中创建一个新列"entries_edited“,是吗?然后在每个条目编辑后加起来.

有什么暗示吗?

Stackoverflow档案馆:

注意:我不是在问如何将徽章与用户联系起来。我不是在问如何颁发徽章(这将以编程方式完成)。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2009-06-26 14:17:47

考虑到徽章标准可以是任意复杂的,我认为您无法将其存储在一个数据库表中,将其分解为“简单”的数据元素。试图编写一个能够处理任意复杂条件的“规则引擎”,这将使您在编程语言中基本上重写所有的工具。

如果您事先知道,您希望这些徽章仅限于特定字段(即徽章只基于声誉或编辑的数量),那么您可以将这些标记存储在一个简单的表中,如:

代码语言:javascript
复制
ReputationBadgeCriteria
  BadgeId
  BadgeName
  MinReputation

或者,您可以使用某种DSL来编写您的“规则”,但是当您读取规则以及执行这些规则时,您还必须创建一个解析器来解析规则。根据DSL中所需的复杂性,这可能不是一项琐碎的任务。这看起来像您在问题中使用的路径,其中有一个标准列(大概是纯文本),其中包含“信誉> 1000”或“帖子> 5”之类的内容。您仍然需要解析和执行这些规则,编写这些规则的复杂性取决于您希望这些规则有多复杂。

我建议您阅读这些每日WTF 文章,了解为什么这种方法会导致疼痛。

票数 23
EN

Stack Overflow用户

发布于 2009-06-26 15:12:29

取决于您想要在其中走多远,您的模式可能变得相当复杂。在我看来,您需要跟踪的基本元素是:

代码语言:javascript
复制
Badges awarded
Points earned

到目前为止非常简单,但是您希望能够动态地创建新的徽章和新的点数类别。徽章奖励将取决于在一个或多个积分类别中获得的点数,这些点数加起来将达到一定的数额。因此,您需要跟踪点数类别(以及所获得的分数)与徽章之间的关系:

代码语言:javascript
复制
Point categories
Badge categories

因此,关键是您的用户点数表,它将链接到点类别,哪个链接到徽章。用户在特定类别中获得积分,这将有助于获得一个或多个徽章的积分。

代码语言:javascript
复制
badges:
badge_id
badge_name
required_points
....

point_categories:
point_id
category_name
weighting (optional)
...

point_groups:
badge_id
point_id
weighting (optional)
...

user_points:
user_id
point_id
points
...

user_badges:
user_id
badge_id
points_earned
badge_awarded (yes/no)
...

您的“管理”界面将允许某人创建一个新的徽章,并选择需要哪个点类别才能获得该徽章(point_groups)。每当用户获得积分( user_points )时,您都会更新user_points表,然后确定这些分数可以用于哪些标记(point_groups)。然后,重新编译受所挣点数影响的徽章的点数,并使用user_badges更新point_earned表。然后,根据徽章表中的points_earned字段检查user_badges中的required_points字段。

您可以通过为不同的点类别分配不同的权重,甚至为特定的徽章的点数类别分配不同的权重,从而获得更多的乐趣。但是,这种设置将允许在不改变表结构的情况下很容易地创建和管理无限数量的徽章和点数类别。

如果这不是你想要的,那么我认为我至少应该得到一两张选票,因为我需要大量打字。

票数 23
EN

Stack Overflow用户

发布于 2009-06-26 13:49:47

您可以在一个表中跟踪您的唯一用户,在另一个表中跟踪唯一的标记,然后创建一个交叉参考表来关联它们。

一个用户可以有许多徽章,一个徽章可以有许多用户。

代码语言:javascript
复制
create table users (
id int,
name varchar
)

create table badges (
id int,
badge_name varchar
)


create table user_badges_xref (
user_id int,
badge_id int
)

作为网站管理的一部分,可能会影响用户是否获得徽章的统计信息会被跟踪。因此,类似于被接受的答案的内容将出现在一个与问题和答案相关的模式中。为了显示答案和答案的所有者,将有一个与用户表和触发器的关系,每当发生更改时,这些触发器将检查是否有徽章条件。

我不是在问怎么颁发徽章。我在问如何在数据库中存储标准。

因此,您想要存储逻辑操作,以确定是否在某个字段中获得了一个徽章?

我认为,我同意另一张海报的观点,即标准应该是业务逻辑的一部分。这个逻辑可以在应用程序端,也可以在触发器内。我觉得这是风格的问题。

如果您真的同意将条件存储在字段中的想法,我会将其存储为参数化SQL并动态运行它。

因此,这类事情将出现在标准字段中:

代码语言:javascript
复制
select "Badge Earned"
from all_posts 
where user_id = @user_id
having count(*) > 10000
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1049233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档