48 votes

Architecture de base de données pour "Insigne" du Système et de l'Arbitraire des Critères (MySQL/PHP)

Quickie Question:

Pour résumer, je suis un peu confus quant à la façon dont j'ai fait la conception d'une base de données qui permet à durée indéterminée insigne de la règle de création sans nécessiter de changements structurels à l'utilisateur déjà existant-les tables dans la base de données.

Le stockage de l'Insigne Titre, les Critères, etc. Quel serait ce Tableau ressemble?

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

Poussif Question:

Je souhaite la mise en place d'un badge de système sur mes propres projets personnels, mais suis à la recherche d'un peu de conseils sur la façon dont l'un serait la meilleure façon de faire une telle chose. J'ai lu certaines des questions ici sur badge-systèmes, mais ne pas voir la base de données-architecture d'obtenir beaucoup d'attention.

Les Badges qui sont basées sur l'utilisateur des points (Hypothétique "10k Badge") semble assez simple. Tout événement qui affecte les utilisateurs de la réputation (upvotes, downvotes, réponse acceptée, etc) invoquer une méthode pour examiner les utilisateurs de réputation, et potentiellement d'attribution d'un badge.

Ce système semble assez simple, mais à quoi cela ressemble une base de données pour l'administrateur qui veut créer d'innombrables quantités de badges avec peu d'effort en bas de la route, dont une partie peut être basée sur différents critères, et pas seulement la réputation de l'utilisateur.

Utilisateur-réputation est probablement une valeur à l'intérieur de l'utilisateur-enregistrement lui-même. Mais, idéalement, vous ne voudriez pas pour éviter d'avoir à ajouter de nouveaux champs à la table utilisateur lorsque vous créez de nouveaux badges? Par exemple, le "Édité À 100 Entrées" badge - vous de ne pas créer une nouvelle colonne "entries_edited" dans la Table des Utilisateurs, le feriez-vous? Et puis incrémenter qu'après chaque entrée-édité...

Tous les conseils?

Stackoverflow Archive:


Note: je ne suis PAS demandant comment associer des badges avec les utilisateurs. Je ne suis PAS demandant comment attribution des badges (qui sera effectué par programmation)

23voto

David Archer Points 954

Étant donné que l'insigne de critères peut être arbitrairement complexe, je ne pense pas que vous pouvez les stocker dans une table de base de données décomposées en "simple" éléments de données. Essayer d'écrire un "moteur de règles" qui peut gérer de manière arbitraire des critères complexes va vous prendre vers le bas le chemin de la ré-écriture de tous les outils que vous avez dans votre langage de programmation.

Si vous savez à l'avance que vous souhaitez les badges limitée aux seuls certains champs (c'est à dire les badges sont uniquement basés sur la réputation ou le nombre de modifications ou de quelque chose), alors vous pouvez le stocker dans un tableau simple comme:

ReputationBadgeCriteria
  BadgeId
  BadgeName
  MinReputation

Sinon, vous pouvez utiliser une sorte de DSL pour écrire vos "règles", mais vous finissez par avoir à créer également un analyseur de parser les règles lors de la lecture ainsi que quelque chose à exécuter ces règles. En fonction de la complexité que vous voulez dans votre connexion DSL, ce n'est pas une tâche triviale. Cela ressemble à du chemin que vous allez dans votre question avec les Critères de la colonne (sans doute en texte brut) qui a quelque chose comme "[Réputation] > 1000" ou "[Postes] > 5" en elle. Vous avez encore de l'analyser et de l'exécution de ces règles et de la complexité de l'écriture quelque chose à faire dépend de la façon complexe que vous voulez ces règles.

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

19voto

Brent Baisley Points 320

En fonction de combien vous voulez aller avec elle, votre schéma peut être assez compliqué. Il me semble que les éléments de base que vous devez suivre sont:

Badges awarded
Points earned

Assez simple, mais vous voulez être en mesure de créer dynamiquement de nouveaux badges et de nouveaux points de catégories. Insigne des prix dépendra de gagner des points dans une ou plusieurs point de catégories qui permettrait d'ajouter jusqu'à un certain montant. Si vous avez besoin de suivre la relation entre le point de catégories (et de points gagnés) et des badges:

Point categories
Badge categories

Donc, la clé de l'utilisateur de votre table de points, ce qui permettrait de relier au point de catégories, qui ont un lien vers les badges. Les utilisateurs de gagner des points dans une catégorie particulière, ce qui permettrait de 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 "admin" de l'interface permettent à quelqu'un de créer un nouveau badge et choisir quel point les catégories sont nécessaires pour gagner ce badge (point_groups). Chaque fois qu'un utilisateur gagne des points (user_points), vous mettez à jour le user_points table, puis déterminer les insignes de ces points serait pourrait contribuer à (point_groups). Vous recompilez alors les points pour les badges qui ont été touchés par les points gagnés et mise à jour de la user_badges table avec le point_earned. Ensuite, vérifiez le points_earned champ dans user_badges contre la required_points dans le tableau insignes.

Vous pouvez obtenir beaucoup d'amateur en attribuant des poids différents à différents point de catégories, ou même de différents poids pour point de catégories particulières pour les badges. Mais cette configuration permettrait à un nombre illimité de badges et de point d'catégories à être créé et géré assez facilement, sans modification de tableaux de structures.

Si c'est pas du tout ce que vous cherchez, alors je pense que je devrait au moins obtenir un vote ou deux pour beaucoup de saisie.

5voto

Bob Probst Points 4502

Vous auriez suivi de vos utilisateurs uniques dans un tableau unique et des badges à l'autre alors créer une table de concordance 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
)

Des 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, d'être accepté, serait dans un schéma qui concerne les questions et les réponses. pour afficher la réponse et le propriétaire de la réponse, il y aurait une relation à l'utilisateur de table et les déclencheurs qui permettrait de contrôler pour l'insigne des conditions chaque fois qu'un changement a été fait.

Je ne suis pas demandant comment attribution de badges. Je me demande comment stocker les critères dans la base de données.

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

Je pense d'accord avec les autres affiches que ces critères devraient être une partie de la logique métier. Cette logique peut être sur le côté app ou dans un déclencheur. Je pense que c'est une affaire de style.

Si vous étiez réellement marié à l'idée de stocker les critères dans un champ, j'avais le stocker en tant que SQL paramétrée et l'exécuter de façon dynamique.

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

3voto

Patrick Desjardins Points 51478

Je ne voudrais pas créer un incrément pour l'édition de badge. Je pense que vous devriez avoir un travail en cours d'exécution en arrière-plan et count() la numbero de post édité pour les membres qui n'ont pas l'insigne de l'édition. Quand vous voyez que le comte est sur la plage que vous voulez, vous devez ajouter une entrée dans la base de données qui indiquent que l'utilisateur d'avoir le badge.

Je pense qu'il est le même pour les autres badges. Essayez de limiter le nombre de l'écriture et de ne pas écrire directement le comte de l'insigne de l'information dans la table user. Utiliser une table qui contiendra l'insigne de l'information et de la relier à la table utilisateur.

3voto

Tapefreak Points 490

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

Avec cette méthode, l'insigne exigences pourraient également être liés ensemble pour former des dépendances plus complexe. Par exemple, l'utilisateur doit recevoir trois distinct, spécifique badges w/dans un certain délai pour obtenir ce badge.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X