Auditoria de tabelas com gatilhos
Crie um histórico de auditoria com gatilhos AFTER INSERT/UPDATE/DELETE que gravem em uma tabela audit_log.
Auditoria de tabelas com gatilhos é uma aula grátis de SQL Academy no CoddyKit. Esta é a aula 4 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.
Por que auditar?
Os registros de auditoria respondem a "quem alterou o quê e quando". São necessários para conformidade (HIPAA, SOX, GDPR e investigações do direito ao apagamento) e para perícia operacional.
A tabela de auditoria
Uma tabela central captura todas as alterações:
CREATE TABLE audit_log (
id BIGSERIAL PRIMARY KEY,
ts TIMESTAMPTZ NOT NULL DEFAULT NOW(),
user_name TEXT NOT NULL DEFAULT CURRENT_USER,
table_name TEXT NOT NULL,
action TEXT NOT NULL, -- INSERT, UPDATE, DELETE
row_id TEXT,
old_data JSONB,
new_data JSONB
);A função de gatilho de auditoria
Uma função reutilizável em muitas tabelas:
CREATE OR REPLACE FUNCTION audit_row()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_log (table_name, action, row_id, old_data, new_data)
VALUES (
TG_TABLE_NAME,
TG_OP,
COALESCE(NEW.id::TEXT, OLD.id::TEXT),
CASE WHEN TG_OP IN ('UPDATE','DELETE') THEN to_jsonb(OLD) END,
CASE WHEN TG_OP IN ('INSERT','UPDATE') THEN to_jsonb(NEW) END
);
RETURN COALESCE(NEW, OLD);
END;
$$ LANGUAGE plpgsql;Anexar às tabelas
Acione em AFTER INSERT/UPDATE/DELETE:
CREATE TRIGGER trg_audit_users
AFTER INSERT OR UPDATE OR DELETE ON users
FOR EACH ROW EXECUTE FUNCTION audit_row();to_jsonb(NEW)
O recurso to_jsonb captura a linha inteira de forma genérica — sem código por coluna. Funciona para qualquer tabela que tenha uma coluna id.
Rastreamento do responsável
Se o aplicativo for executado como um único usuário do banco de dados, o usuário atual não será suficiente. Passe o usuário do aplicativo por meio de um GUC de sessão:
-- App sets:
SET LOCAL app.user_id = '42';
-- Trigger reads:
INSERT INTO audit_log (... actor_id ...) VALUES (..., current_setting('app.user_id', true)::BIGINT);Auditoria de colunas específicas
Utilize a cláusula WHEN do gatilho para auditoria seletiva:
CREATE TRIGGER trg_audit_role_change
AFTER UPDATE OF role ON users
FOR EACH ROW WHEN (OLD.role IS DISTINCT FROM NEW.role)
EXECUTE FUNCTION audit_role_change();Tabelas de auditoria por tabela
Alternativa: uma tabela de auditoria para cada tabela real (por exemplo, users_audit) com o mesmo esquema e metadados de auditoria. É mais fácil consultar, mas exige mais DDL para manter.
Auditoria somente de diferenças
Armazene somente as colunas alteradas:
INSERT INTO audit_log (table_name, action, changes)
VALUES (
TG_TABLE_NAME, TG_OP,
(SELECT jsonb_object_agg(key, value)
FROM jsonb_each(to_jsonb(NEW))
WHERE NEW.* IS DISTINCT FROM OLD.* AND to_jsonb(NEW)->key IS DISTINCT FROM to_jsonb(OLD)->key)
);Desempenho da tabela de auditoria
A tabela de auditoria cresce rapidamente em sistemas ocupados. Particione-a por tempo:
CREATE TABLE audit_log (...) PARTITION BY RANGE (ts);
CREATE TABLE audit_log_2024_q1 PARTITION OF audit_log
FOR VALUES FROM ('2024-01-01') TO ('2024-04-01');Compensação de desempenho
Cada operação de inserção, atualização ou exclusão agora grava uma segunda linha. Em tabelas com muitas gravações, isso pode duplicar o IO. Teste, monitore e decida se a compensação vale a pena.
Quando NOT utilizar gatilhos do banco de dados
Se precisar de integração com um barramento de eventos, enfileire eventos com NOTIFY ou LISTEN, ou utilize ferramentas de replicação lógica/CDC (Debezium) em vez de gatilhos.
Recapitulação
Gatilhos de auditoria são a forma mais simples de capturar o histórico.
- Uma função genérica com to_jsonb(NEW/OLD)
- Anexe-a a todas as tabelas auditadas
- Particione as tabelas de auditoria por tempo
- Rastreie explicitamente o responsável do aplicativo por meio de GUCs
Verificação rápida
Dentro de uma função de gatilho de auditoria, como capturar a nova linha como JSONB de forma genérica?
Perguntas Frequentes
A aula “Auditoria de tabelas com gatilhos” é grátis?
Sim — o texto completo de “Auditoria de tabelas com gatilhos” é 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 “Auditoria de tabelas com gatilhos”?
Crie um histórico de auditoria com gatilhos AFTER INSERT/UPDATE/DELETE que gravem em uma tabela audit_log. 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 4 de 4.
Quanto tempo leva a aula “Auditoria de tabelas com gatilhos”?
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
- Anatomia de gatilhos: BEFORE/AFTER, FOR EACH ROW
- Fundamentos de funções PL/pgSQL
- Blocos DO e código anônimo
- Auditoria de tabelas com gatilhos