History für Datenbankeinträge automatisieren: Trigger benutzen

2 Kommentare
Mischa Sameli, Geschäftsführer & Leiter Entwicklung

Nachverfolgbarkeit von Daten und Aktionen sind immer immens wichtig – nur brauchen tuts niemand, bis einmal etwas passiert. Und dann sind keine schlauen Logfiles vorhanden. Klar. Klar kann man Backups zurückspielen, aber die bieten leider in der Regel nur gerade ein Abbild eines bestimmten Zeitpunkt (es sei denn, man hat auch Zugriff auf Transaction Logs und kann diese auswerten). Eine recht einfache Methode, wie man effizient eine schlaue Protokollierung von Datenbankmutation kommt, möchte ich im Folgenden kurz aufzeigen anhand von sogenannten Triggern.

Was sind Trigger eigentlich? Nun, Trigger sind kleine Überwacher, die selbst definierte Prozesse auslösen können. Man stelle sich etwa Baywatch vor und definiere die StrandwächterInnen als Trigger. Sie tun etwas, wenn: jemand ERTRINKT, SONNENCREME oder ZUNEIGNUNG braucht. Etwa so funktionieren auch Datenbank-Trigger. So tun etwas bei INSERT, UPDATE oder DELETE. Automatisiert, im Hintergrund, zuverlässig. Und Mittlerweile können auch alle wichtigen Datenbanken mit Triggern umgehen.

So, lösen wir nun das Problem der Protokollierung. Nehmen wir an, wir haben eine einfache Tabelle "muster" mit folgenden Spalten: ID, Name, userID Dazu erstellen wir eine Log-Tabelle "log_muster" mit folgenden Spalten: ID, musterID, Name, userID, d_new, action

Jetzt erstellen wir unsere Überwacher der Tabelle "muster", also unsere Trigger. Beginnen wir mit dem Überwacher für Neueinträge, also den INSERT-Trigger:

1CREATE TRIGGER [tbl_insert] ON [muster]
2FOR INSERT
3AS
4INSERT log_muster(musterID,userID,[name],[action])
5SELECT [ID],userID,[Name],'i'
6FROM inserted

Sobald nun ein neuer Datensatz in die Tabelle "muster" eingetragen wird, werden die Daten auch in die Tabelle "log_muster" eingetragen. Damit wir die Aktion verfolgen können, haben wir eine Datum/Zeit-Spalte eingefügt und notieren die durchgeführte Aktion in der Spalte "action", in diesem Fall mit einem "i" für INSERT. Der zweite Trigger sieht beinahe identisch aus und überwacht Änderungen an Datensätzen in der Tabelle "muster":

1CREATE TRIGGER [tbl_update] ON [muster]
2FOR UPDATE
3AS
4INSERT log_muster(musterID,userID,[name],[action])
5SELECT [ID],userID,[Name],'u' FROM inserted

Hier wird ebenfalls ein neuer Eintrag in der Log-Tabelle erstellt. Wenn wir nun diese Tabelle nach der musterID filtern und nach Datum sortieren, erhalten wir exakt die Chronik eines einzelnen Datensatzes. Effizient und einfach.
Den dritten Trigger setzen wir noch für gelöschte Daten:

1CREATE TRIGGER [tbl_delete] ON [muster]
2FOR DELETE
3AS
4INSERT log_muster(musterID,userID,[name],[action])
5SELECT [ID],userID,[Name],'d' FROM deleted

So, damit haben wir auch den letzten Stand noch gesichert, bevor der Datensatz gelöscht worden ist. Drei Trigger, die den ganzen Lebenszyklus eines Datensatzes protokollieren können.