Datenbankstruktur für 2v2-Spiel

10

Ich spiele regelmäßig ein 2-gegen-2-Spiel mit 12 Freunden und möchte eine Datenbank, in der Spieler, Teams, Ergebnisse und Spiele erfasst werden, um ein Rangsystem zu erstellen.

Da wir regelmäßig Teams ändern Ich habe mit Tischen kommen players, teamsund gameswo die Spiele zwei Teams haben (team1 und team2) und die Teams aus zwei Spielern (Spieler1 und player2).

Dies verursacht einige Probleme - wenn ich zum Beispiel zwei Spieler auswähle (nennen wir sie A und B ), um zusammen zu spielen, muss ich überprüfen, ob es bereits ein Team gibt, in dem Spieler1 A und Spieler2 B oder Spieler1 B und Spieler2 ist ist ein.

Die Spalten gamesund winssind sowohl in der playersTabelle als auch in der teamsTabelle vorhanden - aber das liegt daran, dass ich sehen möchte, wie viele Spiele von den Spielern gewonnen werden, aber auch, wie kompatibel der Spieler in verschiedenen Teams ist (wie oft ein Spieler gewinnt, wenn er sich zusammenschließt ein anderer bestimmter Spieler).

  1. Rangliste (ich werde wahrscheinlich das Elo-Bewertungssystem verwenden )
  2. Eine Statistikseite für jeden Spieler mit Bewertungen, Gewinnen, Spielen, Statistiken der letzten Spiele und den Spielern, mit denen er am besten kompatibel ist.

Ich vermute sehr, dass ein Großteil davon gegen einige der Prinzipien der Datenbanknormalisierung verstößt, und ich würde gerne einige Vorschläge zur Implementierung meines Datenbankdesigns erhalten.

Datenbank Design

Daniel
quelle
Ich denke, das ist eine sehr gute Frage. Würde gerne Ihre aktuelle DB-Struktur in der Frage grafisch sehen. Nicht jeder kennt Laravels Schema Builder. Anwendungsfälle könnten auch besser ausgearbeitet werden, damit wir Ihre tatsächlichen Bedürfnisse verstehen.
candied_orange
Vielen Dank @CandiedOrange - Ich habe das DB-Strukturdiagramm hinzugefügt und werde weitere Anwendungsfälle hinzufügen :)
Daniel
Schönes Update. Wäre es richtig anzunehmen, dass jeder Spieler jeweils nur in einer Mannschaft und jeweils nur in einem Spiel spielt? Auch, dass Spieler alte Teams verlassen und zu ihnen zurückkehren, ohne die Informationen für dieses Team zurückzusetzen?
candied_orange
@CandiedOrange Wenn wir ein Spiel spielen möchten, finden wir im Grunde 4 Spieler (von insgesamt ~ 12 Spielern) und schließen sie zufällig in 2er-Teams zusammen.
Daniel
Ich kann nicht sagen, ob das ein Ja oder Nein war. Ich versuche zu verstehen, wie sich die Zeit auf Ihr Design auswirkt.
candied_orange

Antworten:

2

Es gibt zwei Probleme, die ich bei Ihrem aktuellen Schema sehe: Zum einen müssen zwei Felder in einer Tabelle überprüft werden, um festzustellen, ob ein zusammengesetzter Schlüssel tatsächlich ein Duplikat ist, und einige aggregierte Daten werden zur getrennten Ausführung in die einzelnen Tabellen zusammengefasst Entitäten (gewinnt insbesondere, aber möglicherweise auch die Bewertung eines Spielers).

In der ersten Ausgabe gibt es keine In-DB-Tricks, mit denen Sie jedes Feld eines zusammengesetzten Schlüssels so behandeln können, wie Sie es möchten. Wenn Ihre DB dies jedoch unterstützt, können Sie eine Funktion getPlayerTeams(player_id)zum Einkapseln erstellen die Abfrage.

(Sie können auch eine Ansicht mit dem team_thumbprint erstellen, der als Hash der sortierten Spieler-IDs berechnet wird, sodass jede Kombination derselben zwei Personen immer zum gleichen Fingerabdruck führt, aber das kann hier etwas viel sein).

Bei der Normalisierung sollten Sie Entitäten von den Ergebnissen trennen, die auftreten, indem Sie eine team_resultTabelle verwenden, um alle Ergebnisse für ein bestimmtes Team zu verfolgen. Eine etwas extremere Normalisierung würde auch einen player_rating_histTisch erfordern, der alle Bewertungsänderungen für einen Spieler enthält. Ihre aktuelle Bewertung ist einfach die mit dem letzten Datum. Eine Player-Ansicht kann auch verwendet werden, um den neuesten Wert für eine einfache Abfrage zu enthalten.

Vorgeschlagenes Schema (leider kein Diagramm):

player
    id
    name
    created_on
    updated_on

player_rating_hist
    player_id (FK)
    rating
    rating_date

team
    id
    player1_id (FK)
    player2_id (FK)
    created_on
    updated_on

game
    id
    team1_id (FK)
    team2_id (FK)

team_game
    team_id (FK)
    game_id (FK)
    result
    score
    rating_change

team_rating_hist
    team_id (FK)
    rating
    rating_date

Fragen:

--Results for the game, should only ever be two rows for any given game
SELECT * FROM team_game WHERE game_id = 101

--All results for a team
SELECT * FROM team_game WHERE team_id = 123456 

Diese Struktur ermöglicht es, "Basis" -Entitäten (Spieler und Teams) von den "Inhalten" zu trennen, die aufgrund des Systemlaufs im Laufe der Zeit entstehen, und bedeutet, dass Sie eine der Basistabellen nicht ständig mit der aktuellen Bewertung # aktualisieren. von Gewinnen usw. Dies sind abgeleitete Werte und sollten abgerufen werden, indem die neueste Bewertung, die durchschnittliche Bewertung, die COUNTGewinne oder Verluste usw. abgerufen werden . Wenn das System groß genug ist, können Sie in Betracht ziehen, solche aggregierten Daten in ein separates "Lager" zu extrahieren. (auch wenn es sich nur um einen separaten Satz von Tabellen in derselben Datenbank handelte) zur einfacheren Analyse.

Dan1701
quelle