Architecture de base de données pour les critères système et arbitraires « Badge » (MySQL / PHP)

StackOverflow https://stackoverflow.com/questions/1049233

  •  20-08-2019
  •  | 
  •  

Question

Quickie-Question:

Pour résumer, je suis un peu confus quant à la façon dont je concevoir une telle base de données qui permet la création indéfinie règle badge sans exiger des changements structurels dans les tables-utilisateur existant précédemment dans la base de données.

Stockage Titre Badge, critères, etc. Qu'est-ce que ce tableau ressemble?

  • badge_id (1)
  • badge_title (Badge 10K)
  • badge_image (10k.jpg)
  • badge_criteria ([messages]> = 10000)
    ...

Winded-Question:

Je voudrais mettre en place un système de badge sur mes propres projets personnels, mais je cherche un peu de conseils à la façon dont on pourrait mieux faire une telle chose. J'ai lu quelques-unes des questions ici sur BADGE-systèmes, mais ne vois pas la base de données architecture obtenir beaucoup d'attention.

Badges qui sont basés sur des points-utilisateur (Hypothétique « 10k Badge ») semble assez simple. Tout événement qui affecte la réputation des utilisateurs (upvotes, downvotes, réponse acceptée, etc.) invoquerait une méthode pour examiner la nouvelle réputation des utilisateurs, et d'attribuer éventuellement un badge.

Ce système semble assez simple, mais qu'est-ce qui ressemble à une base de données pour l'administrateur qui veut créer d'innombrables quantités de badges avec peu d'effort sur la route - dont certains peuvent être fondée sur des critères différents, et non simplement la réputation de l'utilisateur.

utilisateur réputation est probablement une valeur dans le dossier de l'utilisateur lui-même. Mais idéalement, ne vous voulez éviter d'avoir à ajouter de nouveaux champs à la table utilisateur lors de la création de nouveaux badges? Par exemple, le « Edité 100 entrées » badge - vous pas créer une nouvelle colonne « entries_edited » dans les utilisateurs de table, vous? Et puis incrémenter après chaque modification d'entrée de ...

Les conseils?

Stackoverflow Archive:


Note: Je ne demande pas comment associer badges avec les utilisateurs. Je ne demande pas comment les badges d'attribution (qui sera effectuée par programme)

Était-ce utile?

La solution

Étant donné que les critères de badge peuvent être arbitrairement complexes, je ne pense pas que vous pouvez stocker dans une table de base de données réparties en éléments de données « simples ». Essayer d'écrire un « moteur de règles » qui peut gérer des critères complexes de façon arbitraire va vous emmener sur le chemin de réécrivant essentiellement tous les outils que vous avez dans votre langage de programmation.

Si vous savez à l'avance que vous voulez que les badges limités à seulement certains domaines (à savoir les badges ne sont basés hors réputation ou le nombre de modifications ou quelque chose), alors vous pouvez stocker ces données dans une table simple comme:

ReputationBadgeCriteria
  BadgeId
  BadgeName
  MinReputation

Vous pouvez utiliser une sorte de DSL pour écrire vos « règles », mais vous finissez par avoir à créer également un analyseur pour analyser les règles quand vous les lisez, ainsi que quelque chose à exécuter ces règles. En fonction de la complexité que vous voulez dans votre DSL, ce ne peut pas être une tâche triviale. Cela ressemble le chemin que vous allez dans votre question d'avoir une colonne de critères (texte sans doute clair) qui a quelque chose comme « [Réputation]> 1000 » ou « [Messages]> 5 » en elle. Il vous reste à analyser et d'exécuter ces règles et la complexité de l'écriture quelque chose à faire dépend de la complexité que vous voulez que ces règles soient.

Je vous recommande de lire ces Daily WTF articles pour plus d'informations sur les raisons de cette approche conduit à la douleur.

Autres conseils

Selon jusqu'où vous voulez aller avec elle, votre schéma peut être assez compliqué. Il me semble que les éléments de base dont vous avez besoin pour suivre sont:

Badges awarded
Points earned

Assez simple à ce jour, mais vous voulez être en mesure de créer dynamiquement de nouveaux badges et de nouveaux points catégories. prix Badge dépendraient de gagner des points dans une ou plusieurs catégories de points qui ajouteraient jusqu'à un certain montant. Donc, vous devez suivre la relation entre les catégories de points (et points gagnés) et badges:

Point categories
Badge categories

Donc, la clé serait votre table de points d'utilisateur, qui relierait au point des catégories qui pointent vers des badges. Les utilisateurs gagnent des points dans une catégorie particulière, ce qui contribuerait à gagner des points vers un ou plusieurs badges.

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

