Gespeicherte Prozeduren eine schlechte Praxis bei einem der weltweit größten Beratungsunternehmen für IT-Software?


148

Ich arbeite bei einem Projekt in einem der drei weltweit führenden IT-Beratungsunternehmen und wurde von einem DBA darauf hingewiesen, dass die in einem Best Practice-Verfahren gespeicherten Statusprozeduren kein "Best Practice" sind. Dies steht im Widerspruch zu allem, was ich gelernt habe.

Gespeicherte Prozeduren ermöglichen die Wiederverwendung von Code und die Kapselung (zwei Säulen der Softwareentwicklung), die Sicherheit (Sie können Berechtigungen für einen einzelnen gespeicherten Prozess erteilen / entziehen), schützen Sie vor SQL-Injection-Angriffen und beschleunigen die Ausführung (obwohl dies vom DBA angegeben wurde) Beginnend mit SQL Server 2008 werden sogar reguläre SQL-Abfragen kompiliert, wenn sie genügend oft ausgeführt werden.

Wir entwickeln eine komplexe App unter Verwendung der Agile-Softwareentwicklungsmethode. Kann sich jemand gute Gründe vorstellen, warum er gespeicherte Procs nicht verwenden möchte? Ich vermute, dass die Datenbankadministratoren diese gespeicherten Prozesse nicht beibehalten wollten, aber es scheint zu viele Negative zu geben, um eine solche Entwurfsentscheidung zu rechtfertigen.


3
Welche Wiederverwendung von Code wird hinzugefügt? Was ist, wenn Ihr Client eine andere Datenbank verwendet? Müssen alle diese SPs wegwerfen und von vorne anfangen. Schützen Sie sich nicht vor SQL-Injektionen. Die Geschwindigkeit ist in den meisten Fällen minimal.
Rig

32
Denken Sie daran, dass die meisten großen IT-Beratungsunternehmen das Motiv haben, die abrechnungsfähigen Stunden zu maximieren und dabei den Arsch zu bewahren. Die Oldtimer mit jeder Macht in diesen Firmen sind eher Spieler und Bürokraten als Technikfreaks. Ich würde so etwas von einem Beratungsunternehmen mit einem Körnchen Salz nehmen - ich habe Beratungsunternehmen mehr als einmal aus der Scheiße geholt, indem ich ihre 'beste' Praxis festgelegt habe.
ConcernedOfTunbridgeWells

1
Die Wiederverwendung von @Rig-Code wird wie für Funktionen jeder Sprache hinzugefügt - indem Code in einen wiederverwendbaren Container verpackt wird. Bestimmte gespeicherte Prozeduren schützen Sie tatsächlich vor SQL-Injection, solange Sie keine Zeichenfolge ausführen, die Sie erstellt haben. Zu sagen, dass die Geschwindigkeit minimal ist, scheint einfach ungebildet zu sein. Die meisten Fälle fallen in Bezug auf Leistungsvorteile nicht in die gleichen Kategorien, weisen jedoch große Unterschiede auf.
Garet Claborn

1
@GaretClaborn Es ist jedoch viel wahrscheinlicher, dass die Anwendungsschicht neu aufgebaut wird als jahrelange historische Datenbankdaten. Auf jeden Fall auf jeder nicht trivialen Anwendung. Und wenn Sie dies tun, werden Sie Monate damit verbringen, Rich-Code für gespeicherte Prozeduren zu portieren. Das Hinzufügen einer weiteren Abhängigkeit zu Ihrem Projekt hat nur in Randbedingungen Vorteile. Diese existieren, aber die meiste Zeit ist es nur eine weitere Hürde für die Agilität des Projekts und die Wiederverwendung von Code.
Rig

2
Ausgehend von einem Hintergrund, in dem wir fast ausschließlich sps verwendet haben, kann ich Ihnen den Vorteil erläutern, wenn Sie sich von ihnen entfernen und ein ORM-ähnliches Entity Framework verwenden. Viel zu oft wird Geschäftslogik in die Prozedur eingeschlossen. Sie können zwar Procs mit einigen Arbeits- und / oder Drittanbieter-Tools versionieren. Es ist nicht so einfach wie in einem Framework wie TFS oder GIT. Der von Ihnen ausgegebene Datenbankcode ist für Ihren RDBMS-Anbieter nicht relevant. So können Sie RDBMS-Provider zu einem späteren Zeitpunkt mit weniger Kopfschmerzen austauschen.
Ewahner

Antworten:


280

Nach meiner Erfahrung bei der Arbeit an sehr großen Projekten muss klar sein, wo Geschäftslogik lebt. Wenn Sie eine Umgebung zulassen, in der einzelne Entwickler Geschäftslogik nach eigenem Ermessen in die Geschäftsobjektschicht oder in eine gespeicherte Prozedur einfügen können, ist eine große Anwendung SEHR schwer zu verstehen und zu warten.

Gespeicherte Prozeduren sind ideal, um bestimmte DB-Vorgänge zu beschleunigen. Meine architektonische Entscheidung besteht darin, die gesamte Logik in der Geschäftsschicht der Anwendung zu belassen und gespeicherte Prozeduren gezielt einzusetzen, um die Leistung dort zu verbessern, wo das Benchmarking dies rechtfertigt.


37
Ich sehe die Dinge nicht so einfach. Für mich ist es ALLE Geschäftslogik. Die Datenbank mit oder ohne gespeicherte Prozeduren bietet bestimmte Dienste und gibt bestimmte Garantien. Im Idealfall sollte es für falschen Anwendungscode unmöglich sein, die Datenbank in einen inkonsistenten Zustand zu versetzen. Wenn gespeicherte Prozeduren benötigt werden, um diese Konsistenz aufrechtzuerhalten, verwende ich sie.
Kevin Cline

12
@ Kevin Cline: Definieren Sie "inkonsistenten Zustand". Ich bin damit einverstanden, dass DB-Funktionen wie die referenzielle Integrität wertvoll sind und die Wahrscheinlichkeit eines Anwendungsfehlers, der schwerwiegende Schäden verursacht, erheblich verringern. Grundsätzlich hängt die Definition von "konsistenten Daten" jedoch von der korrekten Ausführung von Geschäftsregeln ab.
Eric J.

16
füge meine Million zu Mayos Million hinzu. Die verteilte Geschäftslogik bringt Sie von der Autobahn der guten Praxis direkt auf die Spur des Wahnsinns
Nico,

27
+1 Das Eindringen von Geschäftslogik in die DAL ist bei der Verwendung gespeicherter Prozeduren von großer Bedeutung.
System Down

30
@ChristopherMahan, ich würde NIEMALS eine Datenbank verwenden wollen, die Sie entwerfen. Dies ist aus Datenbanksicht die schlechteste Vorgehensweise. Datenbanken sind häufig direkt an der Datenbank betroffen. Es ist kurzsichtig zu glauben, dass jemand die Business-Schicht verwenden wird, um eine Million Datensätze oder andere Dinge zu aktualisieren, die sich im Laufe der Zeit ereignen. Importe durchlaufen in der Regel nicht die Business-Schicht (ja, ich möchte meinen 21-Millionen-Datensatzimport nacheinander in der Business-Schicht verarbeiten). Betrug ist viel einfacher, wenn Sie keine Einschränkungen auf Datenbankebene haben. Schlechte Daten sind fast zu 100% sicher.
HLGEM

163

Einige Beobachtungen

Gespeicherte Prozeduren ermöglichen die Wiederverwendung von Code und die Kapselung (zwei Säulen der Softwareentwicklung).

Nur wenn Sie sie in dem Kontext verwenden, in dem sie verwendet werden sollen. Dieselbe Behauptung kann über Funktionen (in strukturierter Programmierung) oder Methoden (in objektorientierter Programmierung) aufgestellt werden, und dennoch sehen wir 1K-Funktionen und mega-ass-Objekte.

Artefakte bieten Ihnen diese Vorteile nicht. Die richtige Verwendung dieser Artefakte ist der Grund für diese Vorteile.

Sicherheit (Sie können Berechtigungen für einen einzelnen gespeicherten Prozess erteilen / entziehen),

Ja. Dies ist ein guter Punkt und einer der Hauptgründe, warum ich gespeicherte Prozeduren mag. Sie bieten eine feinere Zugriffskontrolle als dies normalerweise nur mit Ansichten und Benutzerkonten möglich ist.

schützen Sie vor SQL-Injection-Angriffen,

Dies ist für SPs nicht spezifisch, da Sie mit parametrisierten SQL-Anweisungen und Eingabebereinigung das gleiche Schutzniveau erreichen können. Ich würde jedoch zusätzlich zu diesen SPs aus Gründen der "Sicherheit in der Tiefe" verwenden .

und helfen auch mit Geschwindigkeit (obwohl der DBA sagte, dass ab SQL Server 2008 sogar reguläre SQL-Abfragen kompiliert werden, wenn sie genügend oft ausgeführt werden).

Dies ist in hohem Maße herstellerspezifisch für Datenbanken, aber im Allgemeinen hat Ihr DBA Recht. SQL-Anweisungen (entweder statisch oder parametrisiert) werden kompiliert. SPs helfen, wenn Sie Daten aggregieren und berechnen möchten / müssen, die Sie nicht mit einfachen SQL-Anweisungen ausführen können, die jedoch eng in SQL integriert sind und für die kein Roundtrip zum App-Server erforderlich ist.

