Struttura del database per il gioco 2v2

10

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

Poiché cambiamo regolarmente team, ho creato tabelle players , teams e games in cui i giochi hanno due squadre (squadra1 e squadra2) e le squadre sono composte da due giocatori (giocatore1 e giocatore2).

Questo causa alcuni problemi, ad esempio se prendo due giocatori (chiamiamoli A e B ) per giocare insieme, devo controllare se c'è già Esiste una squadra in cui Player1 è A e Player2 è B o Player1 è B e Player2 è A.

Le colonne games e wins sono presenti sia nella tabella players che in teams - ma questo perché voglio vedere sia il numero di giochi vinti dai giocatori, ma anche quanto sia compatibile il giocatore è in squadre diverse (quante volte un giocatore vince quando si unì con un altro giocatore specifico).

  1. Classifica tabellone (probabilmente userò il sistema di valutazione Elo )
  2. Una pagina di statistiche per ogni giocatore con valutazione, vittorie, giochi, statistiche recenti sui giochi e con quali giocatori è maggiormente compatibile.

Sospetto strongmente che gran parte di questo violi alcuni dei principi nella normalizzazione del database, e mi piacerebbe qualche suggerimento su come implementare la progettazione del mio database.

    
posta Daniel 24.12.2016 - 15:43
fonte

1 risposta

3

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 sono arrotolati nell'individuo tabelle per entità separate (vince, in particolare, ma anche potenzialmente la valutazione di un giocatore).

Per il primo problema, non ci sono trucchi in-DB per far sì che uno qualsiasi dei campi di una chiave composta sia trattato nel modo in cui stai cercando, ma se il tuo DB lo supporta, potresti creare un function getPlayerTeams(player_id) per incapsulare la query.

(Potresti anche creare una vista con team_thumbprint calcolato come hash degli id player ordinati, in modo che qualsiasi combinazione delle stesse due persone abbia sempre la stessa identificazione personale, ma potrebbe essere un po 'troppo qui).

Per quanto riguarda la normalizzazione, considera la possibilità di separare le entità dai risultati che si verificano utilizzando una tabella team_result per tenere traccia di tutti i risultati per un determinato team. Una normalizzazione un po 'più estrema richiederebbe anche una tabella player_rating_hist , contenente tutte le variazioni di rating per un giocatore. La loro valutazione attuale è semplicemente quella con la data più recente. Una visualizzazione giocatore può anche essere utilizzata per contenere il valore più recente per semplificare le query.

Schema proposto (mi dispiace 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

Query:

--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 le 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 l'attuale valutazione, numero di vincite, ecc. Questi sono valori derivati e devono essere recuperati ottenendo la valutazione più recente, il rating medio, il COUNT di vittorie o sconfitte, ecc. Se il sistema diventa 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 semplificare l'analisi.

    
risposta data 29.12.2016 - 20:44
fonte

Leggi altre domande sui tag