Considerações sobre o desempenho do PostgreSQL
Os gatilhos no PostgreSQL são funções de retorno de chamada do banco de dados invocadas ou executadas automaticamente em resposta a determinados eventos em uma tabela ou visualização específica. Eles são usados para aplicar regras comerciais, validar dados de entrada e manter a integridade dos dados.
Uso
Os acionadores são empregados quando você precisa executar automaticamente uma função em resposta a eventos como operações `INSERT`, `UPDATE` ou `DELETE` em uma tabela. Eles são definidos para agir antes ou depois desses eventos.
sql
CREATE TRIGGER trigger_name
{ BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] }
ON table_name
[ FOR [ EACH ] { ROW | STATEMENT } ]
EXECUTE PROCEDURE function_name(arguments);
Nessa sintaxe, `CREATE TRIGGER` configura um acionador chamado `trigger_name` que executa `function_name` quando os eventos especificados ocorrem em `table_name`.
Exemplos
1. Gatilho de inserção básico
sql
CREATE OR REPLACE FUNCTION log_insert()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_table(action, time) VALUES ('INSERT', NOW());
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER insert_audit
AFTER INSERT ON my_table
FOR EACH ROW EXECUTE PROCEDURE log_insert();
Esse acionador registra cada operação de inserção na `minha_tabela`, adicionando um registro à `tabela_de_auditoria`.
2. Acionador de atualização com lógica condicional
sql
CREATE OR REPLACE FUNCTION check_update()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.amount < 0 THEN
RAISE EXCEPTION 'Amount cannot be negative';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER check_update_trigger
BEFORE UPDATE ON transactions
FOR EACH ROW EXECUTE PROCEDURE check_update();
Esse acionador verifica se a coluna `amount` na tabela `transactions` não é negativa antes das operações de atualização.
3. Acionador para exclusões em cascata
sql
CREATE OR REPLACE FUNCTION cascade_delete()
RETURNS TRIGGER AS $$
BEGIN
DELETE FROM child_table WHERE parent_id = OLD.id;
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER cascading_delete_trigger
AFTER DELETE ON parent_table
FOR EACH ROW EXECUTE PROCEDURE cascade_delete();
Esse acionador garante que, quando uma linha for excluída da `tabela_pai`, as linhas relacionadas na `tabela_filha` também serão removidas.
Dicas e práticas recomendadas
- Lógica de acionamento de limite. Mantenha as funções de acionamento simples para minimizar a sobrecarga de desempenho e evitar a lógica comercial complexa.
- Use acionadores em nível de linha de forma seletiva. Opte por acionadores em nível de instrução quando possível para reduzir o número de execuções. Os acionadores em nível de linha são úteis quando as operações precisam ser executadas em cada linha afetada, enquanto os acionadores em nível de instrução podem reduzir a sobrecarga executando uma vez por operação.
- Seja cauteloso com acionadores recursivos. Assegure-se de que os acionadores não chamem a si mesmos de forma não intencional, levando a loops infinitos.
- Faça um teste completo. Teste exaustivamente os acionadores em um ambiente de desenvolvimento para avaliar seu impacto no desempenho.
- Acionadores de documentos. Documente claramente a finalidade e a lógica de cada acionador para referência e manutenção futuras.
- Considere os limites da transação. Tenha em mente os limites da transação para garantir que os acionadores se comportem como esperado em transações com vários demonstrativos.
- Monitore o desempenho. Fique de olho no impacto do desempenho dos acionadores em um sistema ativo e diagnostique quaisquer problemas usando as ferramentas de registro e monitoramento do PostgreSQL.
Gerenciamento de acionadores
- Para desativar um acionador temporariamente, use a opção `ALTER TABLE ... comando DISABLE TRIGGER`.
- Para remover permanentemente um acionador, use o comando `DROP TRIGGER`.