Structure de la base de données pour le jeu 2v2

10

Je joue régulièrement à un jeu 2c2 avec 12 amis et je veux une base de données pour garder une trace des joueurs, des équipes, des scores et des jeux, avec l'intention de créer un système de classement.

Depuis que nous changeons régulièrement d'équipe, j'ai créé des tables players, teamset gamesoù les jeux ont deux équipes (équipe1 et équipe2) et les équipes sont composées de deux joueurs (joueur1 et joueur2).

Cela pose pas mal de problèmes - par exemple si je choisis deux joueurs (appelons-les A et B ) pour jouer ensemble, je dois vérifier s'il existe déjà une équipe où Player1 est A et Player2 est B ou Player1 est B et Player2 est un.

Les colonnes gameset winssont présentes à la fois dans le playerstableau et dans le teamstableau - mais c'est parce que je veux voir à la fois le nombre de parties gagnées par les joueurs, mais aussi la compatibilité du joueur dans différentes équipes (la fréquence à laquelle un joueur gagne lorsqu'il est associé à un autre joueur spécifique).

  1. Tableau de bord de classement (je vais probablement utiliser le système de notation Elo )
  2. Une page de statistiques pour chaque joueur avec classement, victoires, jeux, statistiques de jeux récents et avec quels joueurs il est le plus compatible.

Je soupçonne fortement qu'une grande partie de cela viole certains des principes de normalisation de la base de données, et j'aimerais quelques suggestions sur la façon de mettre en œuvre la conception de ma base de données.

Conception de la base de données

Daniel
la source
Je pense que c'est une très bonne question. J'adorerais voir votre structure DB actuelle représentée dans la question. Tout le monde ne connaît pas le générateur de schéma de Laravel. Les cas d'utilisation pourraient également être mieux étoffés afin que nous comprenions vos besoins réels.
candied_orange
Merci beaucoup @CandiedOrange - J'ai ajouté le diagramme de structure DB, et j'ajouterai plus de cas d'utilisation :)
Daniel
Belle mise à jour. Aurais-je raison de supposer que chaque joueur sera sur une seule équipe à la fois et dans un seul match à la fois? De plus, que les joueurs quittent et retournent dans les anciennes équipes sans réinitialiser les informations de cette équipe?
candied_orange
@CandiedOrange Fondamentalement, lorsque nous voulons jouer à un jeu, nous trouvons 4 joueurs (sur les ~ 12 joueurs au total) et les
Daniel
Je ne peux pas dire si c'était oui ou non. J'essaie de comprendre comment le temps influe sur votre conception.
candied_orange

Réponses:

2

Il y a deux problèmes que je vois avec votre schéma actuel, l'un est le problème d'avoir à vérifier deux champs dans une table pour déterminer si une clé composée est effectivement un doublon, et, certaines données agrégées sont regroupées dans les tables individuelles pour être séparées entités (gagne, en particulier, mais aussi potentiellement la cote d'un joueur).

Pour le premier problème, il n'y a pas d'astuces dans la base de données pour que l'un ou l'autre champ d'une clé composée soit traité de la manière OU que vous recherchez, mais si votre base de données la prend en charge, vous pouvez créer une fonction getPlayerTeams(player_id)pour encapsuler la requête.

(Vous pouvez également créer une vue avec le team_thumbprint calculé comme un hachage des identifiants des joueurs triés, de sorte que tout combo des deux mêmes personnes entraîne toujours la même empreinte numérique, mais cela pourrait être un peu beaucoup ici).

En ce qui concerne la normalisation, envisagez de séparer les entités des résultats qui se produisent en utilisant un team_resulttableau pour suivre tous les résultats pour une équipe donnée. Une normalisation un peu plus extrême nécessiterait également une player_rating_histtable, contenant tous les changements de classement pour un joueur. Leur note actuelle est simplement celle avec la date la plus récente. Une vue de joueur peut également être utilisée pour contenir la valeur la plus récente pour une interrogation facile.

Schéma proposé (désolé pas de diagramme):

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

Requêtes:

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

Cette structure permet de séparer les entités «de base» (joueurs et équipes) du «contenu» résultant du fonctionnement du système au fil du temps, et signifie que vous ne mettez pas constamment à jour l'une des tables de base avec la note actuelle, # de gains, etc. Ce sont des valeurs dérivées et devraient être récupérées en obtenant la note la plus récente, la note moyenne, COUNTdes gains ou des pertes, etc. (même s'il ne s'agissait que d'un ensemble de tables distinct dans la même base de données) pour une analyse plus facile.

Dan1701
la source