Pro und Kontra, Logik in SQL zu setzen?

7

Bei einem neuen Job wurde ich gerade mit dem Konzept konfrontiert, Logik in SQL-Anweisungen zu stecken.

In MySQL wäre ein dummes Beispiel wie folgt:

%Vor%

Für ein realistischeres Beispiel entscheiden Sie vielleicht, ob ein Verkäufer für einen Bonus qualifiziert ist. Sie können sich verschiedene Verkaufszahlen schnappen und einige Berechnungen in Ihrer SQL-Abfrage durchführen, und Sie geben wahr / falsch als Spaltenwert mit der Bezeichnung "qualifications" zurück.

Bisher hätte ich alle Verkaufsdaten aus der Abfrage zurückerhalten und dann die Berechnung in meinem Anwendungscode durchgeführt.

Das scheint mir besser, denn wenn nötig, kann ich mit einem Debugger Schritt für Schritt durch die Anwendungslogik gehen, aber was auch immer die Datenbank macht, ist für mich eine Blackbox. Aber ich bin ein Junior-Entwickler, also weiß ich nicht, was normal ist.

Was sind die Vor- und Nachteile, wenn der Datenbankserver einige Ihrer Berechnungen / Logik ausführen soll?

** Codebeispiel basierend auf Monty Python-Skizze.

    
Nathan Long 22.07.2010, 14:04
quelle

10 Antworten

7

Auf diese Weise wird SQL Teil Ihres Domänenmodells . Es ist ein weiterer (und nicht notwendigerweise naheliegender) Ort, an dem Domänenwissen implementiert wird. Solche Lecks führen zu einer engeren Kopplung zwischen Geschäftslogik / Anwendungscode und Datenbank , was normalerweise eine schlechte Idee ist.

Eine Ausnahme sind Views, Reportabfragen usw. Aber diese sind normalerweise so isoliert, dass es offensichtlich ist, welche Rolle sie spielen.

    
Konrad Garus 22.07.2010 14:16
quelle
7

Einer der überzeugendsten Gründe, Logik in die Datenbank zu pushen, ist die Minimierung des Datenverkehrs. Im Beispiel gibt es wenig Gewinn, da Sie die gleiche Menge an Daten abrufen, ob die Logik in der Abfrage oder in Ihrer App ist.

Wenn Sie nur Benutzer mit dem Vornamen Michael holen möchten, ist es sinnvoller, die Logik auf dem Server zu implementieren. Tatsächlich macht es in diesem einfachen Beispiel keinen großen Unterschied, da Sie Benutzer angeben können, deren Nachname Baldwin ist. Aber betrachten Sie ein interessanteres Problem, bei dem Sie jedem Benutzer einen "Beliebtheitsscore" geben, der sich danach richtet, wie häufig die Vor- und Nachnamen sind, und Sie die 10 "beliebtesten" Nutzer holen möchten. Die Berechnung der "Beliebtheit" in der App würde bedeuten, dass Sie jeden einzelnen Benutzer abholen müssen, bevor Sie ihn klassifizieren, sortieren und lokal auswählen. Wenn Sie es auf dem Server berechnen, können Sie nur 10 Zeilen über die Leitung abrufen.

    
Marcelo Cantos 22.07.2010 23:11
quelle
3

Es gibt nicht viele absolute Vor- und Nachteile für dieses Argument, also lautet die Antwort: "Es kommt darauf an." Einige Szenarien mit unterschiedlichen Bedingungen, die diese Entscheidung beeinflussen, können sein:

Client-Server-App

Ein Beispiel für einen Ort, an dem dies angebracht sein könnte, ist ein älteres 4GL oder Rich Client -Anwendung, bei der alle Datenbankoperationen durch Stored Procedure-basierte Aktualisierung durchgeführt wurden, Einfügen, Löschen von Sprocs. In diesem Fall bestand der Kern der Architektur darin, dass die Sprocs als Hauptschnittstelle für die Datenbank fungierten und alle Geschäftslogiken, die sich auf bestimmte Entitäten bezogen, an einem Ort gelebt wurden.

Diese Art von Architektur ist heutzutage etwas unmodern, aber an einem Punkt wurde es als der beste Weg betrachtet, dies zu tun. Viele VB Oracle Forms, Informix 4GL und andere Client-Server-Apps der Ära waren wie gemacht das und es funktioniert eigentlich ziemlich gut.