Ein gutes Beispiel ist das Abfragen von Daten in einen temporären Cursor (oder Cursor), von dem aus ein anderes SQL ausgeführt werden soll. Sie können dies programmgesteuert auf dem App-Server tun, oder Sie können die Mehrfach-Roundtrips speichern, indem Sie dies in der Datenbank tun.

Dies sollte jedoch nicht die Norm sein. Wenn Sie viele dieser Fälle haben, ist dies ein Zeichen für einen schlechten Datenbankentwurf (oder Sie beziehen Daten aus nicht so kompatiblen Datenbankschemata abteilungsübergreifend).

Wir entwickeln eine komplexe App unter Verwendung der Agile-Softwareentwicklungsmethode.

Agilität hat mit Software-Engineering-Prozessen und Anforderungsmanagement zu tun, nicht mit Technologien.

Kann sich jemand gute Gründe vorstellen, warum er gespeicherte Procs nicht verwenden möchte?

Falsche Frage

Die Frage ist falsch und entspricht der Frage "Gibt es gute Gründe, GOTO nicht zu verwenden?" Ich stehe mehr auf der Seite von Niklaus Wirth als auf der Seite von Dijkstra. Ich kann verstehen, woher Dijkstras Gefühl kam, aber ich glaube nicht, dass es in allen Fällen zu 100% zutreffend ist. Gleiches gilt für Store Procs und jegliche Technologie.

Ein Werkzeug ist gut, wenn es für den vorgesehenen Zweck gut verwendet wird und wenn es das beste Werkzeug für die jeweilige Aufgabe ist. Andernfalls bedeutet dies nicht, dass das Werkzeug falsch ist, der Benutzer jedoch nicht weiß, was er tut.

Die richtige Frage lautet: "Welche Art von Nutzungsmustern für gespeicherte Prozeduren sollte vermieden werden?" Oder "unter welchen Bedingungen sollte ich gespeicherte Prozeduren verwenden (oder nicht)" . Wenn Sie nach Gründen suchen , eine Technologie nicht zu verwenden, geben Sie dem Werkzeug einfach die Schuld, anstatt die technische Verantwortung genau dort zu platzieren, wo sie hingehört - beim Ingenieur.

Mit anderen Worten, es ist eine Ausrede oder eine Erklärung der Unwissenheit.

Ich vermute, dass die Datenbankadministratoren diese gespeicherten Prozesse nicht beibehalten wollten, aber es scheint zu viele Negative zu geben, um eine solche Entwurfsentscheidung zu rechtfertigen.

Sie projizieren dann die Ergebnisse ihrer schlechten technischen Entscheidungen auf die Werkzeuge, die sie schlecht eingesetzt haben.

Was ist in Ihrem Fall zu tun?

Meine Erfahrung ist, wenn ich in Rom bin, mache ich es wie die Römer .

Kämpfe nicht dagegen an. Wenn die Leute in Ihrem Unternehmen Geschäftsprozesse als schlechte Praxis bezeichnen möchten, lassen Sie sie. Beachten Sie jedoch, dass dies eine rote Fahne in ihren Entwicklungspraktiken sein kann.

Eine typische Kennzeichnung von Dingen als schlechte Praxis erfolgt normalerweise in Organisationen mit Tonnen von inkompetenten Programmierern. Indem die Organisation bestimmte Dinge auflistet, versucht sie, den Schaden zu begrenzen, der intern durch ihre eigene Inkompetenz verursacht wird. Ich scheiße dich nicht.

Verallgemeinerungen sind die Mutter aller Fehler. Zu sagen, dass gespeicherte Prozesse (oder jede Art von Technologie) eine schlechte Praxis sind, ist eine Verallgemeinerung. Verallgemeinerungen sind Ausreden für Inkompetente. Ingenieure arbeiten nicht mit offensichtlichen Verallgemeinerungen. Sie analysieren von Fall zu Fall, analysieren Kompromisse und treffen technische Entscheidungen und Lösungen gemäß den vorliegenden Fakten, in deren Kontext sie ein Problem lösen sollen.

Gute Ingenieure bezeichnen Dinge nicht so verallgemeinernd als schlechte Praxis. Sie sehen sich das Problem an, wählen das geeignete Werkzeug aus und machen Kompromisse. Mit anderen Worten, sie machen Engineering.

Meine Meinung, wie man sie nicht benutzt

  • Setzen Sie komplexe Logik nicht über das Sammeln von Daten (und möglicherweise einige Transformationen) hinaus ein. Es ist in Ordnung, Datenmassagelogik in diese zu integrieren oder das Ergebnis mehrerer Abfragen mit diesen zu aggregieren. Aber das war es schon. Alles darüber hinaus würde sich als Geschäftslogik qualifizieren, die sich woanders befinden sollte.

  • Verwenden Sie sie nicht als einzigen Schutzmechanismus gegen SQL-Injection. Sie lassen sie dort, falls etwas Schlimmes für sie zutrifft , aber es sollte eine Menge defensiver Logik vor ihnen stehen - clientseitige Validierung / Bereinigung, serverseitige Validierung / Bereinigung, möglicherweise Umwandlung in Typen, die für Sie sinnvoll sind Domänenmodell und schließlich an parametrisierte Anweisungen übergeben werden (dies können parametrisierte SQL-Anweisungen oder parametrisierte gespeicherte Prozesse sein).

  • Machen Sie Datenbanken nicht zum einzigen Ort, an dem sich Ihre Geschäftsprozesse befinden. Ihre Geschäftsprozesse sollten genauso behandelt werden, wie Sie Ihren C # - oder Java-Quellcode behandeln. Das heißt, die Quellcodeverwaltung steuert die Textdefinition Ihrer Geschäftsprozesse. Die Leute schimpfen darüber, dass Geschäftsprozesse nicht von der Quelle kontrolliert werden können - Bullcrap, sie wissen einfach nicht, wovon zum Teufel sie reden.

Meine Meinung, wie / wo man sie benutzt

  • Ihre Anwendung erfordert Daten, die aus mehreren Abfragen oder Ansichten transponiert oder aggregiert werden müssen. Sie können das von der Anwendung in die Datenbank auslagern. Hier haben Sie eine Performance - Analyse zu tun , da a) Datenbank - Engines effizienter ist , dass App - Server in diese Dinge zu tun, aber b) App - Server sind (manchmal) leichter horizontal zu skalieren.

  • Feinkörnige Zugangskontrolle. Sie möchten nicht, dass ein Idiot kartesische Joins in Ihrer Datenbank ausführt, aber Sie können auch nicht einfach Leuten verbieten, beliebige SQL-Anweisungen einfach so auszuführen. Eine typische Lösung besteht darin, beliebige SQL-Anweisungen in Entwicklungs- und UAT-Umgebungen zuzulassen und sie in System- und Produktionsumgebungen zu verbieten. Jede Aussage, die es zu systest oder zur Produktion schaffen muss, geht in eine Speicherprozedur, die sowohl von Entwicklern als auch von dbas mit Code überprüft wird.

Jeder gültige Bedarf, eine SQL-Anweisung auszuführen, die sich nicht in einem Geschäftsprozess befindet, durchläuft einen anderen Benutzernamen / Konto und Verbindungspool (wobei die Verwendung stark überwacht wird und davon abgeraten wird.)

  • In Systemen wie Oracle können Sie auf LDAP zugreifen oder Symlinks zu externen Datenbanken erstellen (z. B. durch Aufrufen eines Geschäftsprozesses auf der Datenbank eines Geschäftspartners über VPN). Einfache Möglichkeit, Spaghetti-Code zu erstellen. Dies gilt jedoch für alle Programmierparadigmen und manchmal auch Sie haben spezielle Geschäfts- / Umgebungsanforderungen, für die dies die einzige Lösung ist. Mit Store Procs können Sie diese Unangenehmkeit an einem einzigen Ort in der Nähe der Daten zusammenfassen, ohne den App-Server durchsuchen zu müssen.

Ob Sie dies auf der Datenbank als Store Proc oder auf Ihrem App-Server ausführen, hängt von der Abwägungsanalyse ab, die Sie als Ingenieur durchführen müssen. Beide Optionen müssen analysiert und mit einer Art Analyse begründet werden. Auf die eine oder andere Weise die andere Alternative einfach als "schlechte Praxis" zu beschuldigen, das ist nur eine lahme Auseinandersetzung mit der Technik.

  • In Situationen, in denen Sie Ihren App-Server einfach nicht skalieren können (z. B. kein Budget für neue Hardware oder Cloud-Instanzen), aber über ausreichend Kapazität im Datenbank-Back-End verfügen (dies ist typischer, als viele zugeben möchten), zahlt es sich aus Geschäftslogik zu verschieben, um procs zu speichern. Nicht hübsch und kann zu anämischen Domainmodellen führen ... aber andererseits ... Kompromissanalyse, die Sache, an der die meisten Software-Hacks scheißen.

