Verwenden Sie MySQL-Trigger oder -Transaktionen?

8

Ich möchte Sie um Ihre Meinung zur Verwendung von MySQL-Triggern oder -Transaktionen auf einer Website bitten.

Eigentlich habe ich eine Geschichtstabelle paymentmit - UserId | OperationId | Comment | Credits | Sign (debit or credit). Daher wird jeder Zahlungsvorgang in diese Tabelle eingefügt.

Es ist jedoch zeitaufwändig, jedes Mal den Gesamtkreditbetrag des Benutzers zu berechnen, wenn er eine Aktion ausführt. Daher hielt ich es für eine gute Idee, den Gesamtkreditbetrag für jeden Benutzer in einer Benutzertabelle zu profilespeichern.

Hier ist das Problem. Wie kann ich sicher sein, dass der gesamte Kreditbetrag aus der profileTabelle mit den Vorgängen aus der paymentVerlaufstabelle synchronisiert bleibt ?

Ich dachte mit 2 Methoden:

  • MySQL löst aus oder
  • Transaktionen, die im Quellcode codiert sind

Welches ist zuverlässiger? Was ist, wenn ich eine große Datenbank habe (über 100.000 Benutzer)?

Haben Sie Vorschläge dazu?

Die BD MySQL Engine ist InnoDB.

Ek Kosmos
quelle

Antworten:

8

Ohne Zweifel würde ich Auslöser ausschließen und mich strikt an Transaktionen halten.

Trigger sind von Natur aus gespeicherte Prozeduren. Ihre Aktionen sind praktisch schwer rückgängig zu machen . Selbst wenn alle zugrunde liegenden Tabellen InnoDB sind, tritt ein proportionales Volumen an gemeinsam genutzten Zeilensperren und eine störende Unterbrechung durch exklusive Zeilensperren auf. Dies wäre der Fall, wenn Trigger Tabellen manipulieren würden, wobei INSERTs und UPDATEs stagnieren würden, um in jedem Aufruf eines Triggers ein Hochleistungs-MVCC auszuführen .

Kombinieren Sie dies mit der Tatsache, dass in der Stored Procedure Language von MySQL keine ordnungsgemäßen Datenvalidierungsprotokolle implementiert sind . Business Intelligence darf in einer Datenbank enthalten sein, sofern die Sprache für gespeicherte Prozeduren eine Transaktionsumgebung verarbeiten kann . Als MySQL-DBA muss ich ehrlich sagen, dass dies bei MySQL nicht der Fall ist. Oracle (PL / SQL), PostgreSQL (PL / pgSQL) und SQL Server (T-SQL) haben diesen Vorteil gegenüber MySQL.

In Bezug auf Transaktionen hat MySQL InnoDB als wichtigste ACID-kompatible Speicher-Engine (Deafult Storage Engine in MySQL 5.5). Es verfügt über eine hervorragende Wiederherstellung nach einem Absturz und befolgt die ACID-Konformitätsprotokolle.

Ich würde jedes Mal Transacitonen gegenüber Triggern wählen.

RolandoMySQLDBA
quelle
3

Ich stimme Rolandos Einschätzung zu. Ihre Geschäftslogik sollte sich in Ihrer Anwendung befinden und transaktional Änderungen an der Datenbank vornehmen.

Die Skalierung auf 100.000 Benutzer hängt natürlich von Ihrer Anwendung und dem von ihr generierten Datenbankverkehr ab. Wenn MySQL unter einer hohen Transaktionsschreiblast steht, werden Sie möglicherweise bald mit dem Aufwand konfrontiert, Ihr Dataset zu shardieren und / oder zu replizieren, um eine akzeptable Anwendungsantwort aufrechtzuerhalten.

Es gibt jedoch Alternativen zum Sharding von MySQL. Eines davon ist Clustrix (mein Arbeitgeber), ein parallel skalierbares Hochleistungs-SQL-Datenbanksystem mit einer Instanz. Es ist ein Cluster-Datenbanksystem, das sich als einzelner MySQL-Server präsentiert. Das nahtlose Skalieren der in diesem Thread beschriebenen Datenbank auf 100.000 Benutzer auf einer einzelnen Clustrix-Instanz würde kein Sharding und keine zusätzliche Anwendungslogik erfordern.