Es ist jedoch nicht ohne seine Nachteile - SQL ist nicht besonders gut in der Abstraktion, also ist es ziemlich einfach, mit ziemlich stumpfem SQL-Code zu enden, der ein Wartungsproblem darstellt, weil es schwer zu verstehen und nicht so modular ist, wie man es gerne hätte.

Ist es heute noch relevant? Ziemlich oft ist ein Rich Client die richtige Plattform für eine Anwendung und es gibt sicherlich viele neue Entwicklungen mit Winforms und Swing. Wir haben heute gute Open-Source-ORMs, bei denen eine Oracle Forms-App aus dem Jahr 1995 möglicherweise nicht die Möglichkeit hatte, diese Art von Technologie zu verwenden. Die Entscheidung, ein ORM zu verwenden, ist jedoch sicherlich kein Schwarz-Weiß-Verfahren - Fowlers Patterns of Enterprise Application Architecture kann ziemlich gut eine Reihe von Datenzugriffsstrategien durchlaufen und ihre relativen Vorteile diskutieren.

Dreistufige App mit Rich-Objekt-Modell

Diese Art von App verwendet den umgekehrten Ansatz und platziert die gesamte Geschäftslogik in der Modellobjektschicht der mittleren Ebene mit einer relativ dünnen Datenbankschicht (oder einem Standardmechanismus wie ORM ). In diesem Fall versuchen Sie, die gesamte Anwendungslogik in der mittleren Ebene zu platzieren. Die Datenzugriffsschicht hat relativ wenig Intelligenz, außer vielleicht für eine Handvoll gespeicherter Prozeduren, die benötigt werden, um die Grenzen eines ORM zu umgehen.

In diesem Fall wird die SQL-basierte Geschäftslogik auf ein Minimum beschränkt, da das Haupt-Repository der Anwendungslogik die mittlere Ebene ist.

Überhöhte Batch-Prozesse

Wenn Sie einen periodischen Lauf durchführen müssen, um Datensätze auszuwählen, die einige komplexe Kriterien erfüllen, und etwas damit zu tun haben kann geeignet sein, dies als gespeicherte Prozedur zu implementieren. Für etwas, das möglicherweise über einen beträchtlichen Teil einer anständigen Datenbank gehen muss, wird ein Sproc-basierter Ansatz wahrscheinlich der einzige vernünftig performante Weg sein, um so etwas zu tun.

In diesem Fall ist SQL möglicherweise der geeignete Weg, dies zu tun, obwohl traditionelle 3GLs (insbesondere COBOL) speziell für diese Art der Verarbeitung entwickelt wurden. In Umgebungen mit sehr hohem Datenaufkommen (insbesondere Mainframes) kann diese Art der Verarbeitung mit Flat- oder VSAM-Dateien außerhalb einer Datenbank der schnellste Weg sein, dies zu tun. Darüber hinaus können einige Jobs inhärent rekordorientiert und prozedural sein oder bei einer Implementierung auf diese Weise viel transparenter und aufrechterhaltbar sein.

Um Ed Post zu paraphrasieren, "Sie können COBOL in jeder Sprache schreiben" - obwohl Sie es könnten will nicht. Wenn Sie es in der Datenbank behalten wollen, verwenden Sie SQL, aber es ist sicherlich nicht das einzige Spiel in der Stadt.

Berichterstellung

Die Art der Berichttools diktiert tendenziell die Mittel zur Kodierung der Geschäftslogik. Die meisten sind so konzipiert, dass sie mit SQL-basierten Datenquellen arbeiten können, so dass die Art des Tools die Wahl zwingt.

Andere Domänen

Einige Anwendungen wie die ETL-Verarbeitung sind möglicherweise gut für SQL geeignet. ETL-Tools werden nicht mehr benötigt, wenn die Transformation zu komplex wird. Daher sollten Sie sich für eine Stored Procedure-basierte Architektur entscheiden. Mischen von Abfragen und Transformationen über Extraktion, ETL-Verarbeitung und Stored-Proc-basierte Verarbeitung kann zu einem Transformationsprozess führen, der schwer zu testen und zu beheben ist.