Votre interface « admin » permettrait à quelqu'un de créer un nouveau badge et choisir les catégories points sont requis pour gagner cet insigne (point_groups). Chaque fois qu'un utilisateur gagne des points (user_points), vous mettez à jour la table user_points, déterminer alors quels insignes ces points seraient pourrait contribuer à (point_groups). Vous recompiler alors les points pour les badges qui ont été touchés par les points gagnés et mettre à jour la table user_badges avec le point_earned. Ensuite, vérifiez le champ points_earned à user_badges contre les required_points dans la table des badges.

Vous pouvez obtenir beaucoup plus chics en attribuant des poids différents aux différentes catégories de points, ou même des poids différents pour les catégories de points pour badges particuliers. Mais cette configuration permettrait à un nombre illimité de badges et catégories de points à créer et gérer assez facilement sans changer les structures de tableaux.

Si tel est complètement pas ce que vous cherchez, je pense que je devrais au moins obtenir un vote ou deux pour beaucoup de taper.

Vous souhaitez suivre vos utilisateurs uniques dans une table et des badges uniques dans un autre, puis créer une table de références croisées pour les relier.

Un utilisateur peut avoir plusieurs badges et un badge peut avoir de nombreux utilisateurs.

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
)

Les statistiques qui pourraient affecter si un utilisateur gagne un badge sont suivis comme une partie de l'administration du site. donc quelque chose comme une réponse être acceptée serait dans un schéma que les questions et réponses se rapporte. afin d'afficher la réponse et le propriétaire de la réponse, il y aurait une relation à la table d'utilisateur et les déclencheurs qui vérifierait les conditions de badge à chaque fois qu'un changement a été effectué.

  

Je ne demande pas comment badges prix.   Je demande comment stocker des critères au sein de la base de données.

Donc, vous voulez stocker l'opération logique nécessaire pour déterminer si un badge est gagné dans un champ quelque part?

Je pense que d'accord avec l'autre affiche que les critères devraient être une partie de la logique métier. Cette logique peut être du côté de l'application ou dans un déclencheur. Je pense que ce une question de style.

Si vous étiez vraiment marié à l'idée de stocker les critères dans un champ, je stocker comme SQL paramétrées et exécuter dynamiquement.

Donc, ce genre de chose serait dans votre champ de critères:

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

Je ne crée pas un incrément pour le badge d'édition. Je pense que vous devriez avoir un travail en cours d'exécution en arrière-plan et compter () le numbero de poste modifié pour les membres qui n'ont pas encore le badge de l'édition. Quand vous voyez que le compte est sur la plage que vous voulez, vous ajoutez une entrée dans la base de données qui indiquent que l'utilisateur a le badge.

Je pense qu'il est la même chose pour d'autres badges. Essayez de limiter le nombre de writting et ne pas écrire directement le compte de l'information badge dans la table utilisateur. Utilisez une table qui contiendra des informations de badge et le lier à la table utilisateur.

Je suis désolé d'être bref.

Pour mettre en œuvre un tel système, je pourrais créer une table qui stocke soit les noms de procédures stockées ou requêtes réelles qui seraient utilisés pour déterminer si un utilisateur particulier a gagné un badge.

badge_criteria
badge_key int
badge_criteria varchar(max)

Vous pouvez extraire et exécuter les requêtes pour les badges que l'utilisateur n'a pas gagné de votre niveau intermédiaire, mais vous n'auriez pas à apporter des modifications de code ou de structure pour ajouter de nouveaux badges aller de l'avant.

Je l'approche comme ceci: Créer une table pour stocker tous les badges, et ont une colonne de référence une fonction exécutée pour voir si le badge est attribué. De cette façon, la table reste simple et la logique pour déterminer les badges peuvent être conservés dans le code, où il est le mieux adapté.

Avec cette méthode, les exigences de badge pourrait également être reliés entre eux pour former des dépendances plus complexes. Par exemple, l'utilisateur doit recevoir trois badges spécifiques, distincts w / dans un certain délai afin d'obtenir ce badge.

Cela va être presque impossible à faire dans la base de données - badges attribution devrait se faire dans votre logique métier de l'application. De cette façon, vous avez toutes les données existantes dont vous avez besoin (modifications, visites, réputation, etc.) et il peut être traité comme bon vous semble.

Mise à jour:

Si selon les critères que vous voulez dire des règles qui déterminent si et comment le badge est attribué, alors ce n'est pas quelque chose qui devrait être stocké dans la base de données. Ce serait presque impossible de tester et maintenir.

Si vous voulez dire, par exemple, le stockage du « nombre de modifications », il n'y a aucun moyen de se modifier autour d'une table ou une procédure stockée afin d'inclure ces données si vous en avez besoin.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top