Por Que Manter o Histórico
Auditoria, desfazer ações e análises do passado.
Por Que Manter o Histórico é uma aula grátis de SQL Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de SQL Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de SQL Academy inclui 4 aulas no total.
O problema de sobrescrever
Toda vez que você executa um UPDATE ou DELETE, os dados antigos desaparecem para sempre. Isso parece eficiente, mas cria problemas reais: você não consegue responder a perguntas como qual era o preço na última terça-feira? ou quem alterou este registro e quando?
Manter o histórico significa armazenar cada versão de uma linha, não apenas a mais recente. Nesta lição, você explorará por que isso é importante e como o SQL ajuda a fazer isso.
Três motivos para manter o histórico
Há três motivos clássicos para preservar dados históricos em um banco de dados:
1. Auditoria — provar que uma alteração ocorreu, quem a fez e quando.
2. Desfazer — reverter um erro sem restaurar o banco de dados inteiro.
3. Análise — responder a perguntas sobre o passado, identificar tendências e comparar períodos.
Uma estratégia de histórico bem projetada atende às três necessidades sem duplicar uma quantidade excessiva de dados.
Uma tabela de auditoria simples
A abordagem mais simples é uma tabela de auditoria separada que registra cada alteração. Cada linha captura o valor antigo, o novo valor, quem fez a alteração e quando.
Abaixo está uma tabela de auditoria para uma tabela products. A coluna operation armazena INSERT, UPDATE ou DELETE.
CREATE TABLE products_audit (
audit_id SERIAL PRIMARY KEY,
product_id INT NOT NULL,
operation VARCHAR(6) NOT NULL, -- INSERT / UPDATE / DELETE
old_price NUMERIC(10,2),
new_price NUMERIC(10,2),
changed_by TEXT NOT NULL,
changed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);Preenchendo a tabela de auditoria
Você pode gravar em uma tabela de auditoria manualmente, mas a abordagem mais confiável é um gatilho de banco de dados que seja acionado automaticamente sempre que os dados mudarem. Assim, nenhum código da aplicação consegue ignorar o registro.
Aqui, inserimos uma linha de auditoria diretamente para ilustrar a estrutura antes de abordar os gatilhos.
INSERT INTO products_audit (product_id, operation, old_price, new_price, changed_by)
VALUES (42, 'UPDATE', 9.99, 12.49, 'alice');
SELECT * FROM products_audit ORDER BY changed_at DESC LIMIT 5;Lendo a trilha de auditoria
Depois que as linhas se acumulam na tabela de auditoria, você pode consultá-las para responder a perguntas de auditoria. A consulta abaixo mostra o histórico completo de preços de um único produto, começando pelo mais recente.
SELECT
changed_at,
changed_by,
operation,
old_price,
new_price
FROM products_audit
WHERE product_id = 42
ORDER BY changed_at DESC;Datas de vigência: histórico do tempo de validade
Uma tabela de auditoria registra quando a alteração foi feita (tempo da transação). Às vezes, também é necessário acompanhar quando algo era válido no mundo real — o chamado tempo de validade.
Adicionar as colunas valid_from e valid_to à tabela principal cria um histórico do tempo de validade, às vezes chamado de dimensão de alteração lenta (SCD Tipo 2).
CREATE TABLE employee_history (
id SERIAL PRIMARY KEY,
employee_id INT NOT NULL,
department TEXT NOT NULL,
salary NUMERIC(10,2) NOT NULL,
valid_from DATE NOT NULL,
valid_to DATE -- NULL means current record
);
-- Current record for employee 7
INSERT INTO employee_history (employee_id, department, salary, valid_from)
VALUES (7, 'Engineering', 85000, '2023-01-01');Atualizando um registro de alteração lenta
Quando um funcionário muda de departamento, você não atualiza a linha dele com UPDATE. Em vez disso, encerra a linha antiga definindo valid_to e insere uma nova linha sem data de término. Isso preserva o histórico completo.
-- Step 1: close the current record
UPDATE employee_history
SET valid_to = '2024-06-01'
WHERE employee_id = 7 AND valid_to IS NULL;
-- Step 2: insert the new record
INSERT INTO employee_history (employee_id, department, salary, valid_from)
VALUES (7, 'Product', 90000, '2024-06-01');
-- Verify history
SELECT department, salary, valid_from, valid_to
FROM employee_history
WHERE employee_id = 7
ORDER BY valid_from;Consultando um ponto no tempo
Com colunas de tempo de validade, você pode perguntar o que era válido em uma data específica — uma consulta que seria impossível com um modelo baseado em um UPDATE simples.
A cláusula WHERE verifica se a data desejada está dentro do intervalo de validade da linha.
-- What department and salary did employee 7 have on 2023-09-15?
SELECT department, salary, valid_from, valid_to
FROM employee_history
WHERE employee_id = 7
AND valid_from <= '2023-09-15'
AND (valid_to > '2023-09-15' OR valid_to IS NULL);Tabelas temporais com versionamento do sistema
Bancos de dados SQL modernos (PostgreSQL 16+, SQL Server, MySQL 8) oferecem suporte a tabelas temporais com versionamento do sistema. O banco de dados acompanha automaticamente o tempo da transação em colunas ocultas, e você pode consultar estados anteriores com uma sintaxe especial.
Exemplo do SQL Server — o conceito é o mesmo em todos os mecanismos:
-- SQL Server / MariaDB style (illustrative)
CREATE TABLE orders (
order_id INT PRIMARY KEY,
status VARCHAR(20),
total NUMERIC(10,2),
SysStartTime DATETIME2 GENERATED ALWAYS AS ROW START,
SysEndTime DATETIME2 GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)
) WITH (SYSTEM_VERSIONING = ON);
-- Query historical state
SELECT * FROM orders FOR SYSTEM_TIME AS OF '2024-01-15 12:00:00'
WHERE order_id = 100;Usando o histórico para desfazer alterações
As tabelas de histórico não servem apenas para leitura — você pode usá-las para desfazer erros. Se um trabalho em lote corromper 500 registros de preços, você poderá restaurá-los a partir da tabela de auditoria sem recorrer a uma cópia de segurança.
-- Undo all price changes made by the bad batch job at a specific time
UPDATE products p
SET price = a.old_price
FROM products_audit a
WHERE p.id = a.product_id
AND a.operation = 'UPDATE'
AND a.changed_by = 'batch_job'
AND a.changed_at BETWEEN '2024-03-10 02:00:00' AND '2024-03-10 02:05:00';
-- Confirm affected rows
SELECT COUNT(*) AS rows_restored FROM products_audit
WHERE changed_by = 'batch_job'
AND changed_at BETWEEN '2024-03-10 02:00:00' AND '2024-03-10 02:05:00';Análises ao longo do tempo
Os dados históricos permitem fazer análises de séries temporais. Você pode acompanhar a evolução de uma métrica, comparar valores mês a mês ou detectar anomalias — tudo isso sem recorrer a um armazém de dados separado.
Esta consulta mostra o preço médio de um produto em cada mês do calendário usando a tabela de auditoria.
SELECT
DATE_TRUNC('month', changed_at) AS month,
ROUND(AVG(new_price), 2) AS avg_price
FROM products_audit
WHERE product_id = 42
AND operation IN ('INSERT', 'UPDATE')
GROUP BY 1
ORDER BY 1;Verificação de conhecimentos
Teste sua compreensão sobre o armazenamento de dados históricos em SQL.
Recapitulação: por que manter o histórico
Nesta lição, você aprendeu por que sobrescrever dados é arriscado e como os padrões de SQL preservam o histórico para auditoria, desfazer alterações e análises.
Principais aprendizados:
- Tabelas de auditoria registram cada INSERT, UPDATE e DELETE, informando quem fez a operação e quando.
- Linhas com tempo de validade (SCD Tipo 2) usam as colunas
valid_from/valid_topara registrar cronologias do mundo real. - Consultas referentes a um momento específico respondem a perguntas históricas filtrando essas colunas de data.
- Tabelas temporais com versionamento do sistema automatizam o acompanhamento do tempo das transações no nível do banco de dados.
- Os dados históricos permitem desfazer alterações de forma seletiva e fazer análises avançadas de séries temporais sem precisar de cópias de segurança.
Preservar o passado não é um custo adicional — é a base de sistemas confiáveis e auditáveis.
Perguntas Frequentes
A aula “Por Que Manter o Histórico” é grátis?
Sim — o texto completo de “Por Que Manter o Histórico” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de SQL Academy, atualize para CoddyKit PRO. O curso de SQL Academy inclui 4 aulas no total.
O que vou aprender em “Por Que Manter o Histórico”?
Auditoria, desfazer ações e análises do passado. Você pratica SQL Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar SQL Academy?
Nenhuma experiência prévia é necessária. SQL Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.
Quanto tempo leva a aula “Por Que Manter o Histórico”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de SQL Academy?
Sim. Cada aula de SQL Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Por Que Manter o Histórico
- Tabelas de Eventos Somente para Acréscimo
- Linhas Temporais e Versionadas
- Reconstruindo o Estado a Partir de Eventos