Ob dies nun zu einer dauerhaften Lösung wird oder nicht, das ist spezifisch für die in diesem bestimmten Moment beobachteten Einschränkungen.

Ich hoffe es hilft.


14
Das ist eine wirklich gute Antwort.
Yfeldblum

5
Gute Antwort, aber sollte das ironisch sein? "Verallgemeinerungen sind die Mutter aller Fehler."
Bedwyr

2
Ja und nein. Dieser Kommentar von mir war für diesen speziellen Satz gedacht, auf den sich das OP in seiner ursprünglichen Frage bezieht ( gespeicherte Prozeduren sind keine "Best Practice" .) Eine grobe Beschreibung von Speicherprozeduren als beste oder schlechte Praxis ist eine Verallgemeinerung. Das Ignorieren der Kontext , in dem sie gut oder schlecht kann (und wird oft führen) ups schrauben , wenn Architecting oder Entwicklung von Lösungen;)
luis.espinal

7
+1 für "Eine typische Kennzeichnung von Dingen als schlechte Praxis erfolgt normalerweise in Organisationen mit Tonnen von inkompetenten Programmierern." Ich war dort und habe das miterlebt, einschließlich der Aussage eines Entwicklermanagers, dass ich eine großartige Lösung für ein heikles Problem gefunden habe, aber wenn er es mir erlauben würde, es umzusetzen, würde es die Schleusen für das öffnen Muppets.
Julia Hayward

1
@ Shane Du hast recht. Ich glaube jedoch, dass diese Antwort die Tendenz einiger Gruppen von Ingenieuren zum Entschuldigen ihres Unwissens oder ihrer Analyse darstellt, indem sie auf die Karte der schlechten Praktiken zurückgreifen. Die Antwort könnte sich jedoch für die Unerfahreneren von uns verbessern.
Cesar Hernandez

56

Das Grundprinzip ist, dass die Verwendung einer gespeicherten Prozedur die Portabilität einschränkt und Sie an eine bestimmte Datenbank bindet. Hinzugefügte Wartungskosten werden ebenfalls als Grund angeführt. Ich wollte auch diesen Punkt kommentieren, den Sie gemacht haben:

(gespeicherte Prozeduren) schützen Sie vor SQL-Injection-Angriffen

Tatsächlich schützt Sie die parametrisierte Abfrage, die Sie bei der SQL-Abfrage mit einfachem Text problemlos ausführen können.


18
Und wenn Ihr gespeicherter Prozess eine beliebige Art von dynamischem SQL zusammen mit einem String-Parameter verwendet, sind Sie wieder da, wo Sie begonnen haben.
JeffO

4
Der Unterschied besteht darin, dass die Zugriffsberechtigung für gespeicherte Prozeduren pro Prozedur festgelegt werden kann. Bei parametrisierten SQL-Abfragen müssen Sie darauf vertrauen, dass die Programmierer dies nicht tun, + "blablabla"da Sie einfaches SQL zulassen müssen. Hier endet die Kontrolle.
Coder

19
Ich habe das Argument "Sie an einen bestimmten DB binden" nie verstanden. Wie oft nehmen Sie Ihr Programm und migrieren es in eine völlig andere Datenbank?
Mason Wheeler

11
@ MasonWheeler - +1 jedes Mal. In einem ausreichend großen Projekt wird Ihre App gegen die Schwächen eines bestimmten DB-Produkts geschrieben. Das Konvertieren in eine andere Datenbank wird zu einer wichtigen Aufgabe, egal was passiert, da die neue Datenbank andere Besonderheiten aufweist!
Michael Kohne

6
@HLGEM - aber in der COTS-Welt werden von Anfang an mehrere DBs ERWARTET (Sie wählen tatsächlich die kompatiblen DBs). Es ist nicht so, dass Sie portieren, es ist so, dass Sie verschiedene Backends unterstützen, was ein völlig anderes Biest ist als das Portieren.
Michael Kohne

46

Einige der Gründe, denen ich zustimme, dass gespeicherte Prozesse nicht die beste Vorgehensweise sind.

  • Geschäfts- und Anwendungslogik sollten sich im Code und nicht in der Datenbank befinden. Das Einfügen von Logik in die DB bringt Bedenken durcheinander.
  • Sie können gespeicherte Prozesse nicht so nahtlos testen wie Code in Ihren herkömmlichen Unit-Test-Projekten mit dem Rest der Anwendungslogik.
  • Ich finde gespeicherte Prozesse nicht förderlich, um die erste Programmierung zu testen, wenn ich Code schreibe.
  • Gespeicherte Prozesse sind nicht so einfach zu debuggen wie Anwendungscode, wenn Sie Ihr Programm in Ihrer IDE debuggen.
  • Versionskontrolle / Versionskontrolle von SP im Vergleich zu normalem Code

7
Sie können Test-First-Programmierung für gespeicherte Prozeduren genauso einfach durchführen.

5
Hmmm, na ja ... 1) Die Verwendung von gespeicherten DB-Prozeduren impliziert nicht unbedingt, dass Geschäftslogik in sie eingefügt wird. 2) gespeicherte procs sind einige der einfachsten Sachen, zum der Maßeinheit zu prüfen. 3) Geschäftsprozesse leiten nicht notwendigerweise Test-First-Praktiken ab, wahr, aber nicht alles, was berechenbar ist, kann Test-First'ed werden. 4) Das Debuggen sollte kein Problem sein, da Geschäftsprozesse nur leicht zu überprüfende SQL-Anweisungen und -Cursor enthalten sollten. Das Debuggen sollte auch stattfinden, indem zuerst die SQL-Anweisungen im Code getestet und debuggt werden und dann in die Geschäftsprozesse verschoben werden ... nur IMO übrigens.
Luis.espinal

6
Sie sind offensichtlich kein DB-Entwickler. Quellcodeverwaltung, IDEs - es ist verdammt einfach, einen SP zu debuggen, wenn Sie TOAD oder eine ähnliche IDE verwenden, genau wie bei der Versionierung.
gbjbaanb

6
2) beim Testen gespeicherter Prozesse. idk über andere Unit-Test-Frameworks, aber mindestens mit MS Test (VisualStudio.TestTools.UnitTesting), erfordert das Ausführen einer der Assert-Methoden für den gespeicherten Prozess mindestens eine Db-Verbindung, was ihn per Definition eher zu einem Integrationstest als zu einer Unit macht Prüfung. Ein gespeicherter Prozess kann auf globaler Datenbankebene auf den Status der Datenbank verweisen. Diese sind möglicherweise nicht fälschbar oder haben Schnittstellen.
T. Webster

3
+1 Darüber hinaus sind Sprachen für gespeicherte Prozeduren (pl / sql, t-sql, plpgsql usw.) sehr klobig und ausführlich. Es ist für mich viel einfacher, eine Skriptsprache zu verwenden, um eine Datenbankverbindung herzustellen und die Geschäftslogik außerhalb der Datenbank zu verarbeiten.

22

Gespeicherte Prozeduren ermöglichen die Wiederverwendung von Code und die Kapselung (zwei Säulen der Softwareentwicklung).

Ja, aber auf Kosten anderer agiler Designziele. Zum einen sind sie schwieriger zu warten. Wenn das Projekt, an dem ich arbeite, ein Indiz ist, werden Sie wahrscheinlich mehrere inkompatible SPs haben, die im Wesentlichen die gleiche Arbeit leisten, ohne dass dies von Vorteil ist.

schützen Sie vor SQL-Injection-Angriffen,

Nein tun sie nicht. Ich kann nicht einmal ahnen, woher diese Idee gekommen sein könnte, wie ich oft gehört habe, und sie ist einfach nicht wahr. Es kann bestimmte Arten von SQL-Injection-Angriffen abschwächen, aber wenn Sie nicht in erster Linie parametrisierte Abfragen verwenden, spielt das keine Rolle. Ich kann immer noch '; DROP TABLE Accounts; -

und helfen auch mit Geschwindigkeit (obwohl der DBA sagte, dass ab SQL Server 2008 sogar reguläre SQL-Abfragen kompiliert werden, wenn sie genügend oft ausgeführt werden).

Sie werden normalerweise auch kompiliert, wenn Sie vorbereitete, parametrisierte Anweisungen verwenden (zumindest mit mehreren der von mir verwendeten DBs). Zu dem Zeitpunkt, an dem Ihre Anwendung mit der Ausführung der Abfrage beginnt (oder insbesondere, wenn Sie dieselbe vorbereitete Abfrage mehrmals ausführen), ist jeder Leistungsvorteil, den Sie für Ihren SP halten, völlig hinfällig.

Der einzige Grund für die Verwendung einer gespeicherten Prozedur (IMHO) besteht darin, dass Sie eine komplexe, mehrstufige Abfrage erstellen müssen, die aus mehreren sortierten Quellen stammt. SPs sollten keine Entscheidungslogik auf niedriger Ebene enthalten, und sie sollten niemals einfach eine ansonsten einfache Abfrage kapseln. Es gibt keine Vorteile und nur viele Nachteile.

Hören Sie auf Ihren DBA. Er weiß, was los ist.


