Pergunta

Eu tenho um requisito para armazenar todas as versões de uma entidade de uma forma facilmente indexado e queria saber se alguém tem informações sobre o que sistema para uso.

Sem controle de versão do sistema é simplesmente um banco de dados relacional com um por linha, por exemplo, pessoa. Se o estado da pessoa muda essa linha é alterado para refletir isso. Com versões a entrada deve ser atualizado de tal maneira um modo que podemos sempre voltar para uma versão anterior. Se eu pudesse usar um banco de dados temporais isso seria livre e eu seria capaz de perguntar: 'qual é o estado de todas as pessoas a partir de ontem às 2h de estar em Dublin e envelhecido 30'. Infelizmente, não parece haver qualquer amadurecer projetos de código aberto que pode fazer temporal.

Uma maneira realmente desagradável de fazer isso é apenas para inserir uma nova linha por alteração de estado. Isto leva a duplicação, como uma pessoa pode ter muitos campos, mas apenas uma mudança por atualização. Também é então bastante lento para selecionar a versão correta para cada pessoa dado um timestamp.

Em teoria, deveria ser possível usar um banco de dados relacional e um sistema de controle de versão para um banco de dados temporais imitar, mas isso soa muito horrendo.

Então, eu queria saber se alguém tem se deparar com algo semelhante antes e como eles se aproximaram dele?

Atualizar Como sugerido por Aaron aqui está a consulta usamos atualmente (em mysql). É definitivamente lento em nossa mesa com> 200k linhas. (Id = chave da tabela, person_id = id por pessoa, duplicada se a pessoa tem muitas revisões)

selecione o nome de pessoa p onde p.id = (select max (id) de pessoa onde person_id = p.person_id e timestamp <=: timestamp)

Atualizar Parece que a melhor maneira de fazer isso é com um db temporal, mas dado que não há qualquer fonte as abertas lá fora, a próxima melhor método é armazenar uma nova linha per atualização. O único problema é a duplicação de colunas inalteradas e uma consulta lenta.

Foi útil?

Solução

Há duas maneiras de lidar com isso. Ambos assumem que você sempre inserir novas linhas. Em todos os casos, você deve inserir um timestamp (created) que lhe diz quando uma linha foi "modificada".

A primeira abordagem usa um número para contar quantos casos você já tem. A chave primária é a chave objeto mais o número versão. O problema com essa abordagem parece ser que você precisará de um select max(version) fazer uma modificação. Na prática, isso raramente é um problema, uma vez para todas as atualizações do aplicativo, você deve primeiro carregar a versão atual da pessoa, modificá-lo (e incrementar a versão) e, em seguida, inserir a nova linha. Portanto, o problema real é que este projeto faz com que seja difícil de executar atualizações no banco de dados (por exemplo, atribuir uma propriedade para muitos usuários).

A próxima abordagem usa links no banco de dados. Em vez de uma chave composta, você dá a cada objeto uma nova chave e você tem um campo replacedBy que contém a chave da próxima versão. Esta abordagem torna mais simples para encontrar a versão atual (... where replacedBy is NULL). As atualizações são um problema, embora, desde que você deve inserir uma nova linha e atualizar um já existente.

Para resolver isso, você pode adicionar um ponteiro de volta (previousVersion). Dessa forma, você pode inserir as novas linhas e, em seguida, usar o ponteiro de volta para atualizar a versão anterior.

Outras dicas

Aqui está uma (um pouco datado) levantamento da literatura nas bases de dados temporais: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.91.6988&rep=rep1&type=pdf

Eu recomendaria passar um bom tempo sentado com essas referências e / ou Google Scholar para tentar encontrar algumas boas técnicas que se encaixam no seu modelo de dados. Boa sorte!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top