Benötige ich wirklich Trigger für relationale Datenbanken, zum Beispiel PostgreSQL?

10

Ich weiß, dass Trigger verwendet werden können, um gespeicherte Daten zu validieren und die Datenbank konsistent zu halten. Führen Sie jedoch eine Validierung der Daten auf der Anwendungsseite durch, bevor Sie sie in der Datenbank speichern.

Zum Beispiel speichern wir Clients und möchten eine Validierung durchführen, die auf DDL-Ebene nicht einfach durchzuführen ist. https://severalnines.com/blog/postgresql-triggers-and-stored-function-basics

Ein weiteres Beispiel ist die Prüfung.

Aktualisieren

Wie Trigger und Datenbanktransaktionen zusammenarbeiten. Zum Beispiel, wenn ich eine Validierung der eingefügten Daten durchführen möchte. Dies erfolgt innerhalb einer Transaktion. Was passiert früher: Transaktion wird festgeschrieben oder Trigger ausgeführt?

Yan Khonski
quelle
However, why not perform validation of data on the application side before storing them into the database?Nun, diese beiden schließen sich nicht gegenseitig aus. Es ist wahrscheinlich, dass Sie auf beiden Seiten unterschiedliche Dinge validieren. Während die Validierungen auf der Anwendungsseite geschäftsorientiert sind, sind die Validierungen auf der Datenbank datenzentrierter. Denken Sie in einer Datenbank, die von mehreren und unterschiedlichen Anwendungen gespeist wird.
Laiv
Müssen Sie Daten von einer externen Quelle einfügen, die nur einen sinnlosen Datenauszug in Ihr System ausführt? In diesem Fall kann es vorkommen, dass Sie die Daten zur späteren Korrektur in einem ungültigen Format einfügen müssen. In diesem Fall verursachen Trigger endlose Probleme. Denken Sie daran. Manchmal möchten Sie nicht, dass ein Trigger ausgeführt wird.
Greg Burghardt
Ihr Update sollte eine eigene Frage sein, möglicherweise SO, aber Ihre Frage hat bereits eine Antwort auf Database Administrators.SE . Kurz gesagt, sogar ein "After Update" -Trigger wird ausgeführt, bevor die Transaktion festgeschrieben wird, und wenn eine Ausnahme innerhalb des Triggers ausgelöst wird, führt dies zu einem Rollback.
Doc Brown
@ GregBurghardt Die meisten Datenbanken verfügen über Anweisungen, mit denen Trigger für diese Art von Aktivitäten deaktiviert werden können.
Blrfl
1
@Blrfl: Ja, aber Sie müssen sich bewusst sein, dass diese Trigger vorübergehend für alle verbundenen Benutzer deaktiviert werden können, wenn Sie diese Überprüfungen nur für die aktuelle Sitzung unter bestimmten Bedingungen deaktivieren möchten.
Greg Burghardt

Antworten:

12

Dies hängt davon ab, welche Art von Anwendungssystem Sie erstellen:

  • Wenn Sie ein anwendungsorientiertes System erstellen, das nur eine Hauptanwendung enthält, mit einer dedizierten Datenbank speziell für diese Anwendung und idealerweise einem Team, das für die gleichzeitige Weiterentwicklung von Anwendung und Datenbank verantwortlich ist, können Sie die gesamte Validierungslogik und auch die Prüfung beibehalten Logik innerhalb der Anwendung.

    Der Hauptvorteil davon ist, dass Sie die Geschäftslogik nicht zwischen Anwendung und Datenbank verteilen müssen, sodass die Wartung und Weiterentwicklung des Systems häufig einfacher wird. Als Bonus binden Sie die Anwendung nicht zu stark an einen bestimmten DBMS- oder DBMS-Anbietertyp. Dieser Ansatz ist offensichtlich erforderlich, wenn Ihre Anwendung ein leichtes DB-System verwenden möchte, das keine Trigger bereitstellt.

  • Wenn Sie jedoch ein System erstellen, in dem viele verschiedene Anwendungen eine gemeinsame Datenbank gemeinsam nutzen und nicht vorhersehen können, welche Anwendungen in Zukunft darauf schreiben oder welche Teams in Zukunft Anwendungen zum Füllen von Daten in die Datenbank entwickeln, dann ist dies der Fall Es ist besser, wenn Ihre Datenbank dafür verantwortlich ist, so viel Datenkonsistenz wie möglich zu gewährleisten. Und hier werden Trigger wirklich hilfreich. In größeren Systemen reichen referenzielle Einschränkungen häufig nicht aus, aber ein Trigger, der eine gespeicherte Prozedur aufruft, kann nahezu jede Art von Validierung implementieren, die Sie benötigen.

