Eu tenho uma users
mesa. Quero acompanhar todas as alterações que fiz, nome, telefone etc. Pensei em criar uma tabela extra changes
que armazenará a id
versão anterior e a próxima do usuário. Eu mantenho todos os users
registros. Será esta uma boa abordagem?
Atualizar
Também pensei em usar uma tabela separada para o histórico, veja abaixo
Ou, para usar uma única tabela e rastrear sua versão do timestamp
ou do id
(já que é incremento), mas considero isso uma solução ruim.
Seu projeto tem uma grande desvantagem: obter apenas os valores atuais (com os quais você trabalhará na maior parte do tempo) é uma operação cara que requer uma junção.
Seu sistema ficaria muito mais rápido se você tivesse uma tabela com os dados atuais e uma tabela extra para informações históricas, composta por todas as colunas de
users
e umavalid_until
coluna timestamp, com chave primária sobre (user_id
,valid_until
).Uma questão que você não informou é a frequência de mudanças nos diversos atributos (colunas) que o objeto USER (table users) possui.
Suponha que você tenha uma tabela temporal com P colunas, das quais apenas K, onde K é muito menor que P, geralmente estão sujeitas a alterações. Então ter tudo na mesma tabela ou ter apenas duas tabelas (registros atuais, registros históricos) irá gerar mais novos registros do que seria necessário.
Seria possível dividir os atributos em tabelas diferentes e ter pelo menos duas colunas temporais (transaction_validfrom,transaction_validto)?
Tenho que admitir que algumas junções seriam necessárias para combinar colunas de tabelas diferentes em uma linha, mas geralmente as tabelas com atributos divididos são menores, então você ganha em E/S.
Assumindo... .você não precisa versionar mais de uma tabela .você não precisa consultar a tabela por data
você pode criar uma tabela primária e uma tabela de detalhes. a tabela primária armazenará os IDs dos usuários e a tabela de detalhes do usuário armazenará todas as informações. A abordagem que estou mostrando abaixo torna-se entediante rapidamente para grandes esquemas e muito entediante para muitos para muitos relacionamentos.
Para usar esta abordagem de banco de dados, em inserções, ou seja, novo usuário, um usuário e detalhes do usuário são criados. Para atualizar um usuário, você cria um novo userDetail. Para consultar uma entidade de usuário, você obtém o userDetail mais recente para um determinado userId.
Se o detalhe do usuário tiver uma entidade de endereço que também precise estar sob controle de versão, você também precisará adicionar uma tabela primária e detalhada para a entidade de endereço. Essa abordagem fornece muitas tabelas. Estou executando uma versão modificada disso, na qual o detalhe do usuário tem start_date e end_date que são atualizados para que eu possa consultar facilmente quais registros estavam na data x. (Estou executando um banco de dados muito pequeno) para grandes bancos de dados de alto desempenho, essa é provavelmente uma ideia horrível.
veja o wiki para validade temporal para um pouco mais de visão sobre o que você pode estar tentando fazer.
aqui está um exemplo de histórico de dados enlouquecido usando esta abordagem
Resumindo, eu recomendaria essa abordagem se usada com moderação. Eu sou meio noob, então vou colocar um aviso de que um noob recomenda essa abordagem como aceitável. Deixe-me saber se você precisar de algum esclarecimento.