blbryant
quelle
+1 für gute Antwort und schamlosen Stecker für Clustrix. LOL !!!
RolandoMySQLDBA
1

Gute Antwort von Rolando.

Außerdem - Trigger sollten nicht für die Logik verwendet werden, da einige Dinge später zu einer Verwirrung führen, da die Dinge schnell verwirrend werden. Ein netter Satz von Anweisungen in einer gespeicherten Prozedur oder einer clientseitigen Prozedur kann die Geschäftslogik klarer vermitteln als eine Reihe versteckter Logik in der Datenbank. Es gibt auch Einschränkungen für Trigger in Bezug auf die Tabelle, von der sie ausgelöst werden. Daher können Sie feststellen, dass Sie Ihre Logik an zwei verschiedenen Stellen aufteilen.

Darüber hinaus finden Sie möglicherweise Möglichkeiten, um zu optimieren, wann diese Berechnungen in Ihrem Geschäftslogikserver stattfinden, während jedes Mal ein Auslöser ausgelöst wird. Sie werden feststellen, dass Sie den Trigger ausschalten, die Tabelle aktualisieren und dann den Trigger wieder aktivieren - was auch bedeutet, dass Sie die Triggerlogik in diesen Code einfügen müssen.

Darüber hinaus möchten Sie möglicherweise nicht die gesamte Logik im Geschäftslogikteil des Codes haben und die Tabellenintegrität mithilfe gespeicherter Prozeduren erzwingen. Dies kann eine Transaktion starten, mehrere Updates durchführen und dazu führen, dass die Dinge gut zurückgesetzt werden, wenn etwas fehlschlägt. Auf diese Weise kann jemand, der sich die Datenbank ansieht, beispielsweise die Logik zum Einfügen einer Bestellung erkennen. Dies ist in der heutigen Welt weniger wichtig, da Webdienste die einzige Zugriffsschnittstelle zur Datenbank sein können. In dem Fall, in dem mehrere ausführbare Dateien Zugriff auf die Datenbank haben, kann dies sehr groß sein.

Außerdem - Sie werden sowieso Transaktionen haben - werden Sie Ihre Trigger nicht ohne einen ausführen ... richtig? Es ist also gut zu wissen, wie man eine Transaktion startet. mach ein paar Sachen; und beenden Sie dann eine Transaktion. Wenn Sie dieses Muster in Ihrem Code sehen, wird ein weiterer Code, der es verwendet, die kognitive Belastung beeinträchtigen. Ein Trigger zwingt Sie, wenn Sie sich daran erinnern, dass er vorhanden ist, dazu, für die vom Trigger betroffenen Transaktionen anders zu denken, insbesondere wenn andere Tabellen eingezogen werden, die möglicherweise auch Trigger haben.

Grundsätzlich können Sie zwischen einem regelmäßig geplanten Cron-Job (oder einem Datenbankagenten-Job) und gut gespeicherten Prozeduren 99% der gewünschten Ergebnisse erzielen. Die 1%; Überdenken Sie das Projekt.

Gerard ONeill
quelle
Zusammenfassend wäre Ihr Rat eindeutig, NIEMALS EINEN TRIGGER in einer seriösen Anwendung mit Geschäftslogik zu verwenden?
Ifedi Okonkwo
Im Allgemeinen ja. Ich kann Situationen sehen, in denen Sie Auslöser haben, um seltsame, möglicherweise mehrzeilige Validierungen durchzuführen. Ich kann auch sehen, dass sie verwendet werden, um "Fakten" -Flaggen zu generieren - vielleicht ist dies nur eine Form der Zahlung, bei der das Ergebnis der Validierung irgendwo gespeichert wird. Ich kann sehen, dass sie für Aktualisierungen von Tabelleninformationen verwendet werden (z. B. ein Flag oder eine Tabelle, die angibt, welche Zeilen sich geändert haben). Egal wie einfach und sauber diese Implementierungen sind, ich würde dieses Zeug lieber in einer gespeicherten Prozedur oder in einer Datenbank-API (dh dem Modell) ausführen.
Gerard ONeill