Eu e alguns colegas de trabalho entramos em um debate sobre a melhor maneira de armazenar dados históricos. Atualmente, para alguns sistemas, uso uma tabela separada para armazenar dados históricos e mantenho uma tabela original para o registro ativo atual. Então, digamos que eu tenho a tabela FOO. No meu sistema, todos os registros ativos entrarão no FOO e todos os registros históricos entrarão no FOO_Hist. Muitos campos diferentes no FOO podem ser atualizados pelo usuário, por isso quero manter uma conta precisa de tudo atualizado. FOO_Hist contém exatamente os mesmos campos que FOO, com exceção de um HIST_ID de incremento automático. Cada FOO tempo é atualizado, eu executar uma instrução de inserção em FOO_Hist semelhante a: insert into FOO_HIST select * from FOO where id = @id
.
Meu colega de trabalho diz que esse design é ruim porque não devo ter uma cópia exata de uma tabela por motivos históricos e apenas inserir outro registro na tabela ativa com um sinalizador indicando que é para fins históricos.
Existe um padrão para lidar com o armazenamento de dados históricos? Parece-me que não quero bagunçar meus registros ativos com todos os meus registros históricos na mesma tabela, considerando que pode haver mais de um milhão de registros (estou pensando a longo prazo).
Como você ou sua empresa lida com isso?
Estou usando o MS SQL Server 2008, mas gostaria de manter a resposta genérica e arbitrária de qualquer DBMS.
fonte
Não acho que exista uma maneira padrão específica de fazê-lo, mas pensei em lançar um método possível. Trabalho no Oracle e em nossa estrutura interna de aplicativos da web que utiliza XML para armazenar dados de aplicativos.
Usamos algo chamado modelo Master - Detail que, no mais simples, consiste em:
Tabela mestre, por exemplo, chamada
Widgets
frequentemente apenas contendo um ID. Geralmente contém dados que não mudam com o tempo / não são históricos.Tabela Detalhe / Histórico, por exemplo, chamada
Widget_Details
contendo pelo menos:Então, essencialmente, uma entidade começa com 1 linha no mestre e 1 linha nos detalhes. Os detalhes com uma data de término NULL e STATUS_CONTROL de 'C'. Quando uma atualização ocorre, a linha atual é atualizada para ter END_DATETIME do horário atual e status_control é definido como NULL (ou 'A', se preferir). Uma nova linha é criada na tabela de detalhes, ainda vinculada ao mesmo mestre, com status_control 'C', o ID da pessoa que está fazendo a atualização e os novos dados armazenados na coluna XMLDATA.
Essa é a base do nosso modelo histórico. A lógica Criar / Atualizar é tratada em um pacote Oracle PL / SQL, para que você simplesmente transmita a função o ID atual, seu ID de usuário e os novos dados XML e, internamente, faça toda a atualização / inserção de linhas para representar isso no modelo histórico . Os horários de início e de término indicam quando essa linha da tabela está ativa.
O armazenamento é barato, geralmente não EXCLUEM dados e preferimos manter uma trilha de auditoria. Isso nos permite ver como eram os nossos dados a qualquer momento. Ao indexar status_control = 'C' ou usar uma View, a desordem não é exatamente um problema. Obviamente, suas consultas precisam levar em consideração que você sempre deve usar a versão atual (NULL end_datetime e status_control = 'C') de um registro.
fonte
Eu acho que você se aproxima está correto. A tabela histórica deve ser uma cópia da tabela principal sem índices. Verifique também se você possui um registro de data e hora de atualização na tabela.
Se você tentar a outra abordagem em breve, enfrentará problemas:
fonte
No SQL Server 2016 e acima , há um novo recurso chamado Tabelas Temporais que visa solucionar esse desafio com o mínimo esforço do desenvolvedor . O conceito de tabela temporal é semelhante ao Change Data Capture (CDC), com a diferença de que a tabela temporal abstraiu a maioria das coisas que você precisava fazer manualmente se estivesse usando o CDC.
fonte
Alterar a captura de dados: https://docs.microsoft.com/en-us/sql/relational-databases/track-changes/about-change-data-capture-sql-server?view=sql-server-2017
É suportado no SQL Server 2008 R2, pode ter sido suportado no SQL Server 2008.
fonte
essa pergunta é bastante antiga, mas as pessoas ainda estão trabalhando nessa questão. portanto, se você estiver usando o oracle, poderá estar interessado no flashback do oracle: http://docs.oracle.com/cd/B28359_01/appdev.111/b28424/adfns_flashback.htm
fonte
Só queria adicionar uma opção que eu comecei a usar porque eu uso o Azure SQL e a coisa de várias tabelas era muito complicada para mim. Adicionei um gatilho de inserção / atualização / exclusão na minha tabela e converti a alteração antes / depois para json usando o recurso "FOR JSON AUTO".
Isso retorna uma representação JSON para o registro antes / após a alteração. Em seguida, guardo esses valores em uma tabela de histórico com um carimbo de data e hora de quando a alteração ocorreu (também guardo o ID para o registro atual de preocupação). Usando o processo de serialização, posso controlar como os dados são preenchidos no caso de alterações no esquema.
Eu aprendi sobre isso neste link aqui
fonte
Você poderia apenas particionar as tabelas não?
"Estratégias de tabela e índice particionadas usando o SQL Server 2008 Quando uma tabela de banco de dados cresce em tamanho para centenas de gigabytes ou mais, pode ser mais difícil carregar novos dados, remover dados antigos e manter índices. Apenas o tamanho da tabela faz com que essas operações demorem muito mais tempo. Mesmo os dados que devem ser carregados ou removidos podem ser muito dimensionáveis, tornando impraticáveis as operações INSERT e DELETE na tabela. O software de banco de dados Microsoft SQL Server 2008 fornece particionamento de tabela para tornar essas operações mais gerenciáveis. "
fonte
A verdadeira questão é: você precisa usar dados históricos e ativos para relatórios? Nesse caso, mantenha-os em uma tabela, particione e crie uma exibição para que os registros ativos sejam usados em consultas ativas. Se você precisar apenas examiná-los ocasionalmente (para pesquisar questões de conteúdo ou algo do tipo), coloque-as em uma tabela separada.
fonte
JOIN
duas tabelas em alguns relatórios históricos ou é mais difícil modificar cada inserção / atualização / exclusão de uma única tabela para estar ciente de preocupações históricas? Na verdade, um log de auditoria incluiria até os dados atuais na tabela de histórico, portanto, a tabela atual nem deveria ser necessária em um relatório.Outra opção é arquivar os dados operacionais diariamente [a cada hora | a qualquer hora]. A maioria dos mecanismos de banco de dados suporta a extração dos dados em um arquivo morto .
Basicamente, a idéia é criar um trabalho agendado para Windows ou CRON que
Muitos mecanismos de banco de dados SQL vêm com uma ferramenta que pode ser usada para esse fim. Por exemplo, ao usar o MySQL no Linux, o seguinte comando pode ser usado em um trabalho CRON para agendar a extração:
fonte
Conheço este post antigo, mas Só queria acrescentar alguns pontos. O padrão para esses problemas é o que funciona melhor para a situação. é muito importante compreender a necessidade desse armazenamento e o uso potencial dos dados históricos / de auditoria / controle de alterações.
Auditoria (finalidade de segurança) : use uma tabela comum para todas as suas tabelas auditáveis. defina a estrutura para armazenar os campos nome da coluna, antes e depois do valor.
Arquivar / histórico : para casos como rastrear endereço anterior, número de telefone etc. criar uma tabela separada FOO_HIST é melhor se o esquema da tabela de transações ativas não mudar significativamente no futuro (se a tabela de histórico tiver a mesma estrutura). se você antecipar a normalização da tabela, alteração / adição de tipos de dados / remoção de colunas, armazene seus dados históricos no formato xml. defina uma tabela com as seguintes colunas (ID, Data, Versão do Esquema, XMLData). isso manipulará facilmente as alterações de esquema. mas você precisa lidar com o xml e isso pode introduzir um nível de complicação na recuperação de dados.
fonte
Você pode usar o recurso de auditoria do servidor MSSQL. Na versão SQL Server 2012, você encontrará esse recurso em todas as edições:
http://technet.microsoft.com/en-us/library/cc280386.aspx
fonte
Você pode criar vistas materializadas / indexadas na tabela. Com base nos seus requisitos, você pode fazer uma atualização completa ou parcial das visualizações. Por favor, veja isto para criar mview e log. Como criar visualizações materializadas no SQL Server?
fonte