Datenbank-Architektur für „Badge“ System & Frei wählbare Kriterien (MySQL / PHP)

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

  •  20-08-2019
  •  | 
  •  

Frage

Quickie-Frage:

Um es zusammenzufassen, ich bin ein wenig verwirrt, wie ich eine solche Datenbank entwerfen würde, die Schaffung unbestimmte Abzeichen-Regel erlaubt, ohne dass strukturelle Änderungen an den zuvor vorhandenen Benutzer-Tabellen in der Datenbank.

Speicher Badge Titel, Kriterien usw. Was die Tabelle aussehen würde?

  • badge_id (1)
  • badge_title (10K-Abzeichen)
  • badge_image (10k.jpg)
  • badge_criteria ([Beiträge]> = 10000)
    ...

Winded-Frage:

würde Ich mag ein Abzeichen-System auf meinen eigenen persönlichen Projekten implementieren, aber einen Rat suche, wie würde man so etwas am besten tun. Ich habe einige der Fragen hier über Abzeichen-Systeme zu lesen, aber nicht die Datenbank-Architektur immer viel Aufmerksamkeit sehen.

Abzeichen, die auf Benutzer-Punkte (Hypothetische „10k Badge“) basieren würde ziemlich geradlinig zu sein scheinen. Jedes Ereignis, das den Benutzer Ruf beeinflusst (upvotes, downvotes, Antwort akzeptierte, usw.) würde eine Methode aufrufen, um den Benutzer neuen Ruf zu überprüfen und verleihen möglicherweise ein Abzeichen.

Das System klingt ziemlich geradlinig, aber was das wie für den Administrator als Datenbank sieht die unzählige Mengen von Abzeichen mit wenig Aufwand auf dem Weg schaffen will - von denen einige auf verschiedenen Kriterien basieren, und nicht der Benutzer einfach Ruf.

User-Ruf ist wahrscheinlich ein Wert innerhalb des Benutzer-Datensatz selbst. Aber im Idealfall würde nicht wollen, um zu vermeiden, neue Felder der Benutzertabelle hinzuzufügen, wenn Sie neue Abzeichen erstellen? Zum Beispiel der „Edited 100 Entries“ badge - würden Sie eine neue Spalte nicht schaffen „entries_edited“ innerhalb der Benutzertabelle, würden Sie? Und dann erhöht, dass nach jedem Eintrag bearbeitet ...

Für Hinweise?

Stackoverflow-Archiv:


Hinweis: Ich bin nicht zu fragen, wie Abzeichen mit den Benutzern zuordnen. Ich frage nicht, wie zu vergeben Abzeichen (das programmatisch durchgeführt wird)

War es hilfreich?

Lösung

Da die Abzeichen Kriterien beliebig komplex sein können, ich glaube nicht, dass Sie es in einer Datenbanktabelle in „einfachen“ Datenelemente aufgeschlüsselt speichern können. Der Versuch, eine „Rules Engine“ zu schreiben, die beliebig komplexe Kriterien umgehen kann wird Sie auf dem Weg der im Grunde nehmen alle Werkzeuge neu zu schreiben, die Sie in Ihrer Programmiersprache haben.

Wenn Sie im Voraus wissen möchten, dass Sie die begrenzte Abzeichen nur bestimmte Felder (das heißt Abzeichen werden nur basierend off Ruf oder die Anzahl der Bearbeitungen oder etwas), dann können Sie diese in einer einfachen Tabelle speichern wie:

ReputationBadgeCriteria
  BadgeId
  BadgeName
  MinReputation