1
Red Gate hat ein SQL Source Control- Produkt für SQL Server, aber ich stimme zu, dass das Pushen von Logik in gespeicherte Prozesse eine hervorragende Möglichkeit ist, um sicherzustellen, dass Sie wichtige Logik nicht unter Versionskontrolle haben.
Carson63000

17
@greyfade - "Ich habe noch keine Quellcodeverwaltung für SPs" - machst du Witze? Ein Geschäftsprozess ist nur eine blutige Textdatei, die Sie in Ihre Datenbank-Engine hochladen (die ihn benötigt, kompiliert und zur Ausführung installiert.) An jedem Ort, an dem ich mit dem Speichern von Prozessen gearbeitet habe, speichern wir den Quellcode des Geschäftsprozesses. B. CVS, Clearcase oder das verwendete SCM. Die Behauptung, dass Geschäftsprozesse nicht über die Quellcodeverwaltung gesteuert werden können (weil sie sich in der Datenbank befinden), entspricht der Behauptung, dass mein Anwendungsquellcode (Java, C # oder was auch immer) nicht über die Quellcodeverwaltung gesteuert werden kann, da er in der Produktion kompiliert und bereitgestellt wird.
Luis.espinal

2
@ luis.espinal: Ich habe nicht gesagt, dass sie nicht in der Quellcodeverwaltung sein könnten . Ich sagte lediglich, dass ich kein Tool speziell für die Verwaltung des Verlaufs von SPs kenne, was impliziert, dass dieser Verlauf in der Datenbank verwaltet wird. Bitte schimpfen Sie nicht mit mir, nur weil Sie etwas falsch verstanden haben.
greyfade

1
Alle gespeicherten Procs unterliegen der Quellcodeverwaltung. Nur weil Sie in der Vergangenheit schlechte Paragraphen gesehen haben, bedeutet dies nicht, dass sie der Verwendung gespeicherter Procs inhärent sind.
HLGEM

1
@ luis.espinal Ist es typisch, dass die Quelle einer gespeicherten Prozedur später aus der Datenbank abgerufen werden kann? In diesem Fall können Sie nur ein Tool verwenden, das es regelmäßig herauszieht, und über andere Tools verfügen, mit denen Sie eine Installation von Grund auf neu erstellen können. Tun Sie dies gelegentlich, um sicherzustellen, dass es korrekt ist.

17

Dies war die offizielle Linie, als ich vor ein paar Jahren für einen der Big Five arbeitete. Das Grundprinzip war, dass SPs, da sie an bestimmte Implementierungen gebunden sind (PL / SQL vs. T / SQL vs. ...), die Auswahl an Technologien unnötig einschränken.

Nachdem ich die Migration eines großen Systems von T / SQL zu PL / SQL erlebt habe, kann ich das Argument verstehen. Ich denke, es ist ein bisschen wie ein Trottel - wie viele Orte bewegen sich wirklich aus einer Laune heraus von einer Datenbank in eine andere?


10
@ DaveE: Für eine Unternehmenslösung haben Sie wahrscheinlich Recht. Wenn Sie Softwarepakete erstellen, möchten Ihre größten potenziellen Kunden, dass diese auf Oracle ausgeführt werden, sobald Sie sie auf MSSQL ausliefern.
Eric J.

3
@Eric: zu wahr. Wo ich gerade bin, verwenden wir Tonnen von SPs und sagen den Leuten "Nein", wenn sie kein MSSQL wollen. Es ist schön, das zu können.
DaveE

3
@ DaveE: Wünscht das Verkaufsteam, Sie könnten "Ja" sagen?
Eric J.

2
Es geht nicht so sehr darum, ein System von einer Datenbank in eine andere zu verschieben, sondern darum, dass ein System in der Lage ist, jedes Datenbanksystem zu verwenden, über das der Kunde bereits verfügt. Große Datenbanken sind teuer.

@EricJ: Ja, aber sobald sie sehen, was die Kosten für ihre Provision bedeuten würden, verschwindet die Anfrage.
DaveE

17

Alle drei Unternehmen, für die ich arbeite, haben gespeicherte Prozeduren für ihre Anwendungslogik mit SQL Server verwendet. Ich habe die Dinge nicht wirklich anders gesehen. Aber für mich sind sie ein großes Durcheinander. In der Regel gibt es keine sehr guten Möglichkeiten zur Fehlerbehandlung oder Wiederverwendung von Code mit gespeicherten Prozeduren.

Angenommen, Sie haben eine gespeicherte Prozedur, die ein Dataset zurückgibt, das Sie verwenden möchten. Wie können Sie es in zukünftigen gespeicherten Prozeduren verwenden? Die Mechanismen auf SQL Server dafür sind nicht sehr gut. EXEC INTO ... funktioniert nur auf einer oder zwei Verschachtelungsebenen (ich vergesse jetzt). Oder Sie müssen eine Arbeitstabelle vordefinieren und sie verschlüsseln lassen. Oder Sie müssen eine temporäre Tabelle vorab erstellen und von der Prozedur füllen lassen. Aber was ist, wenn zwei Personen eine temporäre Tabelle in zwei verschiedenen Prozeduren, die sie nie zur gleichen Zeit verwenden wollten, als dasselbe bezeichnen? In jeder normalen Programmiersprache können Sie einfach ein Array von einer Funktion oder einem Punkt auf ein zwischen ihnen geteiltes Objekt / eine globale Struktur zurückgeben (außer in funktionalen Sprachen, in denen Sie die Datenstruktur zurückgeben würden, anstatt nur eine globale Struktur zu ändern ... )

Wie wäre es mit der Wiederverwendung von Code? Wenn Sie anfangen, allgemeine Ausdrücke in UDFs (oder noch schlimmer in Unterabfragen) einzufügen, verlangsamen Sie den Code. Sie können keine gespeicherte Prozedur aufrufen, um eine Berechnung für eine Spalte durchzuführen (es sei denn, Sie verwenden einen Cursor, übergeben die Spaltenwerte nacheinander und aktualisieren dann irgendwie Ihre Tabelle / Ihr Dataset). Um also die bestmögliche Leistung zu erzielen, müssen Sie allgemeine Ausdrücke ausschneiden / einfügen. Dies ist ein Alptraum für die Wartung. Mit einer Programmiersprache können Sie eine Funktion erstellen, mit der Sie das allgemeine SQL generieren und es dann beim Erstellen von überall aufrufen können die SQL-Zeichenfolge. Wenn Sie dann die Formel anpassen müssen, können Sie die Änderung an einer einzigen Stelle vornehmen ...

Wie wäre es mit Fehlerbehandlung? SQL Server hat viele Fehler, die die Ausführung der gespeicherten Prozedur sofort stoppen, und einige, die sogar eine Trennung erzwingen. Seit 2005 gibt es try / catch, aber es gibt immer noch eine Reihe von Fehlern, die nicht abgefangen werden können. Dasselbe passiert auch mit der Code-Vervielfältigung im Fehlerbehandlungscode, und Sie können Ausnahmen nicht so einfach weitergeben oder auf höhere Ebenen bringen wie die meisten Programmiersprachen.

Auch nur Geschwindigkeit. Viele Operationen an Datensätzen sind nicht SET-orientiert. Wenn Sie versuchen, zeilenorientierte Dinge zu tun, verwenden Sie entweder einen Cursor oder einen "Cursor" (wenn Entwickler häufig jede Zeile einzeln abfragen und den Inhalt wie einen Cursor in @ -Variablen speichern). ..Auch wenn dies oft langsamer ist als ein FORWARD_ONLY-Cursor). Mit SQL Server 2000 hatte ich etwas, das 1 Stunde lief, bevor ich es tötete. Ich habe diesen Code in Perl umgeschrieben und er war in 20 Minuten fertig. Wenn eine Skriptsprache, die 20- bis 80-mal langsamer als C ist, die Leistung von SQL beeinträchtigt, haben Sie definitiv keine Möglichkeit, zeilenorientierte Operationen in SQL zu schreiben.

Jetzt verfügt SQL Server über eine CLR-Integration, und viele dieser Probleme werden behoben, wenn Sie gespeicherte CLR-Prozeduren verwenden. Viele Datenbankadministratoren wissen jedoch aus Sicherheitsgründen nicht, wie sie .NET-Programme schreiben oder die CLR deaktivieren sollen, und bleiben bei Transact SQL .

Auch im Allgemeinen ist die Datenbank am schwierigsten zu skalieren. Wenn sich Ihre gesamte Geschäftslogik in der Datenbank befindet, treten Probleme auf, wenn die Datenbank zu langsam wird. Wenn Sie eine Business-Schicht haben, können Sie einfach mehr Caching und mehr Business-Server hinzufügen, um die Leistung zu steigern. Traditionell ist ein anderer Server zum Installieren von Windows / Linux und Ausführen von .NET / Java viel billiger als der Kauf eines anderen Datenbankservers und die Lizenzierung von mehr SQL Server. SQL Server bietet jetzt mehr Clusterunterstützung, ursprünglich gab es keine. Wenn Sie also viel Geld haben, können Sie Clustering hinzufügen oder sogar einen Protokollversand durchführen, um mehrere schreibgeschützte Kopien zu erstellen. Aber insgesamt wird dies viel mehr kosten als nur einen Schreibzugriff hinter den Cache oder so.

