Ich bin fest davon überzeugt, Geschäftslogik so weit wie möglich aus der Datenbank herauszuhalten. Als Performance-Entwickler meines Unternehmens weiß ich jedoch zu schätzen, dass es manchmal notwendig ist, eine gute Performance zu erzielen. Aber ich denke, es ist viel seltener nötig, als die Leute behaupten.
Ich bestreite Ihre Vor- und Nachteile.
Sie behaupten, dass es Ihre Geschäftslogik zentralisiert. Im Gegenteil, ich denke, es dezentralisiert es. In einem Produkt, an dem ich gerade arbeite, verwenden wir gespeicherte Prozeduren für einen Großteil unserer Geschäftslogik. Viele unserer Leistungsprobleme rühren von wiederholt aufgerufenen Funktionen her. Zum Beispiel
select <whatever>
from group g
where fn_invoker_has_access_to_group(g.group_id)
Das Problem bei diesem Ansatz ist, dass die Datenbank in der Regel (in manchen Fällen ist dies falsch) dazu gezwungen wird, Ihre Funktion N-mal pro Zeile auszuführen. Manchmal ist diese Funktion teuer. Einige Datenbanken unterstützen Funktionsindizes. Sie können jedoch nicht jede mögliche Funktion gegen jede mögliche Eingabe indizieren. Oder kannst du?
Eine gebräuchliche Lösung für das obige Problem besteht darin, die Logik aus der Funktion zu extrahieren und in die Abfrage einzufügen. Jetzt haben Sie die Kapselung und die duplizierte Logik unterbrochen.
Ein weiteres Problem, das ich sehe, ist das Aufrufen gespeicherter Prozeduren in einer Schleife, da es keine Möglichkeit gibt, gespeicherte Proc-Ergebnismengen zu verknüpfen oder zu schneiden.
declare some_cursor
while some_cursor has rows
exec some_other_proc
end
Wenn Sie den Code aus dem verschachtelten Prozess ziehen, dezentralisieren Sie ihn erneut. Daher müssen Sie zwischen Kapselung und Leistung wählen.
Im Allgemeinen finde ich, dass Datenbanken schlecht sind bei:
- Berechnung
- Iteration (sie sind für festgelegte Operationen optimiert)
- Lastverteilung
- Parsing
Datenbanken sind gut in:
- Sperren und Entsperren
- Pflege von Daten und deren Beziehungen
- Integrität sicherstellen
Indem Sie teure Vorgänge wie Schleifen und String-Parsing ausführen und in Ihrer App-Ebene belassen, können Sie Ihre Anwendung horizontal skalieren, um eine bessere Leistung zu erzielen. Das Hinzufügen mehrerer App-Server hinter einem Load Balancer ist in der Regel weitaus billiger als das Einrichten der Datenbankreplikation.
Sie haben jedoch Recht, dass dies Ihre Geschäftslogik von der Programmiersprache Ihrer Anwendung entkoppelt, aber ich verstehe nicht, warum dies ein Vorteil ist. Wenn Sie eine Java-App haben, haben Sie eine Java-App. Das Konvertieren einer Reihe von Java-Code in gespeicherte Prozeduren ändert nichts an der Tatsache, dass Sie über eine Java-App verfügen.
Ich bevorzuge es, den Fokus des Datenbankcodes auf die Persistenz zu legen. Wie erstelle ich ein neues Widget? Sie müssen in 3 Tabellen einfügen und diese müssen sich in einer Transaktion befinden. Das gehört in eine gespeicherte Prozedur.
Die Definition, was mit einem Widget geschehen kann, und die Geschäftsregeln für die Suche nach Widgets gehören in Ihre Anwendung.