Sind Datenbankauslöser eine schlechte Idee?
Nach meiner Erfahrung sind sie böse, weil sie zu überraschenden Nebenwirkungen führen können und schwer zu debuggen sind (insbesondere wenn ein Auslöser einen anderen auslöst). Oft denken Entwickler nicht einmal daran, nach einem Auslöser zu suchen.
Auf der anderen Seite scheint es so, als ob Sie eine Logik haben, die jedes Mal auftreten muss, wenn eine neue FOO
in der Datenbank erstellt wird. Der narrensicherste Ort, um sie zu platzieren, ist ein Einfügetrigger in der FOO-Tabelle.
Das einzige Mal, dass wir Trigger verwenden, ist für wirklich einfache Dinge wie das Einstellen der ModifiedDate
.
Antworten:
Die Hauptprobleme mit Triggern sind
Dies bedeutet nur, dass sie unter den richtigen Umständen sorgfältig verwendet werden müssen. was meiner Erfahrung nach auf relationale Integritätsprobleme beschränkt ist (manchmal mit einer feineren Granularität, als Sie deklarativ erhalten können); und normalerweise nicht für geschäftliche oder Transaktionszwecke. YMMV.
quelle
Nein, sie sind eigentlich eine gute Idee. Wenn es ein Problem mit Ihren spezifischen Triggern gibt, dann machen Sie sie nicht richtig, aber das bedeutet normalerweise, dass es ein Problem mit Ihrer Implementierung gibt, nicht das Konzept der Trigger selbst :-).
Wir verwenden häufig Trigger, da dadurch die DBMS-spezifische Aktivität unter die Kontrolle der Datenbank gestellt wird, zu der sie gehört. Benutzer eines DBMS sollten sich nicht um solche Dinge kümmern müssen. Die Integrität der Daten liegt bei der Datenbank selbst, nicht bei den Anwendungen oder Benutzern, die sie verwenden. Ohne Einschränkungen und Auslöser und andere Funktionen in der Datenbank bleibt es den Anwendungen überlassen, die Regeln durchzusetzen, und es ist nur eine betrügerische oder fehlerhafte Anwendung / ein fehlerhafter Benutzer erforderlich, um die Daten zu zerstören.
Ohne Trigger wären beispielsweise wundersame Dinge wie automatisch generierte Spalten nicht vorhanden, und Sie müssten bei der Auswahl jeder Zeile eine Funktion verarbeiten. Dies beeinträchtigt wahrscheinlich die DBMS-Leistung. Es ist weitaus besser, die automatisch generierte Spalte beim Einfügen / Aktualisieren zu erstellen, da dies das einzige Mal ist, dass sie sich ändert.
Außerdem würde das Fehlen von Triggern verhindern, dass Datenregeln im DBMS erzwungen werden, z. B. Vor-Trigger, um sicherzustellen, dass Spalten ein bestimmtes Format haben. Beachten Sie, dass sich dies von Datenintegritätsregeln unterscheidet, bei denen es sich im Allgemeinen nur um Fremdschlüssel-Lookups handelt.
quelle
Werkzeuge sind niemals böse. Anwendungen dieser Tools können böse sein.
quelle
Genau. Das Problem mit Auslösern sind Menschen, keine Auslöser. Obwohl es mehr zu betrachten, mehr zu berücksichtigen und die Verantwortung für Codierer zu erhöhen ist, die Dinge korrekt zu überprüfen, verwerfen wir keine Indizes, um unser Leben einfacher zu machen. (Schlechte Indizes können genauso schlecht sein wie schlechte Trigger)
Die Bedeutung von Triggern (meiner Meinung nach) ist, dass ...
- Jedes System sollte immer in einem gültigen Zustand sein
- Code zur Durchsetzung dieses gültigen Zustands sollte zentralisiert sein (nicht in jedem SP geschrieben)
Unter Wartungsgesichtspunkten ist ein Auslöser sehr nützlich für konkurrierende Programmierer und Probleme für jüngere / Amateur-Programmierer. Dennoch müssen diese Menschen lernen und irgendwie wachsen.
Ich denke, es kommt auf Ihr Arbeitsumfeld an. Haben Sie zuverlässige Leute, die gut lernen und denen man vertrauen kann, dass sie methodisch sind? Wenn nicht, haben Sie anscheinend zwei Möglichkeiten:
- Akzeptieren Sie, dass Sie die Funktionalität verlieren müssen, um dies zu kompensieren.
- Akzeptieren Sie, dass Sie andere Personen oder eine bessere Schulung und Verwaltung benötigen
Sie klingen hart und ich denke, dass sie es sind. Aber es ist die grundlegende Wahrheit in meinen Augen ...
quelle
Ich denke, Trigger sind nicht nur nicht böse, sondern für ein gutes Datenbankdesign notwendig. Anwendungsprogrammierer glauben, dass Datenbanken nur von ihrer Anwendung betroffen sind. Sie sind oft falsch. Wenn die Datenintegrität unabhängig von der Herkunft der Datenänderung aufrechterhalten werden soll, sind Auslöser erforderlich, und es ist dumm, sie zu vermeiden, da einige Programmierer zu ethnozentrisch sind, um zu berücksichtigen, dass etwas anderes als ihre wertvolle Anwendung Auswirkungen auf die Dinge haben kann. Es ist nicht schwer, einen Trigger zu entwerfen, zu testen oder Fehler zu beheben, wenn Sie ein kompetenter Datenbankentwickler sind. Es ist auch nicht schwierig festzustellen, dass ein Auslöser ein unerwartetes Ergebnis verursacht, wenn es Ihnen (wie mir) einfällt, dort nachzuschauen. Wenn ich eine Fehlermeldung erhalte, dass eine Tabelle, auf die ich in meinem SP nicht verweise, einen FK-Fehler aufweist, Ich weiß, ohne darüber nachzudenken, dass der Auslöser das Problem verursacht, und das sollte auch jeder kompetente Datenbankentwickler tun. Das Einfügen von Geschäftsregeln nur in die Anwendung ist die häufigste Ursache für schlechte Daten, da andere keine Ahnung haben, dass diese Regel überhaupt existiert, und sie in ihren Prozessen verletzen. Datenzentrierte Regeln gehören in die Datenbank, und Trigger sind der Schlüssel zur Durchsetzung der komplexeren Regeln.
quelle
some programmers are too ethnocentric to consider that something other than their prized application may be affecting things
Meistens ja.
Die Schwierigkeit mit einem Auslöser besteht darin, dass er Dinge "hinter deinem Rücken" macht; Der Entwickler, der die Anwendung verwaltet, konnte leicht nicht erkennen, dass sie vorhanden ist, und Änderungen vornehmen, die die Dinge vermasseln, ohne es zu merken.
Es entsteht eine Komplexitätsebene, die lediglich Wartungsarbeiten hinzufügt.
Anstatt einen Trigger zu verwenden, kann eine gespeicherte Prozedur / Routine im Allgemeinen dazu gebracht werden, dasselbe zu tun, jedoch auf klare und wartbare Weise. Wenn eine gespeicherte Routine aufgerufen wird, kann der Entwickler ihren Quellcode überprüfen und genau sehen, was passiert.
quelle
Trigger sind äußerst leistungsfähig und nützlich. Es gibt eine Reihe von Szenarien, in denen ein Trigger die beste Lösung für ein Problem darstellt.
Sie sind auch ein sehr gutes "Hack" -Tool. Es gibt häufig Situationen, in denen Sie nicht sofort die Kontrolle über den Code und die Datenbank haben. Wenn Sie 2 Monate auf die nächste Hauptversion Ihres Codes warten müssen, aber sofort einen Patch auf Ihre Datenbank anwenden können, können Sie einen Auslöser für eine Tabelle setzen, um einige zusätzliche Funktionen auszuführen. Wenn die Codefreigabe möglich ist, können Sie diesen Trigger bei Bedarf durch Ihre codierte Version derselben Funktionalität ersetzen.
Am Ende des Tages ist alles "böse", wenn Sie nicht wissen, was es tut. Zu entscheiden, dass Auslöser sind, weil es Entwickler gibt, die sie nicht verstehen, ist dasselbe wie zu argumentieren, dass Autos böse sind, weil manche Leute nicht fahren können ...
quelle
Trigger haben ihre Verwendung - Protokollierung / Prüfung und Beibehaltung eines "letzten Änderungsdatums" sind zwei sehr gute Verwendungen, die in früheren Antworten erwähnt wurden.
Einer der Grundpfeiler eines guten Designs ist jedoch, dass Geschäftsregeln / Geschäftslogik / wie auch immer Sie es nennen möchten, an einem einzigen Ort konzentriert sein sollten. Das Einfügen eines Teils der Logik in die Datenbank (über Trigger oder gespeicherte Prozesse) und eines Teils in die Anwendung verstößt gegen dieses Prinzip. Das Duplizieren der Logik an beiden Stellen ist noch schlimmer, da sie immer nicht mehr miteinander synchron sind.
Es gibt auch das bereits erwähnte Thema "Prinzip der geringsten Überraschung".
quelle
Trigger sind ein gutes Werkzeug, wenn sie richtig verwendet werden. Insbesondere für Dinge wie das Überwachen von Änderungen, das Auffüllen von Zusammenfassungstabellen usw.
Jetzt können sie "böse" sein, wenn Sie mit einem Auslöser, der andere Auslöser auslöst, in der "Trigger-Hölle" landen. Ich habe einmal an einem COTS-Produkt gearbeitet, bei dem sie sogenannte "Flex-Trigger" hatten. Diese Trigger wurden in einer Tabelle gespeichert, da bei jeder Ausführung dynamische SQL-Stings kompiliert wurden. Kompilierte Trigger würden nachschlagen, ob in dieser Tabelle Flex-Trigger ausgeführt werden könnten, und dann den "Flex" -Trigger kompilieren und ausführen. Theoretisch klang dies nach einer wirklich coolen Idee, da das Produkt leicht angepasst werden konnte, aber die Realität war, dass die Datenbank aufgrund all der Kompilierungen, die sie durchführen musste, ziemlich explodierte ...
Also ja, sie sind großartig, wenn Sie das, was Sie tun, im Blick behalten. Wenn es etwas ziemlich Einfaches wie Prüfen, Zusammenfassen, automatische Sequenzierung usw. ist, kein Problem. Denken Sie nur an die Wachstumsrate der Tabelle und daran, wie sich der Auslöser auf die Leistung auswirkt.
quelle
Auf hoher Ebene gibt es zwei Anwendungsfälle für Trigger1
1) Um Dinge "automatisch" geschehen zu lassen. In diesem Fall verursachen Trigger einen Nebeneffekt. Sie ändern Daten auf eine Weise, die aufgrund des (primitiven) Einfügens, Aktualisierens oder Löschens des Operators, der ausgeführt wurde und den Trigger ausgelöst hat, nicht erwartet wurde.
Der allgemeine Konsens hier ist, dass Auslöser tatsächlich schädlich sind. Weil sie die bekannte Semantik einer INSERT-, UPDATE- oder DELETE-Anweisung ändern. Durch Ändern der Semantik dieser drei primitiven SQL-Operatoren werden andere Entwickler gebissen, die später in Zukunft an Ihren Datenbanktabellen arbeiten müssen, die sich nicht mehr wie erwartet verhalten, wenn sie mit den SQL-Primitiven bearbeitet werden.
2) Zur Durchsetzung von Datenintegritätsregeln, die nicht deklarativ behandelt werden können (mit CHECK, PRIMARY KEY, UNIQUE KEY und FOREIGN KEY). In diesem Anwendungsfall müssen die Trigger lediglich QUERY (SELECT) -Daten eingeben, um zu überprüfen, ob die durch INSERT / UPDATE / DELETE vorgenommene Änderung zulässig ist oder nicht. Genau wie deklarative Einschränkungen für uns. Nur in diesem Fall haben wir (die Entwickler) die Durchsetzung programmiert.
Die Verwendung von Triggern für den letzteren Anwendungsfall ist nicht schädlich.
Ich blogge darüber unter: http://harmfultriggers.blogspot.com
quelle
Ich weiß, dass Entwickler, die der Meinung sind, dass Trigger immer dort eingesetzt werden sollten, wo dies der direkteste Weg ist, um die gewünschte Funktionalität zu erreichen, und Entwickler, die dies niemals tun werden. Es ist fast wie ein Dogma zwischen den beiden Lagern.
Ich persönlich stimme MarkR jedoch voll und ganz zu - Sie können (fast) immer Code schreiben, der funktional dem Trigger entspricht, der übersichtlicher und daher einfacher zu warten ist.
quelle
Nicht böse. Sie vereinfachen tatsächlich Dinge wie
1. Protokollierung / Überwachung von Änderungen an Datensätzen oder sogar Datenbankschemata
Sie könnten einen Auslöser für ALTER TABLE haben, der Änderungen in Ihrer Produktionsumgebung rückgängig macht. Dies sollte versehentliche Änderungen an der Tabelle verhindern.
2.Erzwingen der referenziellen Integration (Primär- / Fremdschlüsselbeziehungen usw.) über mehrere Datenbanken hinweg
quelle
ALTER TABLE
.Nein, sie sind nicht böse - sie werden nur missverstanden :-D
Trigger haben eine gültige Verwendung, aber viel zu oft als Retro-Hack, der die Dinge letztendlich noch schlimmer macht.
Wenn Sie eine Datenbank als Teil einer Anwendung entwickeln, sollte sich die Logik immer im Code oder in den Sprocs befinden, die den Aufruf ausführen. Trigger führen später nur noch zu Debug-Schmerzen.
Wenn Sie verstehen, wie Sperren, Deadlocking und wie DBs auf Dateien auf der Festplatte zugreifen, kann die richtige Verwendung von Triggern (z. B. Überwachung oder Archivierung des direkten DB-Zugriffs) sehr hilfreich sein.
quelle
Zu sagen, dass sie böse sind, ist eine Übertreibung, aber sie können zu Maschen führen. Wenn das Auslösen eines Auslösers dazu führt, dass andere Auslöser ausgelöst werden, wird dies sehr kompliziert. Angenommen, sie sind problematisch: http://www.oracle.com/technology/oramag/oracle/08-sep/o58asktom.html
Das Ausführen von Geschäftslogik in Oracle mit Triggern ist aufgrund von Problemen mit mehreren Parallelitäten schwieriger als es scheint. Sie sehen keine Änderungen in einer anderen Sitzung, bis die anderen Sitzungen festgeschrieben sind.
quelle
Sie sind definitiv nicht böse. Ich fand Trigger wertvoll beim Umgestalten von Datenbankschemata, beim Umbenennen einer Spalte oder beim Aufteilen einer Spalte in zwei Spalten oder umgekehrt (Beispiel: Groß- / Kleinschreibung) und beim Übergang.
Sie sind auch sehr nützlich für die Prüfung.
quelle
Diese Antwort gilt speziell für SQL Server. (obwohl es auch für andere RDBMS - Systeme anwenden habe ich keine Ahnung. Ich hätte es als eine Antwort zu geben , hier aber das war als Betrogene diesen geschlossen.)
Ein Aspekt, der in keiner der Antworten bisher erwähnt wurde, ist die Sicherheit. Da Trigger standardmäßig im Kontext des Benutzers ausgeführt werden, der die Anweisung ausführt, die den Trigger auslöst, kann dies eine Sicherheitsbedrohung verursachen, sofern nicht alle Trigger überprüft werden.
Das in BOL unter der Überschrift " Verwalten der Triggersicherheit " angegebene Beispiel zeigt einen Benutzer, der einen Trigger mit dem Code erstellt,
GRANT CONTROL SERVER TO JohnDoe ;
um seine eigenen Berechtigungen zu erweitern.quelle
Wenn es Nebenwirkungen gibt, ist dies ein Problem. In einigen Datenbanksystemen gibt es keine andere Möglichkeit, ein Autoincrement-Feld festzulegen, dh für ein Primärschlüssel-ID-Feld.
quelle
Ich denke, sie können böse sein, aber nur so böse wie alles andere in der Entwicklung.
Obwohl ich nicht wirklich viel Erfahrung mit ihnen habe, hatte ich sie kürzlich bei einem Projekt, an dem ich gearbeitet habe, was mich zu diesem Schluss geführt hat. Das Problem, das ich mit ihnen habe, ist, dass sie dazu führen können, dass Geschäftslogik an zwei Orten landet, einer Codebibliothek und einer Datenbank.
Ich sehe es als ein ähnliches Argument bei der Verwendung von Sprocs. Oft haben Sie Entwickler, die wirklich gut darin sind, SQL-Geschäftslogik in die Datenbank zu schreiben, während Leute, die dies nicht tun, ihre Geschäftslogik anderswo haben.
Meine Faustregel lautet also: Sehen Sie sich die Struktur Ihres Projekts an. Wenn es sinnvoll erscheint, Geschäftslogik in der Datenbank zu speichern, kann es nützlich sein, Trigger zu haben.
quelle
In der Tat werden Auslöser häufig missbraucht. Eigentlich braucht man sie in den meisten Fällen gar nicht. Aber das macht sie nicht unbedingt schlecht.
Ein Szenario, das mir in den Sinn kommt, in dem Trigger nützlich sind, ist, wenn Sie eine Legacy-Anwendung haben, für die Sie den Quellcode nicht haben und es keine Möglichkeit gibt, ihn zu ändern.
quelle
Die Idee der Auslöser ist nicht böse, die Begrenzung der Verschachtelung der Auslöser ist böse.
quelle