Ein weiterer Grund für die Verwendung von Triggern kann die Leistung sein: In komplexen Datenmodellen treten nicht selten komplexe Konsistenzregeln auf, die die Verwendung vieler zusätzlicher Daten erfordern, die nicht Teil des aktuellen Arbeitssatzes sind, der in der Clientanwendung verfügbar ist. Das erstmalige Übertragen all dieser Daten über das Netzwerk, um eine Validierung auf der Clientseite zu ermöglichen, kann erhebliche Auswirkungen auf die Leistung haben.

Siehe auch diesen älteren SE-Beitrag: Anwendungslogik gegen DB-Trigger für die Datenbankbereinigung

Entscheiden Sie also selbst, welche Art von System Sie erstellen, und treffen Sie eine fundierte Entscheidung, ob Trigger das richtige Werkzeug für Ihren Fall sind oder nicht.

Doc Brown
quelle
3

Ich denke, die Frage betrifft die Verantwortung für die Qualität der Daten.

Die Antwort hängt davon ab, wie Sie das System sehen.

Wenn Sie die Datenbank als einen unabhängigen, eigenständigen und autonomen Dienst betrachten, der von der Anwendung getrennt ist, ist die Datenbank dafür verantwortlich, die Konsistenz und Qualität der darin enthaltenen Daten sicherzustellen. Im Wesentlichen, weil diese Datenbank von einer anderen Anwendung verwendet werden kann, sodass sie sich nicht darauf verlassen kann, dass diese zweite Anwendung das gleiche Konsistenz- und Qualitätsverhalten aufweist. Unter diesen Umständen muss die Datenbank so konzipiert sein, dass eine API und ein autonomes Verhalten verfügbar gemacht werden. In dieser Ansicht gibt es mindestens zwei Anwendungen, eine davon ist die Datenbank und die andere ist die Anwendung, die sie verwendet.

Umgekehrt könnte die Datenbank als eine komplizierte Form von Datei betrachtet werden, die unter der direkten und vollständigen Kontrolle der Anwendung steht. In diesem Sinne entwickelt sich die Datenbank zu einem reinen Serialisierungs- und Dokumentennavigationswerkzeug. Es bietet möglicherweise einige erweiterte Verhaltensweisen zur Unterstützung der Abfrage- und Dokumentwartung (wie dies bei JSON- oder XML-Tools der Fall ist), muss dies jedoch nicht (wie bei den meisten Dateistreams). In diesem Fall liegt es ausschließlich in der Verantwortung des Programms, das richtige Format und den richtigen Inhalt in der Datei beizubehalten. In dieser Ansicht gibt es eine Anwendung.

In beiden Ansichten lautet die nächste Frage, wie die Verwendung der Datenbank als ausgefallene Datei oder als separater Dienst unterstützt werden kann. Sie könnten dies erreichen durch:

  • Verwenden der von der Datenbankplattform bereitgestellten Tools in Form von Tabellen / Ansichten / gespeicherten Prozeduren / Triggern / etc ...
  • Umschließen der Datenbank selbst in einen Dienst, den alle Clients verwenden müssen, um auf die Datenbank zuzugreifen
  • Umschließen der Datenbank in eine Bibliothek, die von allen Clients verwendet werden muss, um auf die Daten zugreifen zu können.

