Estou tentando encontrar uma abordagem para um projeto, onde um usuário pode editar registros e poder ver versões anteriores desses registros. Aqui está um esquema de exemplo simplificado, usando uma lista:
TABLE list (
id int auto_increment primary key,
user_id int,
title varchar(255)
);
TABLE list_tasks (
id int auto_increment primary key,
list_id int,
title varchar(255),
order int,
is_complete tinyint
);
Para que um usuário possa entrar e fazer várias edições na lista (por exemplo, adicionar ou remover tarefas, reordenar tarefas, marcar algumas como concluídas, renomear outras, etc.), salve-as. Nesse momento, gostaria de gerar uma 'versão 2' da lista e das tarefas e permitir que elas visualizassem versões anteriores, mas, quando acessam a lista, sempre obtêm a versão mais recente.
Existe um padrão comum de abordagem / design para lidar com dados de versionamento dessa maneira em um banco de dados MySQL?
mysql
versioning
GSto
fonte
fonte
Respostas:
É muito comum querer fazer isso em um banco de dados. Embora você esteja dando uma guinada nisso, você deseja acompanhar uma revisão de uma lista de itens.
Uma maneira de fazer isso pode ser alterar a estrutura, como
Quando o usuário salvar sua lista, crie uma nova revisão na
revisions
tabela acima e atribua esse valor aos itens da listalist_tasks
e, em seguida, ao ID da revisãolists
para marcar esse ID como a revisão 'atual'. Quando o usuário editar os itens, não edite os itens existentes. Em vez disso, insira novos com um novo ID de revisão e atualize alist
tabela com essa revisão para marcá-la como a atual.Em seguida, para listar os itens atuais, liste os itens do ID da revisão atual especificado na
lists
tabela. Para procurar versões anteriores, você pode obter uma lista de revisões anteriores das listas na tabela de revisões e, em seguida, listar os itens individuais com base nesse ID.fonte
Esta solução usa uma tabela de auditoria separada. Tem prós e contras. Você pode preferir eliminar os registros antigos da sua tabela principal. A melhoria de desempenho pode ser insignificante.
Adicione os seguintes campos a cada tabela auditada:
Você precisará atualizar esses campos sempre que os dados forem alterados. O CurrentVersion é incrementado em 1 (poderia ser usado como uma maneira de bloquear um registro, mas essa é outra questão). IsDeleted fornece uma "exclusão reversível" para que possa ser referenciada no futuro.
Tabelas de auditoria separadas Cada tabela deve ter uma versão _Archive ou _History correspondente da tabela. Provavelmente, eles não precisam ser indexados da mesma maneira. Obviamente, um único campo de chave primária não se aplicará. Você deve conseguir criar uma chave composta fora do campo ID e UpdateDateTime.
Usando um gatilho (Isso abordará as alterações feitas dentro ou fora do seu código. Você pode decidir se isso funciona para a sua situação.) Ou outra codificação, quando um registro é anexado, atualizado ou excluído, uma cópia do registro é colocada no arquivo morto. / tabela de histórico. Todas as versões e outros campos de auditoria são mantidos. Isso informará o que os usuários fizeram e quando. A tabela pode ser comparada consigo mesma para ver quando um registro foi alterado ou para ver tendências.
Vi esse trabalho bem nos últimos anos. Eu gostaria de ouvir sobre as desvantagens que posso não estar considerando.
fonte
Eu sugiro que você leia este artigo bem detalhado.
https://blog.jondh.me.uk/2011/11/relational-database-versioning-strategies/comment-page-1/#comment-373850
Outra abordagem é ter uma coluna version_id na sua tabela e um sinalizador 'current' que especifique qual linha é a atual. Cada vez que você precisar de uma atualização, poderá inserir uma nova linha e definir o sinalizador 'atual' da versão existente como 0 / false e a linha recém-adicionada como 1.
Dessa forma, você pode criar uma exibição mostrando apenas aqueles com o conjunto de sinalizadores atual.
fonte