Schauen Sie sich auch die Transact-SQL-Funktionen an. String-Manipulation? Ich nehme jeden Tag an den Klassen Java String Class / Tokenizer / Scanner / Regex teil. Hash-Tabellen / Verknüpfte Listen / usw. Ich nehme die Java Collection-Frameworks usw. und das Gleiche für .NET. Sowohl C # als auch Java sind weitaus weiterentwickelte Sprachen als Transact SQL. .

Darüber hinaus sind gespeicherte Prozeduren effizienter, wenn Sie mit einem großen Dataset arbeiten und mehrere Abfragen / Kriterien anwenden, um es zu verkleinern, bevor Sie es an die Business-Schicht zurückgeben. Wenn Sie eine Menge großer Datenmengen an die Clientanwendung senden und die Daten auf dem Client auflösen müssen, ist dies weitaus ineffizienter als die gesamte Arbeit auf dem Server.

Auch gespeicherte Prozeduren sind gut für die Sicherheit. Sie können den gesamten Zugriff auf die zugrunde liegenden Tabellen unterbrechen und den Zugriff nur über die gespeicherten Prozeduren zulassen. Mit einigen modernen Techniken wie XML können Sie gespeicherte Prozeduren haben, die Stapelaktualisierungen durchführen. Alle Zugriffe werden dann über die gespeicherten Prozeduren gesteuert, so lange sie sicher / korrekt sind und die Daten eine höhere Integrität aufweisen können.

Das SQL-Injection-Argument trifft nicht mehr wirklich zu, da wir programmiersprachliche Abfragen parametrisiert haben. Auch wirklich noch vor parametrisierten Abfragen hat ein wenig Ersetzen ("'", "'") die meiste Zeit auch funktioniert (obwohl es immer noch Tricks gibt, um über das Ende des Strings hinauszugehen, um das zu bekommen, was Sie wollen).

Insgesamt denke ich, dass SQL und Transact SQL großartige Sprachen zum Abfragen / Aktualisieren von Daten sind. Aber für das Codieren jeder Art von Logik, das Manipulieren von Strings (oder das Manipulieren von Dateien ... Sie wären überrascht, was Sie mit xp_cmdshell machen können ...) bitte nein. Ich hoffe, einen zukünftigen Ort zu finden, der meistens keine gespeicherten Prozeduren verwendet. Aus Sicht der Code-Wartbarkeit sind sie ein Albtraum. Was passiert auch, wenn Sie die Plattform wechseln möchten (obwohl Sie wirklich für Oracle / DB2 / Sybase / SQL Server / usw. bezahlt haben), können Sie genauso gut alles aus ihnen herausholen, indem Sie jede proprietäre Erweiterung verwenden, die Ihnen hilft. ..).

Auch überraschend oft ist die Geschäftslogik nicht die gleiche. In der idealen Welt würden Sie die gesamte Logik in gespeicherte Prozeduren einfügen und diese zwischen Anwendungen teilen. Die Logik unterscheidet sich jedoch häufig je nach Anwendung, und Ihre gespeicherten Prozeduren werden zu übermäßig komplexen Monolithen, von denen die Menschen Angst haben, sie zu ändern, und deren Auswirkungen sie nicht verstehen. Während mit einer guten objektorientierten Sprache eine Datenzugriffsebene codiert werden kann, die über einige Standardschnittstellen / -hooks verfügt, die jede Anwendung an ihre eigenen Anforderungen anpassen kann.


6
Ich kann jedoch nicht anders, als Anlass zum Nachdenken in Bezug auf das gesamte Set-orientierte vs. prozedurale Thema zu geben. Ich habe Datenbankcursor gesehen, die in allen Arten von Fällen verwendet wurden, in denen dieser Ansatz nur verrückt war. Ich persönlich habe explizites Cursorbasiertes SQL (in diesem Fall Oracle PL / SQL) durch eine satzorientierte Abfrage ersetzt und festgestellt, dass die Ergebnisse nicht in 8 Minuten, sondern in weniger als einer Sekunde vorliegen. Ich brauchte 30 Minuten, um diesen 1000-Zeilen-Cursorcode zu zerlegen und zu "bekommen". Die resultierende SQL-Abfrage war kurz, elegant und einfach. Die Leistung ihrer Datenbankserver wird viel zu oft und viel zu schnell unterschätzt.
Craig

12

Wie versionieren Sie gespeicherte Prozeduren auf dem Server?

Wenn Sie gespeicherte Prozeduren aus der Versionskontrolle auf dem Server erneut bereitstellen, wird der gespeicherte Ausführungsplan ausgeblasen.

Gespeicherte Prozeduren sollten nicht direkt auf dem Server geändert werden können. Woher wissen Sie sonst, was gerade wirklich läuft? Ist dies nicht der Fall, benötigt das Bereitstellungstool Zugriff, um gespeicherte Prozeduren in die Datenbank schreiben zu können. Sie müssten bei jedem Build bereitgestellt werden (Ausführungsplan muss möglicherweise anders sein)

Während gespeicherte Prozeduren nicht portierbar sind, ist SQL im Allgemeinen auch nicht portierbar (jemals gesehene Oracle-Datumsverarbeitung - uggghhh).

Wenn Sie also Portabilität wünschen, erstellen Sie eine interne Datenzugriffs-API. Sie können dies wie Funktionsaufrufe aufrufen, und intern können Sie mit parametrisierten Abfragen beliebigen Jargon einbauen und es kann versionsgesteuert werden.


6
Wie versionieren Sie gespeicherte Prozeduren auf dem Server? - Sie kontrollieren den Quellcode des Store Proc. Wenn es Zeit für die Bereitstellung ist, greifen Sie auf die Geschäftsprozesse (ab einer bestimmten Baseline) zu und stellen Sie (oder Ihre DBA) für die Produktion bereit. Die erneute Bereitstellung (sei es beim Testen oder in der Produktion) führt zwar dazu, dass der gespeicherte Ausführungsplan nicht mehr angezeigt wird, dies geschieht jedoch unabhängig davon, ob Sie Ihre SPs über die Quellcodeverwaltung steuern oder nicht.
Luis.espinal

1
@BarryBrown Es funktioniert nicht, wenn Benutzer direkten Zugriff auf den Server haben und die gespeicherten Prozeduren ändern können. Ich müsste einen Prozess haben, der die SPs überwacht, oder vor jeder Verwendung eine Überprüfung durchführen ...
Christopher Mahan

2
Wenn Sie nur Leute haben, die Sprocs auf Servern ändern, ohne ihre Änderungen an der Quellcodeverwaltung vorzunehmen, haben Sie mit ziemlicher Sicherheit ein Prozessproblem , das sich auch auf Ihre unerlässliche Codeentwicklung auswirkt , selbst wenn Sie sich dessen nicht bewusst sind.
Craig

1
Eines der Dinge, die ich in der Vergangenheit getan habe, war, eine Entwicklungsinstanz des Datenbankservers auf den Workstations der einzelnen Entwickler zu platzieren. Wenn dies nicht möglich war, sollten zumindest "dev" - und "production" -Instanzen der Datenbanken vorhanden sein Alle DDL- und DML-Skripten sowie Beispieldaten und Ladeskripten wurden in einem eigenen Verzeichnis in der Quellstruktur gespeichert, und die Datenbank wurde routinemäßig mithilfe der MAKE-Datei aus diesen Skripten erstellt. Entwickler konnten mit nmake auch einzelne gespeicherte Prozesse erstellen. Wenn sie es nicht unter Quellcodeverwaltung stellten, würde es auf ihnen verschwinden, und sie wussten es.
Craig

1
... Ich wollte in meinem früheren Kommentar nicht abfällig klingen, mit dem Satz "..., auch wenn Sie sich nicht bewusst sind ...". Was ich damit sagen wollte war, dass, wenn so etwas mit gespeicherten Prozeduren passiert, es wahrscheinlich auch in anderen Teilen des Projekts passiert. Ich persönlich mag die integrierte Quellcodeverwaltung in IDEs nicht, zum Teil, weil ich der Meinung bin, dass die Leute faul sind, darüber nachzudenken, was es für das Team und das gesamte Projekt bedeutet , Änderungen vorzunehmen und diese Änderungen in die Quellcodeverwaltung zu übernehmen Repository. Diese Dinge sollten meiner Meinung nach nicht "automatisch" sein.
Craig

9

Dies steht im Widerspruch zu allem, was ich gelernt habe.

Möglicherweise müssen Sie mehr raus. [grinst] Im Ernst, gespeicherte Procs sind seit mindestens 10 Jahren rückläufig. Seitdem n-tier den Client-Server abgelöst hat. Der Rückgang wurde nur durch die Einführung von OO-Sprachen wie Java, C #, Python usw. beschleunigt.

Das heißt nicht, dass gespeicherte Procs noch keine Befürworter und Befürworter haben - aber dies ist eine langwierige Diskussion und Debatte. Es ist nicht neu und wird wahrscheinlich noch einige Zeit dauern. IMO, die Gegner der gespeicherten Procs gewinnen klar.

Gespeicherte Prozeduren ermöglichen die Wiederverwendung von Code und die Kapselung (zwei Säulen der Softwareentwicklung)

