PostgreSQL Anwendungsfälle
Trigger in PostgreSQL sind Datenbank-Callback-Funktionen, die automatisch ausgeführt werden, wenn ein bestimmtes Datenbankereignis eintritt, wie z.B. eine `INSERT`-, `UPDATE`- oder `DELETE`-Operation. Sie werden eingesetzt, um Geschäftsregeln durchzusetzen, Eingabedaten zu validieren und die Datenintegrität zu gewährleisten.
Verwendung
Trigger automatisieren Aufgaben und setzen Regeln auf Datenbankebene durch, um sicherzustellen, dass bestimmte Vorgänge als Reaktion auf Änderungen in den Daten erfolgen. Sie bestehen aus einem Auslöseereignis, einem Timing und der dazugehörigen Funktion, die ausgeführt werden soll.
CREATE TRIGGER trigger_name
{ BEFORE | AFTER | INSTEAD OF }
{ INSERT | UPDATE | DELETE }
ON table_name
FOR EACH ROW
EXECUTE FUNCTION function_name();
In dieser Syntax definiert `CREATE TRIGGER` einen neuen Trigger und gibt an, wann er ausgelöst werden soll (`BEFORE`, `AFTER` oder `INSTEAD OF` eines Ereignisses) und welche Funktion er ausführen soll. BEFORE"-Trigger werden in der Regel verwendet, um Daten zu ändern, bevor sie in die Datenbank geschrieben werden, `AFTER"-Trigger werden für Aktionen verwendet, die nach der Übertragung der Daten erfolgen sollen, und `INSTEAD OF"-Trigger werden häufig für Views verwendet, um die erforderlichen Änderungen an den zugrunde liegenden Tabellen vorzunehmen.
FOR EACH ROWgibt an, dass die Triggerfunktion für jede Zeile, die von dem auslösenden Ereignis betroffen ist, einmal ausgeführt wird. Im Gegensatz dazu kannFOR EACH STATEMENTverwendet werden, um die Triggerfunktion einmal pro SQL-Anweisung auszuführen, unabhängig von der Anzahl der betroffenen Zeilen.NEWundOLDsind spezielle Datensatzvariablen innerhalb von Triggern:NEWenthält die neuen Zeilendaten für die OperationenINSERToderUPDATEundOLDenthält die bestehenden Zeilendaten für die OperationenUPDATEoderDELETE.
Beispiele
1. Basic Insert Trigger
CREATE FUNCTION log_insert() RETURNS TRIGGER AS $$
BEGIN
-- Log every insert operation into log_table
INSERT INTO log_table(action, timestamp) VALUES ('Insert', now());
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER before_insert
BEFORE INSERT ON main_table
FOR EACH ROW
EXECUTE FUNCTION log_insert();
In diesem Beispiel wird ein Trigger erstellt, der jede Einfügeoperation in der "main_table" in einer "log_table" protokolliert.
2. Auslöser mit Bedingung aktualisieren
CREATE FUNCTION update_timestamp() RETURNS TRIGGER AS $$
BEGIN
-- Update the updated_at timestamp field when a row is modified
NEW.updated_at := now();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_time
BEFORE UPDATE ON main_table
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE FUNCTION update_timestamp();
Dieser Trigger aktualisiert das Zeitstempelfeld `updated_at` in `main_table`, wenn eine Zeile geändert wird.
3. Komplexer Auslöser für Auditing
CREATE FUNCTION audit_changes() RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'DELETE') THEN
-- Log DELETE operations into audit_log
INSERT INTO audit_log(action, old_data, timestamp) VALUES ('DELETE', OLD, now());
ELSIF (TG_OP = 'UPDATE') THEN
-- Log UPDATE operations with both old and new data
INSERT INTO audit_log(action, old_data, new_data, timestamp) VALUES ('UPDATE', OLD, NEW, now());
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER audit_trigger
AFTER INSERT OR UPDATE OR DELETE ON main_table
FOR EACH ROW
EXECUTE FUNCTION audit_changes();
Dieser Trigger protokolliert Änderungen an `main_table` in einem `audit_log`. Dabei werden sowohl die alten als auch die neuen Daten für `UPDATE`-Operationen erfasst.
Tipps und bewährte Praktiken
- Optimiere für die Leistung. Trigger können den Datenbankbetrieb unnötig belasten, daher solltest du sicherstellen, dass sie effizient sind.
- Verwende Auslöser sparsam. Vermeide die übermäßige Verwendung von Triggern, um Komplexität und mögliche Leistungsprobleme zu vermeiden.
- Achte auf Atomarität. Achte darauf, dass die Triggerfunktionen atomar sind und Ausnahmen behandeln, um die Datenintegrität zu wahren.
- Teste gründlich. Teste die Trigger gründlich in einer Entwicklungsumgebung, bevor du sie in der Produktion einsetzt, um unbeabsichtigte Nebeneffekte zu vermeiden.
- Ziehe Alternativen in Betracht. Prüfe, ob Stored Procedures oder Anwendungslogik für bestimmte Vorgänge besser geeignet sind, um Klarheit und Wartbarkeit zu gewährleisten.