Database
 sql >> Base de Dados >  >> RDS >> Database

O que os Jogos Olímpicos, as partidas de futebol da UEFA Euro 2016 e os bancos de dados têm em comum?




Ao ouvir o que eu faço, as pessoas tendem a me fazer a mesma pergunta:Você pode desenvolver um sistema que preveja os resultados dos jogos de futebol? Ou resultados de medalhas olímpicas? Pessoalmente, não confio muito em previsões. Ainda assim, se tivéssemos uma grande quantidade de dados históricos e indicadores relevantes, certamente poderíamos projetar um sistema para nos ajudar a obter suposições mais precisas. Neste artigo, consideraremos um modelo que pode armazenar os resultados de partidas e torneios.

Esse modelo é focado principalmente em partidas, estatísticas e resultados de futebol europeu, mas pode ser facilmente ajustado para acomodar muitos outros esportes. Minha principal motivação para este artigo foram os dois grandes eventos de futebol deste ano:o Campeonato da UEFA Euro 2016 que acabou de acontecer e os Jogos Olímpicos de 2016 que estão acontecendo agora.

O que sabemos antes do início do torneio?


Antes do início do torneio, sabemos quase tudo sobre ele – exceto o mais importante:quem vai ganhar. Vamos dizer brevemente exatamente o que já sabemos:
  • As datas em que o torneio começa e termina
  • Os locais onde as partidas acontecerão
  • As horas exatas em que as partidas começarão
  • Quais equipes se classificaram para o torneio
  • Os jogadores de cada uma dessas equipes
  • O desempenho passado de cada jogador e sua forma atual

Quais detalhes de correspondência queremos armazenar?


Os torneios consistem em várias partidas. Antes de armazenarmos os detalhes da partida, precisamos:
  • Relacione cada partida com o torneio
  • Registre a fase do torneio quando a partida foi disputada (por exemplo, fase de grupos, semifinais)

Também precisamos armazenar detalhes para partidas individuais, incluindo:
  • As equipes envolvidas na partida
  • Alinhamentos iniciais e substituições
  • Eventos de partidas (no futebol são:gol, pênalti, falta, cartão amarelo etc.)
  • Pontuação final
  • Ações dos jogadores durante a partida

Usaremos esses dados para capturar todos os eventos importantes da partida. Comparar o desempenho de um jogador antes e durante a partida pode levar a certas conclusões. Talvez não pudéssemos prever os resultados finais de seu desempenho (ou seja, uma vitória ou uma derrota), mas as estatísticas certamente poderiam nos ajudar a fazer suposições com um grau de confiabilidade.

Apresentando o modelo





O modelo é dividido em quatro áreas principais:
  • Tournament details
  • Match details
  • Events
  • Indicators and Performance

As tabelas fora dessas áreas são dicionários (sport , phase , position ), catálogos (sport_event , team , player ) e uma única relação muitos-para-muitos (plays ).

Descreveremos primeiro as tabelas não categorizadas e, em seguida, examinaremos cada área de perto.

As tabelas não categorizadas


Essas tabelas são importantes porque as tabelas de todas as quatro áreas as utilizam como dicionários ou catálogos.



O sport table lista todos os esportes que armazenaremos em nosso banco de dados. Provavelmente teremos apenas um esporte aqui, futebol masculino, mas esta tabela nos dá a flexibilidade de adicionar esportes semelhantes (por exemplo, futebol feminino) se necessário.



No sport_event tabela, armazenaremos os eventos relacionados ao(s) nosso(s) esporte(s). Um exemplo seriam os “Jogos Olímpicos de 2016”.



A phase table é um dicionário que contém todas as etapas possíveis do torneio. Ele contém valores como “fase de grupo” , “rodada de 16” , “quartas-de-final” , “semifinais” , “final” .



A team table é, como você deve imaginar, uma lista simples de todas as equipes. Os valores possíveis são “Croácia” , “Polônia” , “EUA” etc. Se usarmos o banco de dados para armazenar informações sobre competições de clubes ou ligas, também teremos valores como “Barcelona” , "Real Madrid" , “Bayern” , “Manchester United” etc.



No player tabela, armazenaremos registros de todos os jogadores pertencentes às equipes relevantes.



