Tabela de histórico do banco de dados / tabela de rastreamento

13

Atualmente, quero estruturar uma tabela de acompanhamento / histórico como esta:

  • PrimaryKey - ID
  • OtherTableId - fk
  • fieldName - nome do campo que seu rastreamento
  • OldValue
  • Novo valor
  • Nome do usuário
  • CreateDateTime

Então, basicamente, eu quero ter uma tabela que rastreie outro histórico de tabelas, armazene o nome da coluna do campo alterado com o valor novo e antigo. Minha pergunta é: alguém pode fazer buracos nisso? Além disso, qual é a maneira mais fácil de garantir que apenas um nome de coluna das tabelas que seu rastreamento seja inserido na coluna fieldName? Atualmente, minhas opções são ter uma enumeração no serviço que estou construindo ou criar outra tabela de status e tornar o fieldName um fk. Alguma ideia melhor?

Editar objetivo: atualmente, existem apenas 2 campos que queremos rastrear. Um campo será mostrado em uma página da web para exibir o histórico, o outro campo será acessado apenas por um departamento e eles terão acesso a uma visualização do banco de dados que poderão consultar. Eles consultariam apenas esse campo para obter informações sobre quem alterou o campo e o que fazer. Essa é a razão pela qual desejamos configurá-lo onde um campo do banco de dados define a coluna da tabela em vez de ter uma cópia exata do histórico de registros da tabela. Queremos apenas dois campos rastreados com as possibilidades de adicionar ou remover campos no futuro.

Obrigado!

user76982
fonte
Você sabe com antecedência quantas tabelas você acompanhará?
Kofi Sarfo
Essa tabela rastreará apenas uma outra tabela; até agora, estamos rastreando apenas essa tabela.
user76982
Portanto, essa abordagem pode ser um exagero. Pior ainda, não será fácil consultar esta tabela com a que está sendo monitorada em conjunto para recriar os dados ao vivo em um determinado momento, se a recriação de um instantâneo tiver algum valor.
Kofi Sarfo
1
Por outro lado, a consulta para ver quais colunas mudam com mais frequência será mais fácil usando a abordagem que você propôs.
Kofi Sarfo
Você pode pesquisar no dba.stackexchange.com ; perguntas semelhantes foram feitas lá e algumas podem ter respostas que você pode usar.
FrustratedWithFormsDesigner

Respostas:

8

Fazendo furos: e se o esquema do banco de dados for alterado no mesmo ponto posteriormente, e o nome de uma coluna for alterado ou a coluna for excluída completamente? Muitos sistemas de banco de dados permitem isso. O que acontecerá com o seu "fieldName" então?

Para integridade dos dados: você deve garantir que todas as operações de atualização ou exclusão atualizem sua tabela de rastreamento com certeza. Isso é melhor realizado por gatilhos que chamam um procedimento armazenado. Você deve garantir que apenas o procedimento armazenado tenha acesso de gravação à sua tabela de rastreamento, para que ninguém mais possa escrever valores incorretos.

Se você pode viver com uma solução específica de fornecedor de banco de dados: a maioria dos sistemas db possui tabelas de sistema em que as informações do esquema (nomes de tabelas, IDs de tabelas, nomes de colunas etc.) são armazenadas. Você pode verificar se é possível definir uma referência de chave estrangeira para essa tabela de sistema. Isso permitiria substituir o nome do campo por um ID do campo, se o banco de dados suportar algo assim.

Na verdade, se você precisar rastrear linhas inteiras da tabela específica, incluindo todas as colunas (e não apenas um pequeno subconjunto das colunas), considere a sugestão de @ sarfeast. Leia este artigo sobre as desvantagens dos modelos nome-valor-par.

Doc Brown
fonte
8

A implementação de auditoria de mudanças (rastreamento de histórico) mais bem-sucedida que eu já vi é menos genérica e muito mais simples. Isso envolve a criação de uma tabela de log de alterações para cada tabela que você deseja monitorar, mantendo nomes de colunas e tipos de dados idênticos (com uma coluna adicional para o registro de data e hora).

O objetivo final, ou seja, o que você gostaria de fazer com os dados auditados ajudará a avaliar a adequação de cada abordagem.

Kofi Sarfo
fonte
Olá Sarfeast, adicionei o objetivo final que quero alcançar. Desculpe por não incluir isso para começar.
user76982
Essa abordagem tem suas desvantagens. Leia aqui: database-programmer.blogspot.co.uk/2008/07/history-tables.html
Tuukka Haapaniemi:
7

Resumindo: você precisa definir o mecanismo de Trilha de Auditoria para as tabelas que deseja acompanhar a alteração de valor.

Tabela de trilha de auditoria única :

Crie uma tabela para registrar o nome da tabela, o nome do campo e as versões antigas e novas dos dados. Para esse método, é comum registrar as versões antiga e nova dos dados e apenas os campos que foram alterados. Para implementar isso em gatilhos, é necessário que exista uma chave primária na tabela ou que apenas linhas únicas sejam atualizadas.

Aqui está um bom post com scripts sobre como alcançá-lo - Criando trilhas de auditoria

Outras referências úteis para procurar:

Yusubov
fonte
O segundo link está ruim agora.
Jeremy Harris
@ cilosis, Obrigado por perceber isso. Ele é atualizado agora :)
Yusubov
3

Convém verificar a documentação do projeto NHibernate Envers para obter idéias.

Basicamente, você tem uma tabela de revisão na qual pode adicionar dados extras, como um carimbo de data / hora ou usuário. Em seguida, cada tabela que você controla obtém uma tabela de auditoria adicional com todas as colunas duplicadas, um fk para a tabela de revisão e o tipo de revisão (adicionar, modificar, excluir). AFAIK, você não gostaria que suas tabelas de auditoria tivessem um FK real para a tabela real, pois isso impediria exclusões.

dotjoe
fonte