Sehr richtig. Dies gilt jedoch auch für eine anständig strukturierte OO-Ebene.

Sicherheit (Sie können Berechtigungen für einen einzelnen gespeicherten Prozess erteilen / entziehen)

Während Sie das tun können, tun es nur wenige aufgrund der schwerwiegenden Einschränkungen. Die Sicherheit auf DB-Ebene ist nicht granular genug, um kontextsensitive Entscheidungen zu treffen. Aufgrund des Leistungsaufwands und des Verwaltungsaufwands ist es ungewöhnlich, dass auch Verbindungen pro Benutzer bestehen. Daher benötigen Sie in Ihrem App-Code immer noch eine gewisse Berechtigungsstufe. Sie können rollenbasierte Anmeldungen verwenden, müssen diese jedoch für neue Rollen erstellen, die ausgeführte Rolle verwalten, die Verbindungen wechseln, um auf "Systemebene" wie bei der Protokollierung zu arbeiten usw. Und letztendlich, wenn Ihre App gehört - ebenso wie Ihre Verbindung zur DB.

Schützen Sie sich vor SQL-Injection-Angriffen

Nicht mehr als parametrisierte Abfragen. Welche Sie brauchen sowieso tun werden.

und helfen auch mit Geschwindigkeit (obwohl der DBA sagte, dass ab SQL Server 2008 sogar reguläre SQL-Abfragen kompiliert werden, wenn sie genügend oft ausgeführt werden).

Ich denke, das begann in MSSQL 7 oder 2000. Es gab eine Menge Debatten, Messungen und Fehlinformationen über gespeicherte Prozesse im Vergleich zur Inline-SQL-Leistung - ich fasse alles unter YAGNI zusammen. Und wenn Sie es brauchen, testen Sie.

Wir entwickeln eine komplexe App unter Verwendung der Agile-Softwareentwicklungsmethode. Kann sich jemand gute Gründe vorstellen, warum er gespeicherte Procs nicht verwenden möchte?

Ich kann mir nicht viele Gründe vorstellen, die Sie sich wünschen würden . Java / C # / jede dritte GL-Sprache ist in Bezug auf Kapselung, Wiederverwendung und Flexibilität usw. weitaus leistungsfähiger als T-SQL. Die meisten davon sind bei einem halbwegs anständigen ORM kostenlos.

Angesichts des Ratschlags, "nach Bedarf zu verteilen, aber nicht mehr" - denke ich, dass die Beweislast heutzutage bei SP-Befürwortern liegt. Ein häufiger Grund für das Speichern von Prozessen ist, dass T-SQL einfacher als OO ist und der Shop bessere T-SQL-Entwickler als OO hat. Oder dass der DBA auf der Datenbankebene stoppt und gespeicherte Prozesse die Schnittstelle zwischen dev und DBA sind. Oder Sie versenden ein halbkundenspezifisches Produkt und die gespeicherten Prozesse können vom Benutzer angepasst werden. In Abwesenheit solcher Überlegungen denke ich, dass der Standard für jedes Agile SW-Projekt heutzutage ORM sein wird.


1
Es gibt eine Menge Performance- Vorteile , wenn Sie keine riesigen Datenmengen aus der Datenbank übertragen müssen, um einfache Aufgaben zu erledigen. Bei Bedarf messen und optimieren.

Genau. Gespeicherte Prozeduren können wie ein Skalpell verwendet werden. Es ist eine absolute Garantie, dass die E / A im Datenbankserver mehr Bandbreite als die E / A zwischen dem Datenbankserver und Ihrer mittleren Ebene haben. Und Sie werden in Ihrem Middle Tier keinen schnelleren und effizienteren Daten-Join-Code schreiben als die Datenbank-Engine-Entwickler, die auf dem Datenbankserver geschrieben wurden. Wenn Sie 1.000.000 Datenzeilen auf Ihre mittlere Ebene übertragen, um einen Join durchzuführen, was ich sicherlich gesehen habe, sollten Sie nur ausgepeitscht werden ... Es ist wie bei den Leuten, die behaupten, Sie sollten "Ihren eigenen Rollback-Code schreiben". Wahnsinn.
Craig

1
Unterschätzen Sie Ihren Datenbankserver nicht. Erfahren Sie, wie Sie es richtig verwenden.
Craig

1
FWIW, Sie brauchen keinen gespeicherten Prozess, um einen Join auf der Datenbankseite durchzuführen. Und wenn Sie einen Cursor für die prozedurale Logik verwenden, haben Sie wahrscheinlich den Performance-Krieg bereits verloren. Das Aufgeben gespeicherter Prozeduren ist sicherlich nicht dasselbe wie das Aufgeben von SQL- oder Set-basierten Lösungen.
Mark Brackett

1
Ganz richtig, und ich habe eigentlich mehr für SQL gestritten als speziell für Sprocs. Aber wenn SQL in Ihren Imperativcode eingebettet ist, ist das auch nicht unbedingt der Schlüssel zum Glück, oder? Das führt oft zu der ganzen ORM-Debatte, die mich dann dazu führt, Performance-Vergleiche zwischen ORM-gesteuertem Datenbankzugriff und einfachem Erlernen des SQL-Gebrauchs anzustellen. Ich habe sowohl Systeme gesehen als auch von diesen gehört, bei denen Oracle-Berater empfohlen haben, den Datenbankserver so wenig wie möglich zu belasten, was zu schwerer (und extrem teurer!) Middleware mit einer unerträglichen Leistung führte.
Craig

4

In Anbetracht all dieser Fälle möchte ich noch einen hinzufügen. Die Wahl von SP kann auch von der Wahl der Leute abhängen.

Ich persönlich bin frustriert, wenn Leute sehr komplexe Logik in SP einbauen, und ich glaube, dass es sehr komplex ist, solche SP zu warten und zu debuggen. Sogar in vielen Fällen hat der Entwickler selbst Probleme, wenn das Debuggen im Code dahinter (sprich Sprachteil) viel einfacher ist als in SP.

SP sollte nur für einfache Operationen verwendet werden. Nun, das ist meine Wahl.


4

Ich möchte sowohl einige Pro- als auch Probleme mit gespeicherten Prozessen behandeln. Wir verwenden sie ausgiebig mit LedgerSMB , und unsere Regel lautet mit einigen sehr spezifischen Erweiterungen: "Wenn es sich um eine Abfrage handelt, machen Sie sie zu einem gespeicherten Prozess."

Unser Grund dafür war, die Wiederverwendung von Abfragen in verschiedenen Sprachen zu vereinfachen. Es gibt keinen besseren Weg, dies ehrlich zu tun.

Am Ende steht immer die Frage nach den Details. Gut eingesetzte gespeicherte Prozeduren erleichtern die Arbeit erheblich, und schlecht eingesetzte Prozeduren erschweren die Arbeit erheblich.

Also weiter zur Gegenseite.

  1. Wie traditionell verwendet, sind gespeicherte Prozeduren spröde. Alleine verwendet, schaffen sie die Möglichkeit, Ihrem Code an Stellen Fehler hinzuzufügen, von denen Sie nicht erwartet haben, dass sich die Aufrufsyntax geändert hat. Allein genommen ist dies ein kleines Problem. Es gibt viel zu viel Zusammenhalt zwischen den Schichten und dies verursacht Probleme.

  2. Ja, es ist möglich, eine Intra-Sproc-SQL-Injektion durchzuführen, wenn eine dynamische SQL durchgeführt wird. Es ist eine schlechte Sache, in diesem Bereich zu zuversichtlich zu sein, und daher muss man über umfangreiche Sicherheitserfahrung in diesem Bereich verfügen.

  3. Änderungen an den Schnittstellen sind mit gespeicherten Prozeduren aus dem obigen Grund Nr. 1 etwas problematisch, aber dies kann ein sehr großer Albtraum werden, wenn eine große Anzahl von Client-Apps beteiligt ist.