O plays table é a nossa única relação muitos-para-muitos e relaciona jogadores e equipas. Um jogador pode pertencer a mais de um time ao mesmo tempo (por exemplo, a seleção nacional e um clube), mas durante um torneio ele obviamente jogará por apenas um time.



Por fim, temos a position tabela. Este dicionário simples irá armazenar uma lista de todas as posições necessárias. No futebol, isso inclui goleiro, meio-campista, atacante, etc.

Detalhes do torneio



Observação: Se você deseja apenas armazenar os resultados de partidas únicas, não precisa usar esta seção.

Um torneio consiste em mais de uma partida; tanto o UEFA Euro 2016 quanto os eventos de futebol nos Jogos Olímpicos de 2016 são torneios. Como dissemos antes, podemos armazenar uma única partida em nosso banco de dados, mas também podemos relacionar as partidas aos respectivos torneios. As mesas na seção Torneio são:

  • tournament – Contém todos os dados básicos do torneio:o esporte, data de início, data de término, etc. Também precisamos armazenar o nome do torneio e uma descrição de onde está ocorrendo. O sport_event_id atributo é opcional porque um torneio não precisa estar associado a um evento maior (como as Olimpíadas).
  • group – Isso lista todos os grupos nesse torneio. O UEFA Euro 2016 teve seis grupos, de A a F.
  • participant – Estas são as equipas que jogam no torneio; cada participante pode ser atribuído a um grupo. A maioria dos torneios começa com uma fase de grupos e depois continua para uma fase eliminatória (por exemplo, UEFA Euro, Copa do Mundo da UEFA, futebol olímpico). Alguns torneios terão apenas uma fase de grupos (por exemplo, ligas nacionais), enquanto outros terão apenas uma fase eliminatória (por exemplo, copas nacionais).
  • in_team – Esta tabela fornece uma relação muitos-para-muitos que armazena informações sobre os jogadores registrados para aquele torneio e suas posições esperadas.
  • tournament_schedule – Na minha opinião, esta é a tabela mais interessante desta seção. A lista de todos os jogos disputados durante este torneio é armazenada aqui. O tournament_id atributo denota a qual torneio cada partida pertence, e o phase_id atributo define a fase durante a qual a partida ocorrerá. Também armazenaremos o local da partida e a hora em que ela começa. Ambos os participantes serão descritos por campos de texto. Quando a fase de grupos terminar, saberemos todos os confrontos da rodada eliminatória. Por exemplo, no início do UEFA Euro 2016, sabíamos que o vencedor do Grupo E (1E) jogaria contra o vice-campeão do Grupo D (2D). Depois que todas as três rodadas da fase de grupos foram disputadas, essa dupla foi Itália x Espanha.

Detalhes da correspondência



Os Match details A área é usada para armazenar dados para correspondências únicas. Usaremos duas tabelas:

  • match – Contém todos os detalhes sobre uma única partida; esta partida pode estar relacionada a um torneio, mas também pode ser um único jogo. Portanto, o tournament_schedule_id atributo é opcional e armazenaremos o sport_id , start_time e location atributos novamente aqui. Se a partida for parte de um torneio, então tournament_schedule_id será atribuído um valor. O team_1_id e team_2_id atributos são referências às equipes envolvidas na partida. O goals_team_1 e goals_team_2 atributos contêm o resultado da partida. Eles são obrigatórios e devem ter "0" como valor padrão para ambos.
  • in_match – Esta tabela é uma lista de todos os jogadores que estão inscritos para aquela partida; os jogadores que não participarem terão um NULL no started_at atributo, enquanto os jogadores que entraram como substitutos terão started_at> 0 . Se um jogador foi substituído, ele terá um ended_at atributo que corresponde ao started_at atributo do jogador que os substituiu. Se o jogador permanecer durante toda a partida, seu ended_at atributo terá o mesmo valor que o end_time atributo.

Eventos de Partida