Alternativ können Sie eine Art von DSL benutzen, um Ihre „Regeln“ zu schreiben, aber Sie am Ende zu auch einen Parser zu erstellen, um die Regeln zu analysieren, wenn man sie auch etwas lesen Sie diese Regeln auszuführen. Je nach Komplexität in Ihrem DSL wollen, kann dies keine triviale Aufgabe sein. Dies sieht aus wie der Pfad, den Sie in Ihrer Frage gehen, um mit mit einer Spalte Kriterien (vermutlich Klartext), das so etwas wie „[Reputation]> 1000“ oder „[Beiträge]> 5“ in sich hat. Sie müssen noch analysieren und diese Regeln auszuführen und die Komplexität etwas zu schreiben, so zu tun, hängt davon ab, wie komplex Sie wollen diese Regeln sein.

Ich würde empfehlen, lesen Sie diese Täglich WTF Artikel für Informationen darüber, warum dieser Ansatz zu Schmerzen führt.

Andere Tipps

Je nachdem, wie weit Sie mit ihm zu gehen, kann Ihr Schema ziemlich kompliziert werden. Es scheint mir, dass die Basiselemente, die Sie brauchen, um zu verfolgen sind:

Badges awarded
Points earned

Ganz einfach so weit, aber Sie wollen in der Lage sein, dynamisch neue Abzeichen und neue Punkte Kategorien zu erstellen. Abzeichen Auszeichnungen würde davon abhängen, Punkte in einer oder mehreren Punktkategorien zu verdienen, die zu einem bestimmten Betrag addieren würde. Sie müssen also die Beziehung zwischen Punkt Kategorien verfolgen (und Punkte erhalten) und Abzeichen:

Point categories
Badge categories

So ist der Schlüssel Benutzerpunktetabelle sein würde, die verbinden würde Kategorien zu verweisen, die Abzeichen verknüpfen. Benutzer Punkte sammeln, in einer bestimmten Kategorie, die zu sammeln Sie Punkte auf einem oder mehr Abzeichen beitragen würde.

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

Ihre „admin“ Schnittstelle erlauben würde jemand ein neues Abzeichen zu schaffen und die Punktkategorien erforderlich ist, um zu verdienen, dass Abzeichen (point_groups) wählen. Jedes Mal, wenn ein Benutzer Punkte (user_points) verdient, aktualisieren Sie die user_points Tabelle, dann bestimmen, welche diese Punkte Abzeichen würde (point_groups) könnte dazu beitragen. Sie neu kompilieren dann die Punkte für die Abzeichen, die verdient durch die Punkte betroffen waren und aktualisieren Sie die user_badges Tabelle mit dem point_earned. Dann überprüfen Sie die points_earned Feld in user_badges gegen die required_points in der Abzeichen Tabelle.

Sie können viel schicker erhalten, indem verschiedene Gewichte zu verschiedenen Punkten Kategorien zuweisen oder sogar unterschiedliche Gewichte für Punkt Kategorien für besondere Abzeichen. Aber diese Einrichtung wäre eine unbegrenzte Anzahl von Abzeichen und Punkt Kategorien erlaubt ziemlich einfach erstellt und verwaltet werden, ohne Tabellen Strukturen zu verändern.

Wenn das nicht ganz, was Sie suchen, dann denke ich, dass ich zumindest eine Stimme oder zwei für eine Menge Tipparbeit bekommen sollte.

Sie werden dann noch in Ihre Unique User in einer Tabelle und einzigartige Abzeichen verfolgen eine Querverweis-Tabelle erstellen, sie zu beziehen.

Ein Benutzer kann viele Abzeichen haben und ein Abzeichen können viele Benutzer haben.

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
)

Statistik, die beeinflussen könnte, ob ein Benutzer ein Abzeichen verdient wird als Teil der Verwaltung der Website verfolgt. so etwas wie eine Antwort akzeptiert würde in einem Schema, die Fragen & Antworten bezieht. um die Antwort und den Besitzer der Antwort angezeigt werden, es würde eine Beziehung zu der Benutzertabelle und Trigger, der gemacht wurde Abzeichen Bedingungen, wenn eine Änderung überprüfen würde.

  

Ich frage nicht, wie zu vergeben Abzeichen.   Ich frage, wie speichern Kriterien in der Datenbank.