Die oben genannten sind ziemlich schwer zu leugnen. Sie passieren. Jeder, Pro-SP und Anti-SP, hat wahrscheinlich Horrorgeschichten über diese gehabt. Die Probleme sind nicht unlösbar, aber wenn Sie sie nicht beachten, können Sie sie nicht lösen (in LedgerSMB verwenden wir einen Service Locator, um SP-Aufrufe zur Laufzeit dynamisch zu erstellen und die oben genannten Probleme vollständig zu vermeiden. Während wir PostgreSQL sind nur könnte etwas ähnliches für andere db's gemacht werden).

Auf zum Positiven. Angenommen, Sie können die oben genannten Probleme lösen, erhalten Sie:

  1. Die Möglichkeit einer besseren Übersichtlichkeit bei Set-Vorgängen. Dies gilt insbesondere dann, wenn Ihre Anfrage sehr umfangreich oder sehr flexibel ist. Dies führt auch zu einer verbesserten Testbarkeit.

  2. Wenn ich bereits einen Service Locator in diesem Bereich habe, beschleunigen gespeicherte Prozeduren die Entwicklung, da sie den Anwendungsentwickler von Datenbankproblemen befreien und umgekehrt. Dies hat einige Schwierigkeiten, aber es ist nicht so schwer zu tun.

  3. Abfrage Wiederverwendung.

Oh und ein paar Dinge, die Sie in einem SP so gut wie nie tun sollten:

  1. Nicht-Transaktionslogik. Sie haben die E-Mail gesendet, dass die Bestellung versandt wurde, aber die Transaktion wurde zurückgesetzt. Oder Sie warten darauf, dass der E-Mail-Server online geschaltet wird. Oder Sie setzen Ihre Transaktion zurück, nur weil Sie die nicht erreichen können E-Mail-Server ....

  2. viele kleine Fragen, die locker aneinandergereiht und mit prozeduraler Logik übersät sind ...


Stimmen Sie voll und ganz zu, und halten Sie nicht-transaktionale Junk-Mails von gespeicherten Prozeduren fern. In diesem E-Mail-Beispiel sollte die E-Mail-Nachricht in eine Warteschlange gestellt und trotzdem asynchron bearbeitet werden. Sprechen Sie darüber, wie Sie sich auf einen massiven Leistungseinbruch und ein flippiges Verhalten unter Last einstellen und Ihre Datenbanktransaktionen von der Antwort Ihres Mailservers abhängig machen können? Huch!
Craig

3

Für wen arbeitest du?

Die Antwort kann davon abhängen, bei wem Sie angestellt sind, von welchem ​​Beratungsunternehmen oder von welchem ​​Unternehmen. Was für ein Unternehmen am besten ist, ist für ein Beratungsunternehmen oder einen anderen Softwareanbieter oft nicht am besten. zB Ein intelligentes Unternehmen möchte einen dauerhaften Vorteil gegenüber seinen Wettbewerbern haben. Im Gegensatz dazu möchte ein Softwareanbieter in der Lage sein, allen Unternehmen einer bestimmten Branche die gleiche Lösung zu den niedrigsten Kosten anzubieten. Wenn dies gelingt, entsteht für den Kunden kein Nettowettbewerbsvorteil.

In diesem speziellen Fall kommen und gehen Anwendungen, aber sehr oft lebt die Unternehmensdatenbank für immer weiter. Ein RDBMS verhindert in erster Linie, dass Junk-Daten in die Datenbank gelangen. Dies kann gespeicherte Prozeduren beinhalten. Wenn es sich bei der Logik um eine gute Logik handelt und es sehr unwahrscheinlich ist, dass sie sich von Jahr zu Jahr ändert, warum sollte sie dann nicht in der Datenbank vorhanden sein und intern konsistent bleiben, unabhängig davon, welche Anwendung für die Verwendung der Datenbank geschrieben wurde? Jahre später wird jemand eine Frage an die Datenbank haben, die beantwortet werden kann, wenn Junk daran gehindert wurde, in die Datenbank einzutreten.

Vielleicht hat das etwas damit zu tun, dass Ihr DBA für ein Beratungsunternehmen arbeitet. Je portabler sie ihren Code machen können, desto mehr können sie Code von Client zu Client wiederverwenden. Je mehr Logik sie in ihre App einbinden können, desto mehr ist das Unternehmen mit dem Anbieter verbunden. Wenn sie dabei ein großes Durcheinander hinterlassen, werden sie dafür bezahlt, es aufzuräumen, oder sehen das Durcheinander nie wieder. In jedem Fall ist es ein Gewinn für sie.

Bildbeschreibung hier eingeben

Für (viele) weitere Diskussionen auf beiden Seiten des Zauns lesen Sie die Diskussion zu Coding Horror . FWIW Ich lehne mich an die Seite der SP-Befürworter.


1
Diese Antwort konzentriert sich darauf, die Frage, ob gespeicherte Prozeduren verwendet werden sollen oder nicht, mit der Frage zu verknüpfen, für wen Sie arbeiten und welche Motivationen sie haben. Downvote. Die Antwort sollte sich stattdessen darauf konzentrieren, die Frage zu klären, ob gespeicherte Prozeduren mit den Vor- und Nachteilen gespeicherter Prozeduren verwendet werden sollen oder nicht. Wenn sich die Antwort auf die Idee konzentriert hätte, dass SPs keinen Müll in die Datenbank gelangen lassen, hätte ich nicht abgelehnt. Ich würde nicht zustimmen, im Interesse der Offenlegung, aber ich hätte nicht abgelehnt.
Yfeldblum

Außerdem haben Sie einen Artikel aus dem Jahr 2004 verlinkt. IMHO hat sich die Landschaft seitdem ziemlich verändert. OR / Ms sind viel alltäglicher geworden. Ruby / Rails ActiveRecord, MS kam mit Linq & EF, Django für Python, etc.
Brook

@Justice, er hat jedoch Recht, ob die Best Practice für gespeicherte Prozesse von der Person des Unternehmens abhängt und welche Rolle sie spielen. Mit gespeicherten Prozessen können Sie beispielsweise Berechtigungen für den Prozess selbst und nicht direkt für die Tabelle festlegen. Wenn Sie finanzielle Arbeit leisten und interne Kontrollen in Betracht ziehen müssen, sind diese die einzig praktikable Option, um Ihre Daten vor Benutzern zu schützen. Wenn Sie jedoch COTS-Produkte mit möglicherweise mehreren Backends erstellen, sind diese zu datenbankspezifisch. Wenn Sie ein Beratungsunternehmen sind, müssen Sie möglicherweise mehrere unterschiedliche Ansätze als am besten für die jeweiligen Umstände betrachten.
HLGEM

3
@HLGEM Ich habe keine Einwände gegen die Punkte, die Sie angesprochen haben . Ich wende mich jedoch gegen die These der Antwort, dass der DBA die Logik in die Anwendung einbauen könnte, weil er ein Berater ist und beabsichtigt, den Kunden zu verarschen. Es bindet die moralische Position einer Person an die Wahl, ob gespeicherte Prozeduren verwendet werden sollen. Meiner Meinung nach gibt es auf beiden Seiten technische Argumente , und die Argumente auf beiden Seiten unterscheiden sich von Anwendung zu Anwendung, Technologie zu Technologie, Unternehmen zu Unternehmen, Industrie zu Industrie. Und ich werde zuerst nach Verdiensten suchen, bevor ich das Motiv in Frage stelle.
Yfeldblum

Er sagte, er arbeite für eine Beratungsfirma. Eine bessere Kontrolle über den Code im Vergleich zu gespeicherten Prozeduren, die beim Kunden bereitgestellt werden, ist ein sehr legitimer Grund, weshalb dies möglicherweise die beste Vorgehensweise ist. Es könnte sein, dass es nicht darum geht, "den Kunden zu verarschen", sondern dass es sich um eine Frage größerer Kontrolle handelt.
Jesse

3

Es ist sehr schwierig, Datenbankmarken zu wechseln und dieselben gespeicherten Prozeduren zu verwenden.

Ihr Team hat entweder keinen DBA und niemand möchte etwas mit SQL zu tun haben.

Dies ist nichts weiter als ein Pisswettbewerb zwischen Programmierer und DBA.


2

IMO kommt darauf an. Gespeicherte Prozeduren haben ihren Platz, sind jedoch weder eine bewährte Methode noch sollten sie unbedingt vermieden werden. Ein intelligenter Entwickler weiß, wie eine bestimmte Situation richtig bewertet und festgestellt wird, ob eine gespeicherte Prozedur die Antwort ist. Persönlich bin ich ein Fan von ORMs (sogar von einfachen wie Linq to Sql) anstatt von gespeicherten Prozeduren, außer vielleicht für vordefinierte Berichte oder ähnliches, aber es ist wirklich von Fall zu Fall.


Downvoter kommentieren.
SandRock

2

Es ist immer wieder problematisch, die Geschäftslogik mit verschiedenen Programmiersprachen auf verschiedene Ebenen aufzuteilen. Das Aufspüren eines Fehlers oder das Implementieren einer Änderung ist viel schwieriger, wenn Sie zwischen den Welten wechseln müssen.

Das heißt, ich kenne Unternehmen, die ziemlich gut abschneiden, indem sie die gesamte Geschäftslogik in PL / SQL-Pakete in der Datenbank einfügen. Das sind keine sehr großen Anwendungen, aber auch nicht trivial. sagen wir 20K-100K LOC. (PL / SQL ist für diese Art von System besser geeignet als T-SQL. Wenn Sie also nur T-SQL kennen, schütteln Sie jetzt wahrscheinlich ungläubig den Kopf ...)


2

Dies ist ein weiterer Punkt, der noch nicht erwähnt wurde:

Tools zur Codegenerierung und zum Reverse Engineering können mit gespeicherten Prozeduren nicht wirklich gut umgehen. Das Tool kann im Allgemeinen nicht sagen, was der Proc tut. Gibt der Proc eine Ergebnismenge zurück? Mehrere Ergebnismengen? Ruft es seine Ergebnismengen aus mehreren Tabellen und temporären Tabellen ab? Ist der Proc nur eine gekapselte Update-Anweisung und gibt nichts zurück? Gibt es eine Ergebnismenge, einen Rückgabewert und eine "Konsolenausgabe" zurück?

Wenn Sie also ein Tool verwenden möchten, um einen DTO- und DAO-Layer für Datenübertragungsobjekte automatisch zu erstellen (wie es der "Service Builder" von Liferay tut), können Sie dies nicht einfach tun.

Darüber hinaus können ORMs wie Hibernate nicht richtig funktionieren, wenn die Datenquelle ein SP ist. Der Datenzugriff ist bestenfalls schreibgeschützt.


Es ist interessant, dass es Tools zur Codegenerierung anscheinend so schwer fällt, herauszufinden, ob eine gespeicherte Prozedur eine Ergebnismenge zurückgibt, wenn die gespeicherte Prozedur selbst keine Probleme damit hat.
Craig

2

Beim Solo-Programmieren kann ich nicht widerstehen , gespeicherte Prozeduren zu schreiben.

Ich benutze hauptsächlich MySQL. Ich habe zuvor keine objektorientierten Datenbanken wie PostGreSQL verwendet, aber was ich mit SPs in MySQL tun kann, ist, die Tabellenstruktur ein wenig zu abstrahieren. SP erlauben Sie mir diese primitive Aktionen zu entwerfen, deren Ein- und Ausgänge wird sich nicht ändern , auch wenn die Datenbank unter es nicht ändern.

Also habe ich eine Prozedur aufgerufen logIn. Wenn Sie sich einloggen, übergeben Sie immer nur usernameund password. Das zurückgegebene Ergebnis ist die ganze Zahl userId.

Wenn logInes sich um eine gespeicherte Prozedur handelt, kann ich jetzt beim Anmelden zusätzliche Arbeit hinzufügen, die gleichzeitig mit der ersten Anmeldung ausgeführt wird. Ich finde eine Reihe von SQL-Anweisungen mit eingebetteter Logik in einer gespeicherten Prozedur einfacher zu schreiben als die (aufrufende) Umgebungs-FETCH) -> (Ergebnis abrufen) -> (aufrufende Umgebungs-FETCH) -Reihe, die Sie ausführen müssen, wenn Sie Ihre Logikserverseite schreiben.


