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

匆匆-问题:

总而言之,我对于如何devise这样的数据库有点困惑,该数据库允许无限制地创build徽章规则,而不需要对数据库中先前存在的用户表进行结构性的改变。

存储徽章标题,标准等等这个表是什么样的?

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

啰嗦,问:

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

基于用户点的徽章(假设的“10k徽章”)看起来非常简单。 任何影响用户声誉的事件(upvotes,downvotes,answer-accepted等)都会调用一个方法来检查用户的新声望,并且可能授予一个徽章。

这个系统听起来非常直截了当,但是对于那些希望通过一点努力就能创造无数徽章的pipe理员来说,这看起来像一个数据库,其中一些可能基于不同的标准,而不仅仅是用户声誉。

用户信誉可能是用户logging本身的一个值。 但理想情况下,当你创build新的徽章时,是否不想避免为用户表添加新的字段? 例如“Edited 100 Entries”徽章 – 你不会在用户表中创build一个新的列“entries_edited”,你会吗? 然后在每个条目编辑之后增加…

任何提示?

Stackoverflow存档:

  • 存储徽章标准的最佳方法 (不是重复的)
  • devise一个徽章系统:在哪里发射商业逻辑?

注意:我不问如何将徽章与用户关联。 我不是问如何奖励徽章(这将以编程方式完成)

鉴于徽章标准可以是任意复杂的,我不认为你可以将其存储在分解成“简单”数据元素的数据库表中。 试图编写一个可以处理任意复杂标准的“规则引擎”,将会使你基本上重写你编程语言中所有的工具。

如果你事先知道你想要的徽章只限于某些领域(即徽章只基于声誉或编辑数量或某物),那么你可以将它们存储在一个简单的表格中,如:

 ReputationBadgeCriteria BadgeId BadgeName MinReputation 

或者,你可以使用某种DSL来编写你的“规则”,但是最终你还得创build一个parsing器来parsing这些规则,当你阅读它们以及执行这些规则的时候。 根据DSL所需的复杂性,这可能不是一件小事。 这看起来像是你的问题所在的标准列(大概是纯文本),其中有“[声誉]> 1000”或“[post]> 5”的path。 你仍然必须parsing和执行这些规则,写这样做的复杂性取决于你想要这些规则的复杂程度。

我会build议你阅读这些每日跆拳道文章 ,了解为什么这种方法导致痛苦的信息。

根据你想要走多远,你的模式可能会变得非常复杂。 在我看来,你需要跟踪的基本元素是:

 Badges awarded Points earned 

到目前为止很简单,但你想能够dynamic地创build新的徽章和新的点类别。 徽章奖励将取决于一个或多个点类别中的赚取点数,这些点数将加起来达到一定数量。 所以你需要跟踪点类别(和点数)和徽章之间的关系:

 Point categories Badge categories 

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

 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) ... 

你的“pipe理员”界面将允许有人创build一个新的徽章,并select要获得徽章(point_groups)所需的点类别。 每当用户获得积分(user_points),就更新user_points表,然后确定这些积分可能对哪些标记有贡献(point_groups)。 然后重新编译受到积分影响的徽章的积分,并使用point_earned更新user_badges表。 然后检查用户标签中的points_earned字段是否符合徽章表中的required_points。

您可以通过为不同的点类别分配不同的权重,甚至为特定的徽章的点类别设定不同的权重,从而获得更多的发明。 但是这个设置将允许无限量的徽章和点类别被创build和pipe理,而不用改变表格结构。

如果这完全不是你正在寻找的东西,那么我认为我应该至less得到一两票才能进行大量的打字工作。

您可以在一个表格中追踪唯一的用户,在另一个表格中追踪唯一的徽章,然后创build一个交叉引用表格来将它们关联。

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

 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 ) 

可能影响用户是否获得徽章的统计信息将作为网站pipe理的一部分进行跟踪。 所以接受答案的东西就是一个涉及问题和答案的模式。 为了显示答案和答案的所有者,将会有一个与用户表和触发器的关系,以便在发生变化时检查徽章条件。

我不是问如何奖章。 我在问如何在数据库中存储标准。

所以你想存储所需的逻辑操作,以确定徽章是否在某个领域获得?

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

如果你真的想把标准存储在一个字段中,我会把它作为参数化的SQL存储起来,并dynamic地运行它。

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

 select "Badge Earned" from all_posts where user_id = @user_id having count(*) > 10000 

我不会创build编辑徽章的增量。 我认为你应该有一个工作在后台运行,并count()编辑职位的编号没有徽章的编辑呢。 当您看到计数超出您想要的范围时,您在数据库中添加一个条目,告诉用户有徽章。

我认为其他徽章也差不多。 尝试限制写入数量,不要直接在用户表中写入徽章信息的数量。 使用将包含徽章信息并将其链接到用户表的表。

我为简短而道歉。

为了实现这样的系统,我可以创build一个表来存储存储过程名称或实际查询,这些名称将用于确定特定用户是否获得了徽章。

 badge_criteria badge_key int badge_criteria varchar(max) 

您可以提取并执行用户没有从中间层获得的徽章查询,但是您不必进行任何代码或结构更改以添加新的徽章。

我正在接近它:创build一个表来存储所有的徽章,并有一个列引用一个function,运行,看看是否颁发徽章。 这样,表格很简单,确定徽章的逻辑可以保存在最合适的代码中。

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

这将是几乎不可能在数据库中做 – 授予徽章应该在您的业务逻辑在应用程序内完成。 这样,您就可以获得所需的所有现有数据(编辑,访问,声誉等),并且可以按照您认为合适的方式进行处理。

更新:

如果按照标准,你的意思是决定是否以及如何颁发徽章的规则,那么这不应该存储在数据库中。 这几乎不可能testing和维护。

例如,如果您的意思是存储“编辑次数”,则无法在您需要时修改表或存储过程以包含该数据。