Wo Sie einen signifikanten Teil Ihrer Logik in sprocs haben, ist es vielleicht besser, die ganze Logik in diese zu stecken, da es Ihnen eine relativ homogene und modulare Codebasis gibt. In der Tat habe ich es ziemlich gut, dass etwa die Hälfte aller Data-Warehouse-Projekte im Banken- und Versicherungssektor auf diese Weise als explizite Design-Entscheidung durchgeführt werden - genau aus diesem Grund.

    
quelle
2

Oftmals hängt die Antwort auf diese Art von Frage sehr stark vom Bereitstellungsansatz ab. Wo es am sinnvollsten ist, Ihre Logik zu platzieren, hängt davon ab, auf was Sie zugreifen müssen, wenn Sie Änderungen vornehmen.

Bei Web-Anwendungen, die nicht kompiliert werden, kann es einfacher sein, mit Änderungen an einer Seite oder Datei umzugehen, als mit Abfragen zu arbeiten (je nach Komplexität der Abfrage, Programmierhintergrund / Know-how usw.). In solchen Situationen ist die Logik in der Skriptsprache normalerweise in Ordnung und erleichtert die spätere Überarbeitung.

Im Fall von Desktop-Anwendungen, die mehr Aufwand beim Ändern erfordern, kann es von Vorteil sein, wenn Sie diese Art von Logik in die Datenbank einfügen, wo sie angepasst werden kann, ohne dass eine Neukompilierung der Anwendung erforderlich ist. Wenn eine Entscheidung getroffen wurde, dass Leute sich bei 20k für Boni qualifiziert haben, aber jetzt 25k verdienen müssen, wäre es viel einfacher, dies auf dem SQL Server anzupassen, als beispielsweise Ihre Buchhaltungsanwendung für alle Benutzer neu zu kompilieren.

    
g.d.d.c 22.07.2010 14:13
quelle
2

Ich bin ein starker Befürworter, so viel Logik wie möglich direkt in die Datenbank zu bringen. Das bedeutet, es in Ansichten und gespeicherte Prozeduren zu integrieren. Ich glaube, dass die meisten dem DRY-Prinzip folgen.

Betrachten Sie beispielsweise eine Tabelle mit den Spalten FirstName und LastName und eine Anwendung, die häufig ein FullName-Feld verwendet. Sie haben drei Möglichkeiten:

  1. Abfrage des Vor- und Nachnamens und Berechnung des vollständigen Namens im Anwendungscode.

  2. Fragen Sie beim Abfragen der Tabelle zuerst, zuletzt und (zuerst || last) im SQL Ihrer Anwendung ab.

  3. Definieren Sie eine Ansicht CustomerExt, die die erste und die letzte Spalte sowie eine berechnete Spalte für den vollständigen Namen enthält, und führen Sie dann eine Abfrage dieser Ansicht statt der Kundentabelle durch.

Ich glaube, Option 3 ist eindeutig richtig. Berücksichtigen Sie das Hinzufügen eines MiddleInitial-Felds zu der Tabelle und der vollständigen Namensberechnung. Mit Option 3 müssen Sie einfach die Ansicht ersetzen, und jede Anwendung in Ihrem Unternehmen verwendet sofort das neue Format für FullName. Die Ansicht macht die Basisspalten immer noch für jene Instanzen verfügbar, in denen Sie spezielle Formatierungen vornehmen müssen, aber für die Standardinstanz funktioniert alles "automatisch".

Das ist ein einfacher Fall, aber das Prinzip ist das gleiche für komplexere Situationen. Führen Sie anwendungs- oder unternehmensweite Datenlogik direkt in der Datenbank aus, und Sie müssen sich nicht darum kümmern, dass verschiedene Anwendungen auf dem neuesten Stand gehalten werden.

    
Larry Lustig 22.07.2010 14:43
quelle
1

Dieses spezielle erste Beispiel ist eine schlechte Idee. Zeilenweise Funktionen skalieren nicht gut, wenn die Tabelle größer wird. Ein (wahrscheinlich) besserer Weg wäre es, LastName zu indizieren und etwas wie:

zu verwenden %Vor%

In Datenbanken, in denen Daten häufiger gelesen werden als geschrieben (und das sind die meisten), sollten diese Arten von Berechnungen zum Zeitpunkt des Schreibens durchgeführt werden, z. B. durch Einfügen / Aktualisieren eines echten FirstName -Feldes.

