Estructura de base de datos para el juego 2v2

10

Regularmente juego un juego de 2 contra 2 con 12 amigos y quiero una base de datos para hacer un seguimiento de los jugadores, equipos, puntajes y juegos, con la intención de crear un sistema de clasificación.

Ya que regularmente cambiar de equipo que he llegado con mesas players, teamsy gamesdonde los juegos tienen dos equipos (team1 y Team2) y los equipos están formados por dos jugadores (player1 y Player2).

Esto causa bastantes problemas: por ejemplo, si elijo a dos jugadores (llamémoslos A y B ) para jugar juntos, tengo que verificar si ya existe un equipo donde el Jugador1 es A y el Jugador2 es B o el Jugador1 es B y el Jugador2 es un.

Las columnas gamesy winsestán presentes tanto en la playersmesa como en la teamsmesa, pero esto se debe a que quiero ver cuántos juegos ganan los jugadores, pero también qué tan compatible es el jugador en diferentes equipos (con qué frecuencia un jugador gana cuando se asocia con otro jugador específico).

  1. Cuadro de indicadores de clasificación (probablemente usaré el sistema de calificación Elo )
  2. Una página de estadísticas para cada jugador con clasificación, victorias, juegos, estadísticas de juegos recientes y con qué jugadores es más compatible.

Sospecho firmemente que gran parte de esto viola algunos de los principios en la normalización de la base de datos, y me encantaría algunas sugerencias sobre cómo implementar el diseño de mi base de datos.

Diseño de bases de datos

Daniel
fuente
Creo que esta es una muy buena pregunta. Me encantaría ver su estructura de base de datos actual diagramada en la pregunta. No todos conocen el generador de esquemas de Laravel. Los casos de uso también podrían desarrollarse mejor para que comprendamos sus necesidades reales.
candied_orange
Muchas gracias @CandiedOrange: agregué el diagrama de estructura de base de datos y agregaré más casos de uso :)
Daniel
Buena actualización ¿Sería correcto suponer que cada jugador estará en un solo equipo a la vez y en un solo juego a la vez? Además, ¿los jugadores se van y vuelven a los equipos antiguos sin restablecer la información de ese equipo?
candied_orange
@CandiedOrange Básicamente, cuando queremos jugar un juego, encontramos 4 jugadores (de un total de ~ 12 jugadores en total) y los agrupamos al azar en equipos de 2.
Daniel
No puedo decir si eso fue un sí o un no. Estoy tratando de entender cómo el tiempo impacta tu diseño.
candied_orange

Respuestas:

2

Hay dos problemas que veo con su esquema actual, uno es la cuestión de tener que verificar dos campos en una tabla para determinar si una clave compuesta es efectivamente un duplicado y algunos datos agregados se acumulan en las tablas individuales para separarlos. entidades (gana, especialmente, pero también potencialmente la calificación de un jugador).

Para el primer problema, no hay trucos en la base de datos para que cualquiera de los campos de una clave compuesta se trate de la manera OR que está buscando, pero si su base de datos lo admite, puede crear una función getPlayerTeams(player_id)para encapsular la consulta.

(También puede crear una vista con la huella del equipo calculada como un hash de los identificadores de jugador ordenados, de modo que cualquier combinación de las mismas dos personas siempre dé como resultado la misma huella digital, pero eso podría ser un poco demasiado aquí).

En cuanto a la normalización, considere separar las entidades de los resultados que ocurren usando una team_resulttabla para rastrear todos los resultados de un equipo determinado. Una normalización un poco más extrema también requeriría una player_rating_histmesa, que contenga todos los cambios de calificación para un jugador. Su calificación actual es simplemente la que tiene la fecha más reciente. Una vista de jugador también podría usarse para contener el valor más reciente para una consulta fácil.

Esquema propuesto (lo siento, no hay diagrama):

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

Consultas:

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

Esta estructura permite separar las entidades "base" (jugadores y equipos) del "contenido" que se produce como resultado de la ejecución del sistema a lo largo del tiempo, y significa que no está actualizando constantemente una de las tablas base con la calificación actual, # de ganancias, etc. Esos son valores derivados y deben recuperarse obteniendo la calificación más reciente, la calificación promedio, COUNTde ganancias o pérdidas, etc. Si el sistema se hizo lo suficientemente grande, podría considerar extraer dichos datos agregados en un "almacén" separado (incluso si se tratara de un conjunto separado de tablas en el mismo DB) para facilitar el análisis.

Dan1701
fuente