Jedes hat seine eigenen Vor- und Nachteile und hängt von den architektonischen Einschränkungen der Umgebung ab, in der das System arbeitet.

Unabhängig davon, welche Ansicht Sie vertreten, lohnt es sich immer, Daten an Grenzen zu validieren.

  • Überprüfen Sie die Felder auf einer Benutzeroberfläche, die ein Benutzer eingibt
  • Überprüfen Sie die Netzwerk- / API-Anforderung, bevor sie den Client verlässt
  • Überprüfen Sie die Netzwerk- / API-Anforderung auf dem Server, bevor Sie etwas unternehmen
  • Überprüfen Sie die Daten, die an Geschäftsregeln übergeben werden
  • Überprüfen Sie die Daten, bevor Sie sie beibehalten
  • Überprüfen Sie die Daten, nachdem sie aus der Persistenz abgerufen wurden
  • so weiter und so fort

Wie viel Validierung an jeder Grenze erforderlich ist, hängt davon ab, wie riskant es ist, sie nicht zu validieren.

  • zwei Zahlen miteinander multiplizieren?
    • Sie bekommen die falsche Nummer ist das ein Problem?
  • Aufrufen einer Prozedur an einem bestimmten Speicherort?
    • Was ist in diesem Speicherort?
    • Was passiert, wenn das Objekt nicht existiert oder sich in einem schlechten Zustand befindet?
  • Verwenden Sie einen regulären Ausdruck für eine Zeichenfolge, die Kanji enthält?
    • Kann das Regex-Modul Unicode verarbeiten?
    • Kann der Regex mit Unicode umgehen?
Kain0_0
quelle
Die Zentralisierung der Validierungslogik ist gut, aber imho-Trigger sind keine gute Möglichkeit, dies zu implementieren. Ich habe auf einem System gearbeitet, auf dem mehrere Anwendungen eine Datenbank gemeinsam genutzt haben, wobei alle Validierungslogiken und Nebenwirkungen durch Trigger und gespeicherte Prozeduren in der Datenbank implementiert wurden. Ich hatte den Eindruck, dass es besser ist, einen Microservice vor der Datenbank zu haben und dort die gesamte Logik zu implementieren. Nicht triviale Logik in einer SQL-Datenbank ist ein Anti-Pattern.
Joeri Sebrechts
1
@JoeriSebrechts Okay, ich werde beißen: Warum ist nichttriviale Logik in einer Datenbank ein Antimuster, und was macht sie eher zu einem Antimuster, als sie in ein separat verwaltetes Programm zu stellen?
Blrfl
@Blrfl Zwei Gründe: Die API für den Zugriff auf die Logik in der Datenbank ist einer Webdienst-API unterlegen (schwieriger zu versionieren, schwieriger zu verwenden, nicht einfach zwischenzuspeichern, ...), und Datenbanken erschweren die saubere Strukturierung und Wartung der API Codebasis in ihnen gehostet. Nach meiner Erfahrung ist es einfacher, die Logik in einem Webdienst vor der Datenbank zu hosten als in dieser Datenbank.
Joeri Sebrechts
@JoeriSebrechts Ich stimme zu, dass die meisten Datenbankplattformen traurige Tools für die Implementierung einer glaubwürdigen, nützlichen und entwicklungsfähigen API bieten. In vielerlei Hinsicht ist es sicherlich eine Einladung, viel Schmerz zu fühlen. Mein Punkt war, dass es um die Perspektive geht und die Erkenntnis, dass es sich bei der Datenbank um eine ausgefallene Datei handelt oder dass es sich wirklich um einen separaten Dienst handelt, zur nächsten Frage führt, wie diese umbrochen werden soll, um diesen Verwendungsstil zu unterstützen. Ich werde meine Antwort ausarbeiten, um das klar zu machen.
Kain0_0
2

Nein, Sie sollten niemals Trigger verwenden, um die Validierung durchzuführen.

Die Datenbank ist nur für ihre eigene Integrität verantwortlich. Jede Benutzerüberprüfung sollte von Ihrer Anwendung durchgeführt werden.

