MySQL 5: Trigger sind da!

Für den Counterkram habe ich die Datenbank gestern auf MySQL 5 aktualisiert. Der wichtigste Grund war die Einführung von Triggern. Mit diesem (bei „richtigen“ Datenbanken schon lange vorhandenen) Feature ist es möglich, innerhalb der Datenbank direkt auf SELECT, UPDATE oder INSERT einer Tabell zu reagieren und weitere Aktionen anzustoßen.

Momentan halte ich die Daten für stündliche, tägliche und monatliche Zugriffe auf die einzelnen Blogs in separate Tabellen der gleichen Datenbank fest. Natürlich könnte man auch mit nur einer Tabelle auskommen, nämlich einer, in der die Zugriffe protokolliert werden und mit entsprechenden SUM– und GROUP BY-Spielereien die gewünschten Daten aus dieser einen Tabelle auswerten.

Diese Tabelle wird aber ziemlich schnell sehr groß und damit auch träge, wenn man nicht gerade viel Geld in teure Hardware steckt. Um dieses Problem zu lösen, habe ich mich also für die redundante Speicherung der Daten entschieden. Bevor ich auf MySQL 5 umgestiegen bin, musste ich dies aber auf Applikationsebene machen, was mir nicht besonders gefällt, da es (a) genau für solche Fälle Trigger gibt und (b) die Daten einfach konsistenter sind, wenn die Datenbank sich um die redundante Speicherung kümmert.

Nun kommen also die Trigger ins Spiel. Dafür nehmen wir ein einfaches Beispiel an: In den Logfiles ist der User-Agent schon so aufbereitet, dass nur noch „Internet Explorer“, „Safari„, etc. als Browser angegeben ist. In einer separaten Tabelle soll nun pro Blog eine Statistik der verwendeten Browser abgelegt werden. Dabei interessiert nur die monatliche Verteilung. Die Tabelle tbl_browser_stat hat also die drei Felder blog_id, month, browser und impressions.

Über einen Trigger soll nun bei jeder neuen Zeile in der Tabelle mit den Logfile-Zeilen, die Tabelle tbl_browser_stat aktualisiert werden. Und hier kommt jetzt ein weiteres, kleines Problem ins Spiel: Falls für die Kombination aus Browser und Blog noch kein Eintrag in der Datenbank vorhanden ist, muss ja ein INSERT statt eines UPDATEs gemacht werden. Dafür gibt es in MySQL das Konstrukt INSERT ... ON DUPLICATE KEY UPDATE .... Deer Trigger sieht dann also folgendermaßen aus:

CREATE TRIGGER monthly_browser_stats AFTER INSERT ON tbl_log_rows
    FOR EACH ROW
        INSERT INTO tbl_browser_stats SET blog_id=NEW.blog_id, month=NEW.month, browser=NEW.browser, impressions=1 
        ON DUPLICATE KEY UPDATE impressions=impressions+1;

Auf der Tabelle tbl_browser_stats wurde ein UNIQUE-Key auf die Kombination von blog_id, month und browser angelegt. Von nun an wird die Tabelle automatisch gefüllt und es können sehr einfach die Verteilung der Zugriffe bestimmter Browser auf einzelne oder alle Blogs abgefragt werden. Die Applikation wird von mir in den nächsten Tagen schrittweise von diesem Ballast befreit, neue Statistiken können dann fast ausschließlich über neue Trigger realisiert werden.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert