Wie kann eine LastUpdatedDate-Spalte in SQL am besten verwaltet werden?

7

Angenommen, ich verfüge über eine Datenbanktabelle mit einer Zeitspalte für die letzte Aktualisierung oder Einfügung. Was wäre vorzuziehen:

  1. Lassen Sie einen Trigger das Feld aktualisieren.
  2. Lassen Sie das Feld, das das Einfügen / Aktualisieren durchführt, das Feld festlegen.

Die erste Option scheint die einfachste zu sein, da ich es nicht einmal neu kompilieren muss, aber das ist nicht wirklich eine große Sache. Abgesehen davon, habe ich Probleme, über irgendwelche Gründe nachzudenken, die eine gegen die andere machen. Irgendwelche Vorschläge?

    
Jason Baker 07.01.2009, 21:08
quelle

10 Antworten

7

Die erste Option kann robuster sein, da die Datenbank das Feld verwaltet. Dies ist mit dem möglichen Mehraufwand für die Verwendung von Triggern verbunden.

Wenn Sie in Zukunft andere Apps über ihre eigenen Schnittstellen in diese Tabelle schreiben könnten, würde ich einen Trigger verwenden, damit Sie diese Logik nirgendwo anders wiederholen.

Wenn Ihre App so aussieht oder alle anderen Apps über dieselbe Datenebene auf die Datenbank zugreifen würden, würde ich diesen Albtraum vermeiden, den Trigger auslösen und die Logik direkt in Ihren Datenlayer (SQL, ORM, gespeicherte Prozeduren) versetzen können , etc.).

Natürlich müssen Sie sicherstellen, dass Ihre Zeitquelle (Ihre App, die PCs Ihrer Benutzer, Ihr SQL-Server) in beiden Fällen korrekt ist.

Warum ich Trigger nicht mag:

Vielleicht war ich voreilig, indem ich sie einen Albtraum nannte. Wie alles andere sind sie angemessen in Maßen. Wenn Sie sie für sehr einfache Dinge wie diese verwenden, könnte ich an Bord gehen.

Wenn der Trigger-Code komplex (und teuer) wird, lösen Trigger viele Probleme aus. Sie sind eine versteckte Steuer auf jede Einfügung / Aktualisierung / Löschung der Abfrage, die Sie ausführen (abhängig von der Art des Auslösers). Wenn diese Steuer akzeptabel ist, dann können sie das richtige Werkzeug für den Job sein.

    
Michael Haren 07.01.2009, 21:14
quelle
6

Sie haben 3 nicht erwähnt. Verwenden Sie eine gespeicherte Prozedur, um die Tabelle zu aktualisieren. Die Prozedur kann Zeitstempel wie gewünscht festlegen.

Vielleicht ist das für Sie nicht machbar, aber ich habe es nicht erwähnt.

    
StuffMaster 07.01.2009 23:29
quelle
4

Ich würde sagen, Trigger für den Fall, dass jemand außer Ihrer App etwas verwendet, um die Tabelle zu aktualisieren, möchten Sie wahrscheinlich auch eine LastUpdatedBy und verwenden Sie SUSER_SNAME () dafür, auf diese Weise können Sie sehen, wer die Aktualisierung

    
SQLMenace 07.01.2009 21:18
quelle
4

Solange ich ein DBMS verwende, auf dessen Trigger ich vertraue, würde ich immer mit der Trigger-Option gehen. Es erlaubt dem DBMS, sich um so viele Dinge wie möglich zu kümmern, was normalerweise eine gute Sache ist.

Es funktioniert, stellen Sie sicher, dass die Timestamp-Spalte unter allen Umständen den richtigen Wert hat. Der Overhead wäre vernachlässigbar.

Das einzige, was gegen Trigger wäre, ist die Portabilität. Wenn das kein Problem ist, glaube ich nicht, dass es eine Frage gibt, in welche Richtung es gehen soll.

    
Thorsten 07.01.2009 21:20
quelle
3

Ich bin ein Verfechter von gespeicherten Prozeduren für alles. Ihr Update-Prozess könnte ein GETDATE () für die Spalte enthalten.

Und ich mag keine Trigger für diese Art von Update. Mangelnde Sichtbarkeit von Triggern führt zu Verwirrung.

    
LJ. 08.01.2009 00:05
quelle
3

Das klingt nach Geschäftslogik für mich ... Ich wäre eher geneigt, das in den Code zu schreiben. Lassen Sie die Datenbank die Speicherung von Daten verwalten ... nicht mehr und nicht weniger.

    
mattruma 08.01.2009 00:15
quelle
3

Trigger sind ein Segen und ein Fluch.

Segen: Sie können sie verwenden, um alle Arten von benutzerdefinierten Constraint-Prüfungen und Datenmanagement ohne Wissen oder Änderungen des Backend-Systems zu aktivieren.

Fluch: Du weißt nicht, was hinter deinem Rücken passiert. Concurrency-Probleme / Deadlocks durch zusätzliche Objekte, die in Transaktionen eingebracht wurden, die ursprünglich nicht erwartet wurden. Phantomverhalten einschließlich Änderung der Sitzungsumgebung, unzuverlässige Zeilenzählung Übermäßiges Auslösen von Bedingungen. Zusätzliche Hotspot- / Leistungsstrafen.

Die Antwort auf diese Frage (Datumsangaben implizit (Auslöser) oder explizit (Code) aktualisieren) belastet den Kontext normalerweise stark. Wenn Sie z. B. das Datum der letzten Änderung als Informationsfeld verwenden, möchten Sie es möglicherweise nur ändern, wenn ein Benutzer wesentliche Änderungen an einer Zeile vornimmt, im Gegensatz zu einem automatisierten Prozess, bei dem eine Art interner Marker nicht aktualisiert wird .

Wenn Sie den Trigger für die Änderungssynchronisierung verwenden oder keine Kontrolle über Code haben, der einen Trigger ausführt, ist das viel sinnvoller.

Ich rate zu Trigger, um vorsichtig zu sein. Bei den meisten Systemen können Sie die Ausführung basierend auf dem Vorgang und den geänderten Feldern filtern. Die richtige Verwendung von "vor" und "nach" Triggern kann erhebliche Auswirkungen auf die Leistung haben.

Schließlich können einige Systeme einen einzigen Trigger für mehrere Änderungen ausführen (mehrere Zeilen innerhalb einer Transaktion). Ihr Code sollte darauf vorbereitet sein, sich selbst als Massenaktualisierung auf mehrere Zeilen anzuwenden.

    
Einstein 08.01.2009 00:46
quelle
2

Normalerweise würde ich es Datenbankseite sagen, aber es hängt von Ihrer Anwendung ab. Wenn Sie LINQ-to-SQL verwenden, können Sie das Feld einfach als Timestamp definieren und Ihre DAL verwenden das Timestamp-Feld für den gemeinsamen Zugriff. Es handhabt es automatisch für Sie, also Code zu wiederholen ist ein Nicht-Ereignis.

Wenn Sie Ihre DAL jedoch selbst schreiben, würde ich eher auf der Datenbankseite damit umgehen, da dies das Schreiben von Benutzeroberflächen viel flexibler macht - obwohl ich dies wahrscheinlich in einer gespeicherten Prozedur tun würde hat "öffentlichen" Zugriff und die Tabellen sind gesperrt - Sie möchten nicht, dass irgendein Clown vorbeikommt und Ihre gespeicherte Prozedur umgeht, indem Sie direkt in die Tabellen schreiben ... es sei denn, Sie planen, Ihre DAL zu einer eigenständigen Komponente zu machen Verwenden Sie, um auf die Datenbank zuzugreifen, in diesem Fall könnten Sie es direkt in die DAL codieren - natürlich sollten Sie dies nur tun, wenn Sie garantieren können, dass jeder, der auf die Datenbank zugreift, dies über Ihre DAL-Komponente tut.

Wenn Sie erlauben, dass "öffentlicher" Zugriff auf die Datenbank in Tabellen eingefügt wird, dann müssen Sie mit dem Auslöser gehen, weil sonst jeder ein einzelnes Feld in die Tabelle einfügen / aktualisieren kann und das aktualisierte Feld könnte nie aktualisiert werden.

    
BenAlabaster 07.01.2009 21:23
quelle
2

Ich würde das Datum in der Datenbank beibehalten, dh einen Trigger, eine gespeicherte Prozedur usw. In den meisten Ihrer datenbankgestützten Anwendungen wird die Benutzer-App nicht das einzige Mittel sein, mit dem die Geschäftsbenutzer Daten abrufen können . Es gibt Reporting-Tools, Extrakte, Benutzer-SQL usw. Es gibt auch Aktualisierungen und Korrekturen, die vom DBA vorgenommen werden, für die die Anwendung das Datum ebenfalls nicht angibt.

Aber ehrlich gesagt ist der Hauptgrund, warum ich es nicht von der Anwendung aus tun würde, dass Sie keine Kontrolle über das Datum / die Uhrzeit auf dem Client-Rechner haben. Sie können es zurückrollen, um mehr Tage aus einer Testlizenz für etwas zu bekommen, oder wollen einfach nur schlechte Dinge für Ihr Programm tun.

    
Eric Sabine 07.01.2009 23:14
quelle
1

Sie können dies ohne den Trigger tun, wenn Ihre Datenbank Standardwerte für die Felder unterstützt. In SQL Server 2005 habe ich beispielsweise eine Tabelle mit einem Feld, das wie folgt erstellt wurde:

%Vor%

dann lässt der Einfügecode dieses Feld nur aus der Einfügefeldliste.

Ich habe vergessen, dass das nur für die erste Einfügung funktionierte - ich habe auch einen Aktualisierungstrigger, um die Datumsfelder zu aktualisieren und eine Kopie des aktualisierten Datensatzes in meine Verlaufstabelle zu legen - die ich posten würde ... aber den Editor Fehler in meinem Code fortbestehen ...

Schließlich:

%Vor%

Ron

    
Ron Savage 07.01.2009 23:22
quelle