"徽章"系统和任意标准的数据库架构(MySQL/PHP)

Sam*_*son 47 database-design badge

匆匆-问题:

总而言之,我对如何设计这样一个允许无限制徽章规则创建而不需要对数据库中以前存在的用户表进行结构更改的数据库感到困惑.

存储徽章标题,标准等.该表的外观如何?

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

啰嗦,问:

我想在我自己的个人项目中实施徽章系统,但我正在寻求一些关于如何最好地做这样的事情的建议.我一直在阅读有关徽章系统的一些问题,但没有看到数据库架构受到太多关注.

基于用户点的徽章(假设的"10k徽章")看起来非常简单.任何影响用户声誉的事件(upvotes,downvotes,answer-accepted等)都会调用一种方法来审核用户的新声誉,并可能颁发徽章.

该系统听起来非常简单,但对于想要在未来几乎不费力地创建无数徽章的管理员而言,这看起来像是一个数据库 - 其中一些可能基于不同的标准,而不仅仅是用户声誉.

用户信誉可能是用户记录本身的值.但理想情况下,您不希望在创建新徽章时不必在用户表中添加新字段吗?例如"Edited 100 Entries"徽章 - 您不会在用户表中创建新列"entries_edited",不是吗?然后在每个条目编辑后增加...

任何提示?

Stackoverflow存档:


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

Dav*_*her 23

鉴于徽章标准可能是任意复杂的,我认为您不能将其存储在分解为"简单"数据元素的数据库表中.尝试编写一个可以处理任意复杂标准的"规则引擎",将会让您走上基本上重写编程语言中所有工具的道路.

如果你事先知道你想要的徽章只限于某些领域(即徽章仅基于断声誉或编辑或东西的数量),那么你可以存储这些在一个简单的表所示:

ReputationBadgeCriteria
  BadgeId
  BadgeName
  MinReputation
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用某种DSL来编写"规则",但最终还是必须创建一个解析器来解析规则,以及执行这些规则.根据您在DSL中所需的复杂程度,这可能不是一项简单的任务.这看起来就像你在问题中的路径,其中有一个Criteria列(可能是纯文本),其中包含"[Reputation]> 1000"或"[Posts]> 5".您仍然需要解析并执行这些规则,编写某些内容的复杂性取决于您希望这些规则的复杂程度.

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


小智 19

根据您想要使用它的程度,您的架构可能变得非常复杂.在我看来,您需要跟踪的基本元素是:

Badges awarded
Points earned
Run Code Online (Sandbox Code Playgroud)

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

Point categories
Badge categories
Run Code Online (Sandbox Code Playgroud)

所以关键是你的用户点表,它将链接到点类别,链接到徽章.用户可以获得特定类别的积分,这有助于获得一个或多个徽章的积分.

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)
...
Run Code Online (Sandbox Code Playgroud)

您的"管理员"界面允许某人创建新徽章,并选择获得该徽章所需的点类别(point_groups).每当用户获得积分(user_points)时,您更新user_points表,然后确定这些积分可能贡献给哪些徽章(point_groups).然后,您重新编译受所获得的点影响的徽章的点数,并使用point_earned更新user_badges表.然后根据徽章表中的required_points检查user_badges中的points_earned字段.

通过为不同的点类别分配不同的权重,甚至为特定徽章的点类别指定不同的权重,您可以获得更多的体验.但是这种设置允许在不改变表结构的情况下相当容易地创建和管理无限量的徽章和点类别.

如果这完全不是你想要的,那么我认为我应该至少得到一两次投票来进行大量打字.


Bob*_*bst 5

您可以在一个表中跟踪您的唯一用户,在另一个表中跟踪唯一的徽章,然后创建一个交叉引用表来关联它们.

用户可以拥有许多徽章,徽章可以拥有许多用户.

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
)
Run Code Online (Sandbox Code Playgroud)

可能会影响用户是否获得徽章的统计信息会作为网站管理的一部分进行跟踪.所以接受的答案就像是一个与问题和答案相关的模式.为了显示答案和答案的所有者,将与用户表和触发器建立关系,以便在进行更改时检查徽章条件.

我不是问如何颁发徽章.我问的是如何在数据库中存储标准.

因此,您希望存储所需的逻辑操作,以确定徽标是否在某个字段中获得?

我认为同意另一张海报,标准应该是业务逻辑的一部分.该逻辑可以在应用程序端或触发器内.我认为这是一种风格问题.

如果您真的嫁给了将标准存储在字段中的想法,我会将其存储为参数化SQL并动态运行.

所以这种事情将在你的标准领域:

select "Badge Earned"
from all_posts 
where user_id = @user_id
having count(*) > 10000
Run Code Online (Sandbox Code Playgroud)


Tap*_*eak 5

我是这样处理的:创建一个表来存储所有徽章,并让一列引用一个运行以查看是否授予徽章的函数。这样,表格保持简单,确定徽章的逻辑可以保存在代码中,最适合的地方。

使用这种方法,还可以将徽章要求链接在一起,以形成更复杂的依赖关系。例如,用户必须在特定时间范围内收到三个单独的特定徽章才能获得此徽章。