0Pricing
SQL Academy · Aula

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_to para 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

  1. Por Que Manter o Histórico
  2. Tabelas de Eventos Somente para Acréscimo
  3. Linhas Temporais e Versionadas
  4. Reconstruindo o Estado a Partir de Eventos
← Voltar para SQL Academy