Naps: Änderungen speichern

Hi,

ich würde gerne bei bestimmten Datenbanken in mysql die Änderungen speichern.

Habe diese Lösung nach kurzer Suche gefunden:

Datenbank

CREATE TABLE `dummy` (  
  `dummy_id` int(11) NOT NULL AUTO_INCREMENT,  
  value int(11),  
  PRIMARY KEY (`dummy_id`)  
) ENGINE=InnoDB;

Datenbank für Änderungen

CREATE TABLE dummy_log (  
  `log_id` int(11) NOT NULL AUTO_INCREMENT,  
  `dummy_id` int(11) NOT NULL,  
  old_value int(11),  
  new_value int(11),  
  action enum('insert','update','delete'),  
  dt datetime,  
  PRIMARY KEY (`log_id`)  
) ENGINE=InnoDB;

Trigger

DELIMITER $$  
  
CREATE TRIGGER trigger_dummy_insert AFTER INSERT ON dummy  
  FOR EACH ROW BEGIN  
    INSERT INTO dummy_log (dummy_id, new_value, action, dt) VALUES (NEW.dummy_id, NEW.value, 'insert', NOW() );  
  END;  
$$  
  
CREATE TRIGGER trigger_dummy_update AFTER UPDATE ON dummy  
  FOR EACH ROW  
    BEGIN  
      IF OLD.value != NEW.value THEN  
        INSERT INTO dummy_log (dummy_id, old_value, new_value, action, dt) VALUES (NEW.dummy_id, OLD.value, NEW.value, 'update', NOW() );  
      END IF;  
    END;  
$$  
  
CREATE TRIGGER trigger_dummy_delete AFTER DELETE ON dummy  
  FOR EACH ROW  
    BEGIN  
      INSERT INTO dummy_log (dummy_id, old_value, action, dt) VALUES (OLD.dummy_id, OLD.value, 'delete', NOW() );  
    END;  
$$  
  
DELIMITER ;

Ist es Sinnvoll es so zu lösen? Was ist aber wenn ich viele Spalten habe und es z.B. eine Änderungen in 3 Spalten gibt. Soll es dann in der "ÄnderungsDB" 3 Einträge geben?

Was ich am Schluss möchte ist einfach nur eine Art Logfile:

z.B.:

  • Titel wurde um xxxx von xxx zu "Neuer Wert" geändert.
  • Beschreibung wurde um xxx von xxx zu "Neuer Wert" geändert.
    ...