Esta seção destina-se a armazenar todos os detalhes ou eventos que aconteceram durante o jogo. E as tabelas são:

  • event – Este é um dicionário que lista todos os eventos que queremos armazenar. No futebol, são valores como “falta cometida” , “falta sofrida” , “cartão amarelo” , “cartão vermelho” , “chute livre” , “penalidade” , “meta” , “impedimento” , “substituição” , “jogador expulso da partida” .
  • match_event – Relaciona eventos com a partida. Armazenaremos o event_time bem como informações do jogador relacionadas a esse evento (in_match_id ).
  • related_event – É isso que reúne as informações do evento. Para explicar, vejamos um exemplo quando o Jogador A comete uma falta no Jogador B. Vamos inserir um registro no match_event tabela que indica que o Jogador A cometeu uma falta e outra que indica que o Jogador B sofreu uma falta. Também adicionaremos um registro ao related_event tabela, onde a 'falta cometida' será o pai e a 'falta sofrida' será a criança. Também registraremos os resultados da falta:cartão amarelo, cobrança de falta ou pênalti e talvez um gol.

Indicadores e desempenho



Esta seção deve nos ajudar a analisar jogadores e equipes antes e depois da partida.

O indicator table é um dicionário com um conjunto predefinido de indicadores para cada jogador antes de cada partida. Esses indicadores devem descrever a forma atual do jogador. Esta lista pode conter valores como:“número de gols nas últimas 10 partidas” , “distância média percorrida nas últimas 10 partidas” , “número de defesas do GK nas últimas 10 partidas” .

O performance dicionário é muito semelhante ao indicator , mas o usaremos para armazenar apenas valores relacionados à correspondência única:“distância coberta” , “passes precisos” , etc

O player_indicator e performance_indicator tabelas compartilham uma estrutura quase idêntica:

  • in_match_id – refere-se ao jogador que participa de uma determinada partida
  • indicator_id / performance_id – referencia o indicator ou "dicionários de desempenho
  • value – armazena o valor desse indicador (por exemplo, um jogador percorreu uma distância de 10,72 km)
  • description – contém uma descrição adicional, se necessário
  • O que aconteceu durante a partida?


    Com todos esses dados inseridos, poderíamos obter facilmente detalhes de partidas, eventos e estatísticas para cada partida em nosso banco de dados.

    Essa consulta simples retornaria detalhes básicos para uma próxima correspondência:

    SELECT team_1.`team_name`, team_2.`team_name`, `match`.`start_time`, `match`.`location`
    FROM `match`, `team` AS team_1, `team` AS team_2
    WHERE `match`.`team_1_id` = team_1.`id`
    AND `match`.`team_2_id` = team_2.`id`
    

    Para obter uma lista de todos os eventos ao vivo durante uma determinada partida, usaríamos a consulta abaixo:

    SELECT `event`.`event_name`, `match_event`.`event_time`, `player`.`first_name`, `player`.`last_name`
    FROM `match`, `match_event`, `event`, `in_match`, `player`
    WHERE `match_event`.`match_id` = `match`.`id`
    AND `event`.`id` = `match_event`.`event_id`
    AND `in_match`.`id` = `match_event`.`in_match_id`
    AND `player`.`id` = `in_match`.`player_id`
    AND `match`.`id` = @match
    ORDER BY `match_event`.`event_time` ASC
    

    Existem inúmeras consultas adicionais nas quais posso pensar; é fácil fazer uma análise quando você tem os dados. Se você mediu e armazenou um grande número de indicadores e dados de desempenho do jogador, poderá relacionar esses parâmetros com um resultado final. Eu pessoalmente não acredito em tais previsões; há o fator sorte durante as partidas, além de vários outros fatores que você não pode saber até o início do jogo. Ainda assim, se você tiver um grande conjunto de dados e muitos parâmetros, sua chance de fazer previsões mais precisas aumenta.

    O modelo apresentado neste artigo permite armazenar partidas, detalhes das partidas e um histórico do desempenho de cada jogador. Também podemos definir indicadores de forma para cada jogador antes da partida. Armazenar detalhes suficientes deve nos fornecer mais parâmetros nos quais basear nossas suposições. Não estou dizendo que poderíamos prever o resultado do jogo, mas poderíamos nos divertir com isso.

    Também poderíamos ajustar facilmente esse modelo para armazenar dados para outros esportes. Essas mudanças não devem ser muito complexas. Adicionando um sport_id atributo aos dicionários deve fazer o truque. Ainda assim, acho que seria sensato ter uma nova instância para cada esporte diferente.