Struttura del database per il gioco 2v2


10

Gioco regolarmente una partita 2v2 con 12 amici e voglio un database per tenere traccia di giocatori, squadre, punteggi e partite, con l'intento di creare un sistema di classificazione.

Dal momento che noi cambiamo regolarmente squadre mi è venuta in mente tavoli players, teamse gamesdove i giochi hanno due squadre (Team1 e Team2) e le squadre composte da due giocatori (Player1 e player2).

Ciò causa alcuni problemi, ad esempio se scelgo due giocatori (chiamiamoli A e B ) per giocare insieme, devo verificare se esiste già una squadra in cui Giocatore1 è A e Giocatore2 è B o Giocatore1 è B e Giocatore2 è un.

Le colonne gamese winssono presenti sia nella playerstabella che nella teamstabella, ma questo è perché voglio vedere sia quante partite vengono vinte dai giocatori, ma anche quanto sia compatibile il giocatore in squadre diverse (con quale frequenza vince un giocatore quando fa squadra un altro giocatore specifico).

  1. Classifica dei punteggi (probabilmente userò il sistema di classificazione Elo )
  2. Una pagina delle statistiche per ogni giocatore con punteggio, vittorie, partite, statistiche sui giochi recenti e con quali giocatori è più compatibile.

Sospetto fortemente che gran parte di questo violi alcuni dei principi della normalizzazione del database e mi piacerebbe avere alcuni suggerimenti su come implementare la progettazione del mio database.

Progettazione di database


Penso che questa sia un'ottima domanda. Mi piacerebbe vedere la tua attuale struttura DB schematizzata nella domanda. Non tutti conoscono lo Schema Builder di Laravel. I casi d'uso potrebbero anche essere migliorati meglio in modo da comprendere i tuoi reali bisogni.
candied_orange,

Grazie mille @CandiedOrange - Ho aggiunto il diagramma della struttura del DB e aggiungerò altri casi d'uso :)
Daniel,

Bel aggiornamento. Sarei corretto nel ritenere che ogni giocatore farà parte di una sola squadra alla volta e in una sola partita alla volta? Inoltre, che i giocatori lasciano e ritornano alle vecchie squadre senza ripristinare le informazioni per quella squadra?
candied_orange,

@CandiedOrange Fondamentalmente quando vogliamo giocare troviamo 4 giocatori (su ~ 12 giocatori in totale) e li uniamo a caso in squadre di 2
Daniel

Non so dire se si trattasse di un sì o di un no. Sto cercando di capire come il tempo influisce sul tuo design.
candied_orange,

Risposte:


2

Ci sono due problemi che vedo con il tuo schema attuale, uno è il problema di dover controllare due campi in una tabella per determinare se una chiave composta è effettivamente un duplicato e, alcuni dati aggregati vengono raggruppati nelle singole tabelle per separarli entità (vince, in particolare, ma potenzialmente anche la valutazione di un giocatore).

Per il primo problema, non ci sono trucchi nel DB per fare in modo che uno / qualunque campo di una chiave composta venga trattato nel modo OR che stai cercando, ma se il tuo DB lo supporta, potresti creare una funzione getPlayerTeams(player_id)da incapsulare la query.

(Potresti anche creare una vista con il team_thumbprint calcolato come un hash degli ID dei giocatori ordinati, in modo che ogni combo delle stesse due persone dia sempre la stessa identificazione personale, ma potrebbe essere un po 'troppo qui).

Per quanto riguarda la normalizzazione, prendere in considerazione la possibilità di separare le entità dai risultati che si verificano utilizzando una team_resulttabella per tenere traccia di tutti i risultati per un determinato team. Una normalizzazione un po 'più estrema richiederebbe anche un player_rating_histtavolo, contenente tutte le variazioni di valutazione per un giocatore. La loro valutazione attuale è semplicemente quella con la data più recente. Una vista giocatore potrebbe anche essere utilizzata per contenere il valore più recente per una facile query.

Schema proposto (scusate nessun diagramma):

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

Interrogazioni:

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

Questa struttura consente di separare entità "base" (giocatori e squadre) dal "contenuto" che si verifica a seguito del funzionamento del sistema nel tempo e significa che non si aggiorna costantemente una delle tabelle di base con la valutazione corrente, # di vittorie, ecc. Questi sono valori derivati ​​e dovrebbero essere recuperati ottenendo il punteggio più recente, il punteggio medio, COUNTdi vittorie o perdite, ecc. Se il sistema è diventato abbastanza grande, potresti prendere in considerazione l'estrazione di tali dati aggregati in un "magazzino" separato (anche se era solo un insieme separato di tabelle nello stesso DB) per un'analisi più semplice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.