Pensei em uma estrutura de banco de dados incomum e me pergunto se alguém já viu isso em uso antes. É basicamente usando 2 bancos de dados:
- O primeiro banco de dados retém apenas os dados atualmente válidos
- O segundo banco de dados mantém o histórico de tudo que já foi inserido, atualizado ou excluído no primeiro banco de dados
Cenário
Estou trabalhando em um projeto no qual sou obrigado a registrar tudo o que acontece e onde os dados são alterados com frequência.
Exemplo (não o real)
Você precisa fazer o design do banco de dados para uma liga de futebol. Nesta liga existem jogadores e equipes. Os jogadores geralmente trocam de time.
- Primeiro requisito : O banco de dados deve conter as informações necessárias para jogar a próxima partida. Isso significa uma lista de todos os jogadores, equipes e em qual equipe cada jogador está atualmente.
- Segundo requisito : O banco de dados deve conter valores históricos que usaremos para gerar estatísticas. Isso significa a lista de todos os jogadores que fizeram parte de um time ou a lista de todos os times dos quais um jogador fez parte.
O problema
Esses dois requisitos são meio opostos um ao outro. Eu tentei fazer tudo no mesmo banco de dados, mas não faz sentido. O primeiro requisito se preocupa apenas em "jogar a próxima partida", enquanto o segundo requisito se preocupa apenas em "gerar estatísticas".
Para fazer tudo no mesmo banco de dados, fui com uma espécie de banco de dados "apenas inserção" usando a óbvia exclusão macia para excluir / atualizar informações ...
O que inicialmente parecia uma tarefa fácil, mantendo uma lista de jogadores, equipes e a equipe atual de cada jogador, de repente se torna muito mais difícil. A lógica do aplicativo necessária para executar a próxima partida já é bastante complicada, mas agora o banco de dados tem um design muito inútil, no qual o aplicativo é obrigado a adicionar a verificação "é excluída" em cada consulta apenas para executar a próxima partida.
Você gostaria de ser o treinador que grita "todos os jogadores do time, venham até mim" e depois 2000 jogadores vêm até você. Nesse ponto, você provavelmente gritará "todos os jogadores que não foram excluídos do time, venham até mim" (enquanto juram sobre esse design estúpido).
Minha conclusão
Eu me perguntei por que você precisa colocar tudo no mesmo banco de dados. A exclusão reversível não apenas faz um trabalho ruim no registro de tudo, a menos que você adicione muitas colunas (time_created, who_created_it, time_deleted, who_deleted_it), mas também complica tudo. Isso complica o design do banco de dados e o design do aplicativo.
Além disso, recebo esses 2 requisitos como parte de um único aplicativo que não pode ser dividido, mas fico pensando: são dois aplicativos completamente distintos. Por que estou tentando fazer tudo juntos.
Foi quando pensei em dividir o banco de dados em dois. Um banco de dados operacional usado apenas para executar a próxima partida e conter apenas as informações atualmente válidas e um banco de dados histórico que contém todas as informações que já existiram, quando foram criadas, excluídas e quem as fez.
O objetivo é manter o primeiro banco de dados (operacional) e o aplicativo o mais simples possível, mantendo o máximo de informações possível no segundo banco de dados (histórico).
Questões
- Você já viu esse design antes? Tem nome?
- Há alguma armadilha óbvia que estou perdendo?
EDIT 2015-03-16
Arquitetura atual
Você pode basicamente pensar em toda a arquitetura como um processo de 2 etapas.
Passo 1 :
- O aplicativo está sendo executado e os usuários estão executando algumas ações
- Cada vez que um evento acontece, ele é gravado automaticamente (solução de auditoria) em uma tabela de eventos
- Em seguida, a linha correta, no banco de dados operacional, é atualizada
Passo 2 :
- Um trabalho lê a inserção mais recente na tabela de eventos e insere esses novos dados no banco de dados histórico.
- Os usuários consultam o banco de dados histórico para recuperar as informações necessárias.
Apenas na tabela de eventos, você pode reconstruir as informações para qualquer ponto no tempo. O problema é que essa tabela de eventos não é facilmente consultável. É aqui que o banco de dados histórico entra em ação; apresentar os dados de maneira que seja fácil recuperar exatamente o que queremos.
Problemas adicionais ao colocar tudo nas mesmas tabelas
Eu já expressei minha preocupação com a complexidade adicional de verificar "é excluído" em cada consulta. Mas há outra questão: integridade .
Faço uso pesado de chave estrangeira e restrição para garantir que, a qualquer momento, os dados que estão no meu banco de dados sejam válidos.
Vejamos um exemplo:
Restrição: Só pode haver um goleiro por equipe.
É fácil adicionar um índice único que verifique se existe apenas um goleiro por equipe. Mas então o que acontece quando você muda o goleiro? Você ainda precisa preservar as informações sobre a anterior, mas agora você tem 2 goleiros nas mesmas equipes, uma ativa e outra inativa, o que contradiz sua restrição.
Claro que é fácil adicionar uma verificação à sua restrição, mas é outra coisa para gerenciar e pensar.