Datenbanken führen drei Validierungsstufen für die Integrität durch. Die erste ist die Validierung auf Feldebene. Ein Feld kann erforderlich sein. Wenn kein Wert (null) vorhanden ist, handelt es sich um einen Fehler. Dies kann auch eine Prüfbedingung sein. Eine Domain hat eine aufgezählte Anzahl von Werten.

Zweitens gibt es Beziehungen zwischen Tabellen. In einer Tabelle speichern Sie einen oder mehrere Fremdschlüssel, verknüpfen diese Tabelle mit anderen Tabellen und verlangen, dass die Werte gültige Schlüssel für die "andere Tabelle" sind. Stellen Sie sich eine Adressdatenbank vor, in der wir Adressen verschiedener Länder unterstützen. Ein Länderschlüssel in einer Adresse muss auf ein bekanntes Land verweisen. Ob die Daten (z. B. eine Postleitzahl) gültig sind, spielt bei dieser Integritätsprüfung keine Rolle.

Drittens und am kompliziertesten sind Auslöser. In der Regel sollten diese (Wortspiel nicht beabsichtigt) Integritätsregeln betreffen, die an Bedingungen geknüpft sind. Um auf das Adressbeispiel zurückzukommen: Wenn ein Land keine Postleitzahl hat, wäre es ein Problem, wenn ein Land in dieser Liste eine Postleitzahl hätte. Die Prüfung wäre also: Wenn dieses Land keine Postleitzahlen hat, sollte das Postleitzahlenfeld null sein.

Die Validierung ist das Anliegen der Anwendung. Die Tatsache, dass eine deutsche Postleitzahl nur aus Ziffern besteht, ist eine Überprüfung, die der Antrag vornehmen sollte, nicht die Datenbank. Die Zeile ist dünn, daher müssen Sie in einigen Fällen möglicherweise überlegen / diskutieren, ob sich etwas in einem Auslöser (Schutz der Integrität Ihrer Datenbank) oder in der Anwendung (Validierung durch den Benutzer) befinden sollte.

Menno Hölscher
quelle
Ich wollte nur hinzufügen, dass das OP gespeicherte Prozeduren immer als sicherere Alternative verwenden kann, wenn es eine komplexe Validierungsregel hinzufügen muss, die in der Datenbank enthalten sein muss.
Borjab
@Borjab: Validierung, um die Datenbank korrekt zu halten. Aber Benutzer vor Validierung? Nr.
Menno Hölscher
1
Ihre erste Aussage lautet "Verwenden Sie niemals Trigger, um die Validierung durchzuführen" , aber unten schreiben Sie: "Ja, Sie können Trigger für bestimmte Arten der Validierung verwenden, und es ist nicht von Natur aus klar, wo die Grenze gezogen werden soll." Das liest sich ziemlich widersprüchlich. Ich würde empfehlen, Ihren ersten Satz zu löschen, um Ihre Antwort erheblich zu verbessern. Oh, und Ihr letzter Satz beantwortet die Frage zur Aktualisierung des OP nicht, da "vorher / nachher" nichts mit der Transaktion zu tun hat. Ich würde empfehlen, es auch zu löschen. (Siehe meinen Kommentar unter der OP-Frage).
Doc Brown
@DocBrown Der Unterschied besteht zwischen dem Schutz der Datenbank vor Beschädigung und der Validierung durch den Benutzer. In "jeder weiteren Validierung" beziehe ich mich also auf die Validierung durch den Benutzer. Wie könnte ich diese Unterscheidung klarer machen? Zu Beginn habe ich das "weiter" entfernt.
Menno Hölscher
2
Es ist vollkommen in Ordnung, eine Validierung in der Datenbank durchzuführen. So wie es in der Anwendung in Ordnung ist. Beide haben ihre Vorteile. Wenn Sie Ihre Validierung in der Anwendung durchführen, müssen Sie jedes Mal, wenn Sie SQL ohne Ihr ORM ausführen, das für nahezu jede komplexe App erforderlich ist, sehr vorsichtig sein.
Qwertie
1