Datenbanken sollten zum Speichern und Abrufen von Daten verwendet werden, nicht durch massive nicht-datenbankbasierte Berechnungen, die alles verlangsamen.

    
paxdiablo 22.07.2010 14:26
quelle
0

Ein großer Profi: Eine Abfrage kann alles sein, womit Sie arbeiten können. Berichte wurden erwähnt: Viele Reporting-Tools oder Reporting-Plugins zu bestehenden Programmen erlauben es Benutzern nur, eigene Abfragen zu erstellen (deren Ergebnisse angezeigt werden).

Wenn Sie den Code nicht ändern können (weil er nicht Ihrer ist), können Sie eine Abfrage möglicherweise noch ändern. In einigen Fällen (Datenmigration) schreiben Sie auch Abfragen für die Migration.

    
Tobiasopdenbrouw 22.07.2010 14:14
quelle
0

Die Antwort hängt von Ihrem Fachwissen und Ihrer Vertrautheit mit den beteiligten Technologien ab. Auch wenn Sie ein technischer Manager sind, hängt es von Ihrer Analyse der Fähigkeiten der Personen ab, die in Ihrem Team arbeiten, und von wem Sie beabsichtigen, Mitarbeiter einzustellen, um die Anwendung in Zukunft zu unterstützen, zu erweitern und zu pflegen Wenn Sie in der Datenbank nicht alphabetisiert und kompetent sind (wie Sie nicht sind), dann bleiben Sie dabei, es in Code zu tun. Wenn otoh, Sie sind literarisch und kompetent in Datenbank-Codierung (wie Sie sein sollten), dann ist nichts falsch (und viel richtig) abput tun es in der Datenbank.

Zwei weitere Überlegungen, die Ihre Entscheidung beeinflussen könnten, sind, ob die Logik so komplex ist, dass sie im Datenbankcode ungleich komplexer oder abstrakter ist als im Code, und zweitens, wenn der Prozess Daten von außen benötigt die Datenbank (aus einer anderen Quelle) In jedem dieser Szenarien würde ich in Betracht ziehen, die Logik in ein Codemodul zu verschieben.

    
Charles Bretana 22.07.2010 14:14
quelle
0

Die Tatsache, dass Sie den Code in Ihrer IDE leichter durchgehen können, ist der einzige Vorteil Ihrer Nachverarbeitungslösung. Durch die Logik im Datenbankserver wird die Größe der Ergebnismengen oft drastisch reduziert, was zu weniger Netzwerkverkehr führt. Es ermöglicht auch dem Abfrageoptimierer, ein viel besseres Bild dessen zu erhalten, was Sie wirklich tun wollen, was wiederum oft eine bessere Leistung ermöglicht.

Daher würde ich fast immer SQL-Logik empfehlen. Wenn Sie eine Datenbank nur als dummes Geschäft behandeln, wird sie den Gefallen zurückgeben, indem sie sich dumm benimmt, und je nach Situation kann das Ihre Leistung völlig zunichtemachen - wenn nicht heute, vielleicht nächstes Jahr, wenn die Dinge in Gang gekommen sind ...

    
Kilian Foth 22.07.2010 14:15
quelle
0

Ich mag es, Daten von Geschäftsregeln zu unterscheiden und die Datenregeln so weit wie möglich in die gespeicherten Prozesse zu übertragen. Es gibt nicht immer eine feste Unterscheidung zwischen den beiden, aber in Ihrem Beispiel der Berechnung der Verkaufsprämien könnte die Formel selbst eine Geschäftsregel sein, aber die Arbeit der Sammlung und Aggregation der verschiedenen in der Formel verwendeten Zahlen ist eine Datenregel / p>

Manchmal hängt dies jedoch vom Bereitstellungsmodell und den Verfahren zur Änderungskontrolle ab. Wenn sich die Verkaufsformel häufig ändert und die Bereitstellung des Business-Layer-Codes umständlich ist, wäre es eine großartige Lösung, nur eine Funktion / einen gespeicherten Prozess in der Datenbank zu optimieren.

    
JeffSahol 22.07.2010 15:11
quelle

Tags und Links