1

Ich möchte auch darauf hinweisen, dass gespeicherte Prozeduren CPU-Zeit auf dem Server verwenden. Nicht viel, aber einiges. Ein Teil der im Arbeitsablauf geleisteten Arbeit kann in der App geleistet werden. Es ist einfacher, die App-Ebene als die Datenebene zu skalieren.


3
Es ist schwer, eine Datenbank zu skalieren?
JeffO

1
Es ist zumindest deutlich teurer (es sei denn , Ihr auf MySQL) und in vielen Orten , die ich gearbeitet habe eine andere SQL Server Enterprise Edition - Lizenz bekommen ist wie Zähne ziehen
ben f.

Das Skalieren einer Datenbank ist nicht schwieriger als das Skalieren eines App-Layers. Ende der Geschichte
Brian Ogden,

1

Ich stimme Mark zu, dass sich die Community seit einiger Zeit wirklich von gespeicherten Prozeduren entfernt hat. Während viele der Punkte, die das Original-Poster angesprochen hat, warum wir SPs verwenden möchten, auf einmal gültig waren, ist es eine Weile her und, wie ein anderes Poster sagte, hat sich die Umgebung verändert. Ich erinnere mich zum Beispiel, dass ein Argument für die frühere Verwendung von SPs die Leistungssteigerung war, die erzielt wurde, weil ihre Ausführungspläne vorkompiliert wurden, während dynamisches SQL aus unserem Code bei jeder Ausführung neu kompiliert werden musste. Dies ist nicht mehr der Fall, da die wichtigsten Datenbanken geändert, verbessert, angepasst usw. wurden.

Das heißt, wir verwenden SPs für mein aktuelles Projekt. Der Grund liegt einfach darin, dass wir neue Anwendungen auf einer vorhandenen Datenbank aufbauen, die noch ältere Anwendungen unterstützt. Daher ist es sehr schwierig, Schemaänderungen vorzunehmen, bis wir die alten Apps deaktivieren. Wir haben uns bewusst dafür entschieden, unsere neuen Anwendungen auf der Grundlage des für die Anwendung erforderlichen Verhaltens und der Regeln zu entwerfen und die SPs zu verwenden, um vorübergehend eine Schnittstelle mit der Datenbank zu bilden, wie wir es uns wünschen, und den SPs die Anpassung an das vorhandene SQL zu ermöglichen . Dies geht auf einen früheren Posting-Punkt zurück, bei dem SPs das Vornehmen von Änderungen auf Datenbankebene erleichtern, ohne dass Änderungen am Anwendungscode erforderlich sind. Die Verwendung von SPs als Implementierung des Adaptermusters ist für mich sicherlich sinnvoll (insbesondere in Anbetracht meines aktuellen Projekts).

Fwiw, wir beabsichtigen, die SPs zu entfernen, wenn das Schema aktualisiert wird. Aber wie bei allem anderen in der Unternehmensentwicklung werden wir sehen, ob das jemals passiert! [Grinsen]


0

Ich wollte nur einen kurzen Überblick darüber geben, wie ich die Verwendung gespeicherter Prozeduren empfehlen würde. Ich denke nicht, dass sie überhaupt eine schlechte Praxis sind, und wie andere gesagt haben, sollten sie in den richtigen Situationen verwendet werden.

Ich kann Probleme feststellen, bei denen das Schreiben von Prozeduren für verschiedene Anwendungen in der Funktionalität verwirrend werden kann und die Geschäftslogik der Anwendung voneinander trennt und dazu führt, dass die Datenbank auch unorganisierter und restriktiver wird.

Daher würde ich eine gespeicherte Prozedur in relationalen datenorientierten datenbankspezifischen Aufgaben verwenden. Mit anderen Worten, wenn für Datenbankoperationen Logik verwendet wird, die mit den Daten für eine Anwendung konsistent ist, kann eine gespeicherte Prozedur verwendet werden, um die Daten konsistent zu speichern (sinnvoll). Ich denke, gute Beispiele dafür sind: konsistente Protokollierung, konsistente Wartung, Arbeiten mit vertraulichen Informationen usw.

Andere Aufgaben, bei denen die Daten so bearbeitet werden, dass sie den Anforderungen der Anwendung entsprechen und dem starken Datenmodell der Datenbank entsprechen, sollten dann in einer anderen Ebene gespeichert werden, die die Geschäftslogik enthält. Kurz gesagt, datenbankspezifische Datenmanipulationen zur Konsistenz können gespeicherte Prozeduren verwenden, bei denen die Konsistenz über das Datenbankintegritätsschemamodell hinausgeht.


-1

Gespeicherte Prozeduren "für mich" eignen sich für schreibgeschützte OLAP-Vorgänge, seltene Verwendung.

Für Geschäftsregeln, OLTP-Lese- / Schreibvorgänge bevorzuge ich Java-Anwendungsserver. Für eine einfache Codierung und eine weitestgehende Entlastung der CPU und des Speichers von den Master-DB-Servern. In diesem Setup ist der gesamte Code auf den Anwendungsservern nicht schwer zu überprüfen oder zu protokollieren und skalierbar.

Wichtig für mich ist, dass das Debuggen in der Business-Schicht einfacher ist als das Debuggen gespeicherter Prozeduren.


Sie haben einige Annahmen getroffen: dass das OP OLAP benötigt (in der Frage nicht angegeben); dass die verwendete Plattform Java-Anwendungsserver hat (unwahrscheinlich, da es sich bei dem Tag um SQL Server handelt). Ihre Antwort bringt auch nichts, was die anderen 22 Antworten noch nicht behandelt haben
Adam Zuckerman

Ich habe nur gesagt, wenn ich ein neues Projekt starte, wird die gespeicherte Prozedur selten für schreibgeschützte Operationen nur eine persönliche Wahl sein. Ich finde es bequemer, die meisten Codierungen auf der Geschäftslogikebene anstatt auf der Datenebene vorzunehmen.
Jaizon Lubaton

dies scheint nicht wesentliche etwas zu bieten über Punkte gemacht und erläutert vor 24 Antworten, kaum einen Inhalt lohnt sich ein 4-Jahre alte Frage Bumping
gnat

-2

Neben der unnötigen Weitergabe von Geschäftslogik und der Bindung an einen bestimmten Datenbankanbieter bin ich fest davon überzeugt, dass eine Technologie auch für die vorgesehenen Zwecke eingesetzt werden kann. Eine Datenbank ist genau das, ein relationaler Datenspeicher. Verwenden Sie es zum Speichern von Daten, sonst nichts.

Wählen Sie Ihre Werkzeuge mit Bedacht aus und Sie sparen sich auf lange Sicht eine Welt voller Verletzungen.


Wenn Sie abstimmen wollen, tun Sie dies, aber erklären Sie zumindest, warum.
Nico

wahrscheinlich weil du falsch liegst. Ein SP bedeutet nicht, dass Sie dort Code schreiben, sondern nur Ihre Datenzugriffsabfragen (in 99% der Fälle, denke ich). Außerdem zählt es als "Code", nur Trigger und Einschränkungen für das Datenmodell zu setzen - dh Betriebslogik, keine Daten. Darum meine ich, dass du falsch liegst.
gbjbaanb

Wo setzen Sie Transformationen für Ihre gespeicherten Daten außer in der Datenbank?
Chris Travers
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.