Sie wollen also die logische Operation speichern erforderlich, um zu bestimmen, ob ein Abzeichen in einem Feld verdient wird irgendwo?

ich glaube, mit dem anderen Plakate einigen, die Kriterien, die ein Teil der Geschäftslogik sein sollten. Diese Logik kann auf der Seite oder innerhalb app ein Auslöser sein. Ich denke, das ist eine Frage des Stils.

Wenn Sie wirklich auf die Idee verheiratet waren in einem Feld, die Kriterien zu speichern, würde ich speichern Sie es als parametrisierte SQL und führen Sie es dynamisch.

So so etwas in Ihren Kriterien Feld sein würde:

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

Ich würde nicht einen Zuwachs für das Bearbeitungs Abzeichen erstellen. Ich denke, Sie sollten einen Job haben, die im Hintergrund laufen und count (), um die numbero der Post für die Mitglieder bearbeitet, die noch nicht das Abzeichen der Bearbeitung hat. Wenn Sie sehen, dass die Zählung über den Bereich ist, dass Sie möchten, fügen Sie einen Eintrag in der Datenbank, die sagen, dass der Benutzer das Abzeichen haben.

Ich denke, es geht um das gleiche für andere Abzeichen. Versuchen Sie, die Anzahl des writting zu begrenzen und nicht schreiben, direkt die Zählung der Abzeichens Informationen in der Benutzertabelle. Verwenden Sie eine Tabelle, die Abzeichen Informationen enthalten und verknüpfen es mit der Benutzertabelle.

Ich entschuldige mich kurz für zu sein.

Um ein System wie diese umzusetzen, könnte ich eine Tabelle erstellen, die entweder gespeicherte Prozedur Namen oder tatsächliche Abfragen speichern, die verwendet werden würden, um zu bestimmen, ob ein bestimmte Benutzer ein Abzeichen verdient.

badge_criteria
badge_key int
badge_criteria varchar(max)

Sie können die Abfragen für Abzeichen extrahieren und auszuführen, die der Benutzer von Ihrem mittleren Ebene nicht verdient hat, aber Sie würden keine Code oder strukturelle Änderungen vornehmen müssen neue Abzeichen hinzufügen geht nach vorn.

ich es so bin nähern: Erstellen Sie eine Tabelle, die alle Abzeichen zu speichern und haben eine Spalte eine Funktion verweisen, wenn das Abzeichen verliehen, um zu sehen ausgeführt wird. So ist der Tisch bleibt einfach und die Logik, um die Abzeichen zu bestimmen, in dem Code gehalten werden, wo sie am besten geeignet ist.

Mit dieser Methode Abzeichen Anforderungen könnten auch miteinander verknüpft werden, komplexere Abhängigkeiten zu bilden. Zum Beispiel, Benutzer müssen drei separate, spezifische Abzeichen w / in einem bestimmten Zeitraum, um dieses Badge zu erhalten erhalten.

Das wird fast unmöglich sein, in der Datenbank zu tun - die Vergabe von Abzeichen sollten in Ihrer Business-Logik in der Anwendung erfolgen. Auf diese Weise haben Sie alle vorhandenen Daten benötigen Sie (Änderungen, Besuche, Ruf, etc.) und kann behandelt werden, wie Sie für richtig halten.

Update:

Wenn Sie nach den Kriterien Sie Regeln bedeuten, die bestimmen, ob und wie das Abzeichen vergeben wird, dann ist das nicht etwas, das in der Datenbank gespeichert werden soll. Dies wäre fast unmöglich, zu testen und zu erhalten.

Wenn Sie meinen, zum Beispiel die „Anzahl der Änderungen“ zu speichern, gibt es keine Möglichkeit, dass die Daten immer um eine Tabelle oder eine gespeicherte Prozedur zu modifizieren einschließen, wenn Sie es brauchen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top