A primeira pergunta deve ser:o que você faria com esses dados? Se você não tiver requisitos comerciais claros, não faça isso.
Eu fiz algo parecido e após 3 anos de execução há cerca de 20% de "dados válidos" e o resto são "versões anteriores". E são 10 milhões + 40 milhões de registros. Nos últimos três anos, tivemos 2 (duas) solicitações para investigar o histórico de alterações e ambas as solicitações foram tolas - registramos o carimbo de hora da alteração do registro e fomos solicitados a verificar se as pessoas trabalhavam horas extras (após as 17h).
Agora, estamos presos a um banco de dados superdimensionado que contém 80% dos dados que ninguém precisa.
EDITAR:
Já que você pediu possíveis soluções, vou descrever o que fizemos. É um pouco diferente da solução que você está considerando.
- Todas as tabelas têm chave primária substituta.
- Todas as chaves primárias são geradas a partir de uma única sequência. Isso funciona bem porque o Oracle pode gerar e armazenar números em cache, portanto, não há problemas de desempenho aqui. Usamos ORM e queríamos que cada objeto na memória (e registro correspondente no banco de dados) tivesse um identificador exclusivo
- Usamos ORM e as informações de mapeamento entre a tabela e a classe do banco de dados estão na forma de atributos.
Registramos todas as alterações em uma única tabela de arquivo com as seguintes colunas:
- id (chave primária substituta)
- marca de hora
- tabela original
- id do registro original
- ID do usuário
- tipo de transação (inserir, atualizar, excluir)
- registrar dados como campo varchar2
- são dados reais na forma de pares de nome de campo/valor.
A coisa funciona assim:
- ORM tem comandos de inserção/atualização e exclusão.
- criamos uma classe base para todos os nossos objetos de negócios que substitui os comandos de inserção/atualização e exclusão
- Os comandos insert/update/delete criam strings na forma de pares fieldname/value usando reflexão. O código procura informações de mapeamento e lê o nome do campo, o valor associado e o tipo de campo. Em seguida, criamos algo semelhante ao JSON (adicionamos algumas modificações). Quando a string representando o estado atual do objeto é criada, ela é inserida na tabela de arquivos.
- quando um objeto novo ou atualizado é salvo na tabela de banco de dados, ele é salvo em sua tabela de destino e ao mesmo tempo inserimos um registro com o valor atual na tabela de arquivo.
- quando o objeto é excluído, nós o excluímos de sua tabela de destino e ao mesmo tempo inserimos um registro na tabela de arquivo que possui o tipo de transação ="DELETE"
Pró:
- não temos tabelas de arquivo para cada tabela no banco de dados. Também não precisamos nos preocupar em atualizar a tabela de arquivos quando o esquema for alterado.
- o arquivo completo é separado dos "dados atuais", portanto, o arquivo não impõe nenhum impacto de desempenho no banco de dados. Colocamos em um tablespace separado em um disco separado e funciona bem.
- criamos 2 formulários para visualizar o arquivo:
- visualizador geral que pode listar a tabela de arquivamento de acordo com o filtro na tabela de arquivamento. Os dados do filtro podem ser inseridos no formulário (período de tempo, usuário, ...). Mostramos cada registro no formulário fieldname/value e cada alteração é codificada por cores. Os usuários podem ver todas as versões de cada registro e podem ver quem e quando fez as alterações.
- visualizador de fatura - este era complexo, mas criamos um formulário que mostra a fatura muito semelhante ao formulário de entrada de fatura original, mas com alguns botões adicionais que podem mostrar diferentes gerações. Foi preciso um esforço considerável para criar este formulário. O formulário foi usado poucas vezes e depois esquecido porque não era necessário no fluxo de trabalho atual.
- código para criar registros de arquivo está localizado em uma única classe C#. Não há necessidade de gatilhos em todas as tabelas do banco de dados.
- o desempenho é muito bom. Nos horários de pico, o sistema é usado por cerca de 700-800 usuários. Este é o aplicativo ASP.Net. Tanto ASP.Net quanto Oracle estão rodando em um dual XEON com 8Gb de RAM.
Contras:
- o formato de arquivo de tabela única é mais difícil de ler do que a solução em que há uma tabela de arquivo para cada uma das tabelas de dados.
- pesquisar no campo não-id na tabela de arquivo é difícil - podemos usar apenas
LIKE
operador na string.
Então, novamente, verifique os requisitos de arquivo . Não é tarefa trivial, mas os ganhos e uso podem ser mínimos.