Danke!
MfG Naps

  1. Für sinnvoll halte ich Trigger dann, wenn die Datenbankstruktur nicht geändert werden darf/soll (um z.B. bei Updates nicht die komplette Datenbank konvertieren zu müssen oder um die Software nicht jedesmalanpassen zu müssen). Einen Trigger nachzusetzen ist oft weniger Aufwand als eine Anpassung der Struktur/Software.

    Ob du Trigger nimmst oder die Datenbankänderungn direkt in deiner Anwendung machst, hängt IMO vom Aufwand ab.
    Ist es deine eigene Anwendung, würde ich zu einer Lösung in der Anwendung raten, denn bei einem Update bleibt das Logging ja in der Software bei einem Update erhalten. Wenn es fremdsoftware ist, würde ich nen Trigger nehmen aus o.g. Gründen.

    Ich nutze Trigger z.B. in einem Kassensystem (Fremdsoftware), damit Verkäufe mit dem Onlineshop (Fremdsoftware) synchronisiert werden. Da die Software regelmässig Updates erfährt, will ich nicht immer die Software per hand anpassen. Da bei einem Update die Datenbank erhalten bleibt, bleiben die Trigger auch und es ist keine zusätzlich Arbeit nötig.

  2. Hallo,

    Ist es Sinnvoll es so zu lösen? Was ist aber wenn ich viele Spalten habe und es z.B. eine Änderungen in 3 Spalten gibt. Soll es dann in der "ÄnderungsDB" 3 Einträge geben?

    Warum so umständlich?

    Sichere doch den alten Datensatz komplett VOR der Änderung. Die Änderungstabelle könnte diesen Aufbau haben:

    id;tabelle_name;tabelle_id;last_modified;text

    und im Feld text steht der komplette alte Datensatz als CSV.

    Jederzeit kannst du dann für einen bestimmten Datensatz die Historie abrufen nach
    * tabelle_name
    * tabelle_id
    * last_modified DESC

    In deiner Beschreibung hast du nicht erwähnt, WER den Datensatz änderte, das wäre aber auch eine wichtige Information.

    Gast

    1. Hallo,

      Ist es Sinnvoll es so zu lösen? Was ist aber wenn ich viele Spalten habe und es z.B. eine Änderungen in 3 Spalten gibt. Soll es dann in der "ÄnderungsDB" 3 Einträge geben?

      Warum so umständlich?

      Sichere doch den alten Datensatz komplett VOR der Änderung. Die Änderungstabelle könnte diesen Aufbau haben:

      id;tabelle_name;tabelle_id;last_modified;text

      und im Feld text steht der komplette alte Datensatz als CSV.

      Jederzeit kannst du dann für einen bestimmten Datensatz die Historie abrufen nach
      * tabelle_name
      * tabelle_id
      * last_modified DESC

      In deiner Beschreibung hast du nicht erwähnt, WER den Datensatz änderte, das wäre aber auch eine wichtige Information.

      Gast

      "Jeder" (nach Login) kann Datensätze über ein Formular ändern.

      Ich dachte anfangs an mysql_affected_rows, aber die Funktionier liefert ja leider nur die Anzahl der geänderten Spalten.

      1. "Jeder" (nach Login) kann Datensätze über ein Formular ändern.

        Zu pauschal. Wer ist "Jeder"? Hundert Leute, die dasselbe Passwort haben und damit nicht zu unterscheiden sind?

        Welche Datensätze kann "Jeder" ändern? Auch die, die von anderen Benutzerm (falls es "andere" neben "Jeder" gibt) angelegt wurden?

        Ich dachte anfangs an mysql_affected_rows, aber die Funktionier liefert ja leider nur die Anzahl der geänderten Spalten.

        Genauer: Die Anzahl der geänderten Datensätze. Wenn bei einem Datensatz drei, fünf oder zehn Felder (rows, Spalten) geändert wurden, ist mysql_affected_rows == 1

        Gast

        1. "Jeder" (nach Login) kann Datensätze über ein Formular ändern.

          Zu pauschal. Wer ist "Jeder"? Hundert Leute, die dasselbe Passwort haben und damit nicht zu unterscheiden sind?

          Nein jeder hat seinen eignen Login und damit verbunden auch seine eigene UserID. Damit wäre es kein Problem die Person zu identifizieren die gerade den Datensatz geändert hat.

          Welche Datensätze kann "Jeder" ändern? Auch die, die von anderen Benutzerm (falls es "andere" neben "Jeder" gibt) angelegt wurden?

          Jeden Eintrag den er selbst erstellt hat.

          Ich dachte anfangs an mysql_affected_rows, aber die Funktionier liefert ja leider nur die Anzahl der geänderten Spalten.

          Genauer: Die Anzahl der geänderten Datensätze. Wenn bei einem Datensatz drei, fünf oder zehn Felder (rows, Spalten) geändert wurden, ist mysql_affected_rows == 1

          stimmt, da habe ich mich falsch ausgedrückt.

        2. Wenn bei einem Datensatz drei, fünf oder zehn Felder (rows, Spalten) geändert wurden, ist mysql_affected_rows == 1

          Sorry. Die Felder eines Datensatzes sind nicht rows (Zeilen), sondern columns (Spalten).

          Mit mysql_affected_rows erfragst du die Anzahl der geänderten Datensätze, aber nicht die Anzahl der geänderten Felder. Die kann ja bei mehreren Datensätzen auch unterschiedlich sein.

          Gast