PostgreSQL

Vincoli, transazioni o trigger: quale strumento scegliere?

Questi tre strumenti proteggono i dati in momenti diversi. Confonderli aggiunge complessità senza migliorare l'affidabilità.

Team SQL.tn10min
Una barriera rifiuta un valore non valido, una capsula assicura due operazioni e un sensore archivia una modifica

Tre problemi, tre momenti di azione

Un vincolo chiede: questa linea rispetta sempre una regola? Un transaction chiede: queste operazioni dovrebbero avere successo o fallire insieme? Un trigger chiede: dovremmo reagire automaticamente quando si verifica un evento relativo ai dati?

La scelta giusta inizia da questa differenza. Utilizza un trigger per tutte le regole della cache; l'utilizzo solo dell'applicazione consente a ciascun processo di reimplementare i controlli.

Vincolo: impedisce uno stato non valido

NOT NULL richiede un valore, UNIQUE evita una ripetizione, CHECK controlla una condizione e FOREIGN KEY garantisce l'esistenza di una relazione. Queste regole sono dichiarative e visibili nella struttura.

Per evitare un prezzo negativo, il CHECK è preferibile al trigger: la regola è breve, atomica e compresa direttamente dallo DBMS.

Vincolo PostgreSQL verificato
CREATE TABLE produits (
  id_produit INTEGER PRIMARY KEY,
  prix NUMERIC NOT NULL CHECK (prix >= 0)
);

Transaction: proteggere un'operazione composta

Un ordine e il relativo pagamento riguardano due tabelle, ma costituiscono un'unica intenzione commerciale. BEGIN apre transaction, COMMIT conferma e ROLLBACK annulla. SAVEPOINT offre un rendimento parziale in uno transaction più lungo.

Uno transaction non sostituisce i vincoli: garantisce l'atomicità delle operazioni, mentre i vincoli controllano ogni stato proposto.

Annulla se il pagamento fallisce
BEGIN;
INSERT INTO commandes (id_commande, montant) VALUES (108, 120);
INSERT INTO paiements (id_commande, montant) VALUES (108, 120);
-- COMMIT se tutto riesce, altrimenti ROLLBACK
COMMIT;

Trigger: reagire a un evento

PostgreSQL separa la funzione di trigger e il trigger collegato al tavolo. OLD contiene la riga prima della modifica, NEW la riga proposta. DOPO UPDATE è adatto per una cronologia delle modifiche già accettata.

PRIMA può modificare o rifiutare NUOVO, ma un vincolo rimane più chiaro per una regola semplice. ROW esegue la funzione per ogni riga; STATEMENT lo esegue una volta per l'istruzione.

Storicizzare un prezzo con PostgreSQL
CREATE FUNCTION journaliser_prix() RETURNS trigger AS $$
BEGIN
  INSERT INTO historique_prix (id_produit, ancien_prix, nouveau_prix)
  VALUES (OLD.id_produit, OLD.prix, NEW.prix);
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER audit_prix
AFTER UPDATE OF prix ON produits
FOR EACH ROW EXECUTE FUNCTION journaliser_prix();

Quando non utilizzare un trigger

Un trigger è particolarmente adatto per un controllo o un logging che deve essere applicato indipendentemente dal chiamante. Anche in questo caso, documentate l’effetto, verificate gli errori e misurate il costo.

  • Un vincolo esprime direttamente la regola semplice.
  • La logica deve essere visibile in un servizio applicativo e con esso la versione.
  • Una modifica massiccia comporterebbe un'elaborazione costosa per riga.
  • Il trigger rischia di modificare la stessa tabella e creare una ricorsione.
  • Al team mancano i test e la supervisione necessari.

Guida rapida alla scelta

Per prima cosa chiedi se stai proteggendo una riga, un insieme di operazioni o una reazione a un evento. Combina gli strumenti quando le loro responsabilità differiscono: CHECK rifiuta un prezzo non valido, uno transaction raggruppa la modifica e il suo pagamento, un trigger mantiene il vecchio prezzo accettato.

Non scegliere la lunghezza del codice. Scegli regola aziendale, visibilità, tempo di esecuzione, comportamento degli errori e costi sotto carico.

Vincolo = stato valido. Transaction = tutto o niente. Trigger = reazione automatica ad un evento.

Dipende da te

Combina questi casi: singola email, bonifico di addebito/credito, cronologia indirizzi, ordine collegato a un cliente e creazione di ordine/pagamento. Le risposte attese sono rispettivamente vincolo, transaction, possibile trigger, chiave esterna e transaction.

La micro-formazione avanzata rimane in preparazione fino a quando un laboratorio PostgreSQL modificabile e ripristinabile non avrà superato i test di sicurezza e robustezza.

Segui la preparazione di questa competenza.

Consulta il risultato previsto, i prerequisiti e lo stato reale del micro-corso.

Vedi il micro-corso