Audit ist ein klassisches Beispiel für den effektiven Einsatz von Triggern. Ich habe einige Fehler gefunden, die der Tester (Verschieben eines Clients von einer Serviceebene auf eine andere) dank einer Audittabelle gemacht hat, die durch Trigger implementiert wurde. Ich empfehle dringend, Trigger für die Prüfung zu verwenden.

Die Validierung könnte im Front-End-Bereich erfolgen, aber ich habe seltsame Fehler in der Datenbank gesehen, die ich behandelt habe (Personen, die im Jahr 3000 geboren wurden usw.), und da einige von ihnen selbst erstellt wurden, empfehle ich dringend, eine zusätzliche Ebene zu verwenden der Validierung in der Datenbank, nur für den Fall. Natürlich können diese Fehlertypen mit Überprüfungsbeschränkungen vermieden werden und sind oftmals effektiver (in MS SQL sind sie die bevorzugte Methode; überprüfen Sie immer die Dokumentation).

Hila DG
quelle
1

Da es um die Frage geht, ob wir wirklich Trigger für relationale Datenbanken benötigen, gibt es hier einige andere Anwendungsfälle, in denen Trigger verwendet werden können:

  1. Zur Prüfung wie in den anderen Antworten beschrieben.
  2. Auditing im weiteren Sinne: Wenn ein Datenbankeintrag geändert wird, kann ein Trigger das Ereignis für die asychrone Nachbearbeitung aufzeichnen, z. B. nächtliche Exporte in eine andere Anwendung.
  3. Trigger für Ansichten: Trigger können definiert werden instead of. Mit diesem Mittel kann man Einträge aus einer Ansicht einfügen, aktualisieren und löschen. Die Trigger können diese Aktionen auf mehrere Tabellen verteilen. Auf diese Weise können Sie eine eingeschränkte Ansicht verfügbar machen, ohne die Details der zugrunde liegenden Tabellen offenzulegen.
  4. So speichern Sie Datenbankumkehrungen explizit: Nehmen Sie eine N: M-Beziehung zwischen Tabelle A und B und einer Zwischentabelle R an. Sie können Fremdschlüsseleinschränkungen von R nach A sowie B definieren und angeben, dass der Eintrag in R gelöscht werden soll, wenn dies der Fall ist entsprechender Eintrag in B wird gelöscht. Die Geschäftslogik erfordert jedoch manchmal, dass Einträge in A mindestens eine Beziehung zu einem Eintrag in B haben müssen. In diesem Fall kann ein Auslöser beim Löschen von R helfen, diese Logik durchzusetzen: Wenn für einen Eintrag in A der letzte Eintrag in R ist Wenn gelöscht wird, kann der Auslöser A löschen. In der anwendungszentrierten Ansicht sind mindestens zwei Umdrehungen erforderlich. Dies ist ein Beispiel für die Validierung. Weitere Beispiele sind denkbar: neben den Anwendungsfällen (1), (2),
  5. Vertrauen: Manchmal ändern Datenbankadministratoren Einträge in der Befehlszeile, ohne Ihre Anwendung zu verwenden. Administratoren arbeiten sorgfältig und wissen, was sie tun. Manchmal können sie jedoch falsch sein. Wenn die Konsistenz kritisch ist, ist der Sicherheitsgurt ein Auslöser.

Als Nachteil ist die Geschäftslogik auf die Schichten verteilt und dies ist ein Hauptnachteil für die Wartung. Wie ein anderer Autor schrieb, ist es eine dünne Grenze zwischen Anwendung und Datenbank und die Wahl ist nicht immer klar. Meine persönliche Meinung ist, dass Trigger die Entwickler belasten. Sie können Zeit in der Entwicklung sparen. Auf jeden Fall verbessern sie die Benutzererfahrung, da sie die Leistung über langsame Netzwerkverbindungen steigern.

Claude
quelle