it-swarm-eu.dev

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

Ich arbeite an einem Projekt in einem der drei weltweit führenden IT-Beratungsunternehmen und wurde von einem DBA darüber informiert, dass die staatlich gespeicherten Prozeduren des Unternehmens keine "Best Practice" sind. Das ist so im Gegensatz zu allem, was ich gelernt habe.

Gespeicherte Prozeduren bieten Ihnen Code-Wiederverwendung und Kapselung (zwei Säulen der Softwareentwicklung), Sicherheit (Sie können Berechtigungen für einen einzelnen gespeicherten Prozess erteilen/widerrufen), schützen Sie vor SQL-Injection-Angriffen und helfen bei der Geschwindigkeit (obwohl dieser DBA dies sagte beginnend mit SQL Server 2008, dass sogar reguläre SQL-Abfragen kompiliert werden, wenn sie genügend oft ausgeführt werden).

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

152
user22453

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

Gespeicherte Prozeduren eignen sich hervorragend, 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 Benchmarking anzeigt, dass dies gerechtfertigt ist.

282
Eric J.

Einige Beobachtungen

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

Nur wenn Sie sie in dem Kontext richtig verwenden, in dem sie verwendet werden sollen. Die gleiche Behauptung kann über Funktionen (in der strukturierten Programmierung) oder Methoden (in der objektorientierten Programmierung) aufgestellt werden, und dennoch sehen wir 1K-Funktionen und Mega-Ass-Objekte.

Artefakte bieten Ihnen diese Vorteile nicht. Die richtige Verwendung dieser Artefakte bietet diese Vorteile.

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

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

schützen Sie vor SQL-Injection-Angriffen,

Dies ist nicht spezifisch für SPs, da Sie mit parametrisierten SQL-Anweisungen und Eingabebereinigung dieselbe Schutzstufe erreichen können. Ich würde jedoch zusätzlich zu diesen SPs verwenden, um "Sicherheit in der Tiefe" zu gewährleisten.

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

Dies ist sehr datenbankspezifisch, aber im Allgemeinen ist Ihr DBA richtig. SQL-Anweisungen (entweder statisch oder parametrisiert) werden kompiliert. SPs helfen, wenn Sie Daten aggregieren und berechnen möchten, die Sie mit einfachen SQL-Anweisungen nicht ausführen können, die jedoch eng in SQL integriert sind und die den Roundtrip zum App-Server nicht rechtfertigen.

Ein gutes Beispiel ist das Abfragen von Daten in einen temporären Cursor (oder Cursor), von dem aus ein anderes SQL selbst ausgeführt werden kann. Sie können dies programmgesteuert auf dem App-Server tun oder die mehreren 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 ein schlechtes Datenbankdesign (oder Sie ziehen Daten aus nicht so kompatiblen Datenbankschemata abteilungsübergreifend ab.)

Wir entwickeln eine komplexe App mit 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 Prozesse nicht verwenden möchte?

Falsche Frage

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

Ein Werkzeug ist gut, wenn es für den beabsichtigten Zweck gut verwendet wird und wenn es das beste Werkzeug für die jeweilige Aufgabe ist. Eine andere Verwendung ist kein Hinweis darauf, dass das Werkzeug falsch ist, sondern dass der Träger nicht weiß, was er/sie tut.

Die richtige Frage lautet "Welche Art von Verwendungsmustern für gespeicherte Prozeduren sollte vermieden werden." Oder "unter welchen Bedingungen sollte ich gespeicherte Prozeduren verwenden (oder nicht) ". Nach Gründen suchen nicht eine Technologie zu verwenden, bedeutet einfach, dem Werkzeug die Schuld zu geben, 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 vermutete, dass die Datenbankadministratoren diese gespeicherten Prozesse nicht beibehalten wollten, aber es scheint viel zu viele Negative zu geben, um eine solche Entwurfsentscheidung zu rechtfertigen.

Was sie dann tun, ist, die Ergebnisse ihrer schlechten technischen Entscheidungen auf die Werkzeuge zu projizieren, die sie schlecht verwendet haben.

Was tun in Ihrem Fall?

Meine Erfahrung ist, in Rom zu tun, wie es die Römer tun .

Kämpfe nicht dagegen an. Wenn die Mitarbeiter Ihres Unternehmens Store Procs als schlechte Praxis kennzeichnen möchten, lassen Sie sie. Beachten Sie jedoch, dass dies eine rote Fahne in ihren Konstruktionspraktiken sein kann.

Die typische Kennzeichnung von Dingen als schlechte Praxis erfolgt normalerweise in Organisationen mit Tonnen inkompetenter Programmierer. Durch die schwarze Liste bestimmter Dinge versucht die Organisation, den intern durch ihre eigene Inkompetenz verursachten Schaden zu begrenzen. Ich scheiße dich nicht.

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

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

Meine Meinung dazu, wie man sie nicht benutzt

  • Fügen Sie keine komplexe Logik über die Datenerfassung (und möglicherweise einige Transformationen) hinaus in sie ein. Es ist in Ordnung, eine Datenmassagelogik in sie zu setzen oder zu aggregieren Sie das Ergebnis mehrerer Abfragen mit ihnen. Aber das war es schon. Alles darüber hinaus würde als Geschäftslogik gelten, die sich woanders befinden sollte.

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

  • Machen Sie Datenbanken nicht zum einzigen Ort, an dem sich Ihre Geschäftsvorgänge befinden. Ihre Geschäftsvorgänge sollten genauso behandelt werden, wie Sie Ihr C # oder Java Quellcode. Das heißt, Quellcodeverwaltung der Textdefinition Ihrer Store-Prozesse. Die Leute schimpfen, dass Store-Prozesse nicht quellengesteuert werden können - Bullcrap, sie wissen einfach nicht, wovon zum Teufel sie reden.

Meine Meinung dazu, wie/wo man sie benutzt

  • Ihre Anwendung benötigt Daten, die aus mehreren Abfragen oder Ansichten transponiert oder aggregiert werden müssen. Sie können diese Daten aus der Anwendung in die Datenbank auslagern. Hier müssen Sie eine Leistungsanalyse durchführen, da a) Datenbank-Engines effizienter sind als App-Server, aber b) App-Server (manchmal) einfacher horizontal zu skalieren sind.

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

Jede gültige Notwendigkeit, eine SQL-Anweisung nicht in einem Store-Prozess auszuführen, durchläuft einen anderen Benutzernamen/Konto und Verbindungspool (wobei die Verwendung stark überwacht und nicht empfohlen wird).

  • In Systemen wie Oracle können Sie Zugriff auf LDAP erhalten oder Symlinks zu externen Datenbanken erstellen (z. B. Aufrufen eines Store Proc auf der Datenbank eines Geschäftspartners über VPN). Einfacher Weg, um Spaghetti-Code zu erstellen, aber das gilt für alle Programmierparadigmen, und manchmal haben Sie spezifische Geschäfts-/Umgebungsanforderungen, für die dies die einzige Lösung ist. Store Procs helfen dabei, diese Unangenehmkeit an einem Ort allein, in der Nähe der Daten und ohne den App-Server zu durchlaufen, zusammenzufassen.

Ob Sie dies auf der Datenbank als Store-Prozess oder auf Ihrem App-Server ausführen, hängt von der Kompromissanalyse ab, die Sie als Ingenieur durchführen müssen. Beide Optionen müssen analysiert und mit einer Art von Analyse begründet werden. Auf die eine oder andere Weise zu gehen, indem man einfach die andere Alternative als "schlechte Praxis" beschuldigt, ist nur eine lahme technische Ausrede.

  • In Situationen, in denen Sie Ihren App-Server einfach nicht skalieren können (dh kein Budget für neue Hardware- oder Cloud-Instanzen), aber mit viel Kapazität auf der Datenbank Back-End (dies ist typischer, als viele Menschen zugeben möchten), es lohnt sich, die Geschäftslogik in das Speichern von Prozessen zu verschieben. Nicht schön und kann zu anämischen Domain-Modellen führen ... aber andererseits ... Kompromissanalyse, die Sache, an der die meisten Software-Hacks scheißen.

Unabhängig davon, ob dies zu einer dauerhaften Lösung wird oder nicht, ist dies spezifisch für die in diesem bestimmten Moment beobachteten Einschränkungen.

Ich hoffe es hilft.

172
luis.espinal

Das Grundprinzip ist, dass das Verlassen auf eine gespeicherte Prozedurschicht die Portabilität einschränkt und Sie an eine bestimmte Datenbank bindet. Als Grund werden auch zusätzliche Wartungskosten angeführt. Ich wollte auch diesen Punkt kommentieren, den Sie gemacht haben:

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

Es ist eigentlich die parametrisierte Abfrage, die Sie schützt, was Sie bei der SQL-Abfrage im Klartext problemlos tun können.

56
System Down

Einige der Gründe, denen ich zustimme, dass gespeicherte Prozesse keine bewährte Methode sind.

  • Geschäfts- und Anwendungslogik sollte sich im Code befinden, nicht in der Datenbank. Das Einfügen von Logik in die DB bringt Bedenken durcheinander.
  • Sie können gespeicherte Prozesse nicht so nahtlos wie Code in Ihren herkömmlichen Unit-Test-Projekten mit dem Rest der Anwendungslogik testen.
  • 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/Quellcodeverwaltung von SP vs. normaler Code
48
Gilles

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

Ja, aber auf Kosten der Erreichung anderer agiler Designziele. Zum einen sind sie schwieriger zu warten. Wenn das Projekt, an dem ich arbeite, ein Hinweis ist, werden Sie wahrscheinlich mehrere inkompatible SPs haben, die im Wesentlichen dieselbe Arbeit ohne Nutzen erledigen.

schützen Sie vor SQL-Injection-Angriffen,

Nein tun sie nicht. Ich kann nicht einmal erraten, woher diese Idee gekommen sein könnte, wie ich oft höre, und es ist einfach nicht wahr. Es kann bestimmte Arten von SQL-Injection-Angriffen abschwächen. Wenn Sie jedoch überhaupt keine parametrisierten Abfragen verwenden, spielt dies keine Rolle. Ich kann immer noch '; DROP TABLE Accounts; - -

und auch bei der Geschwindigkeit helfen (obwohl dieser 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 bei 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 Ihr SP] halten, vollständig umstritten.

Der nur Grund für die Verwendung einer gespeicherten Prozedur, IMHO, ist, wenn Sie eine komplexe, mehrstufige Abfrage erstellen müssen, die aus mehreren sortierten Quellen abgerufen wird. SPs sollten keine Entscheidungslogik auf niedriger Ebene enthalten, und sie sollten nie 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.

23
greyfade

Alle drei Unternehmen, für die ich arbeite, verwenden gespeicherte Prozeduren für ihre Anwendungslogik mit SQL Server. 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 Funktionen zur Fehlerbehandlung oder zur Wiederverwendung von Code mit gespeicherten Prozeduren.

Angenommen, Sie haben eine gespeicherte Prozedur, die einen Datensatz zurückgibt, den Sie verwenden möchten. Wie können Sie ihn 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 Ebenen der Verschachtelung (ich vergesse jetzt). Oder Sie müssen eine Arbeitstabelle vordefinieren und den Prozess 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 Verfahren, die sie nie gleichzeitig verwenden wollten, als dasselbe bezeichnen? In jeder normalen Programmiersprache können Sie einfach ein Array von einer Funktion zurückgeben oder auf ein Objekt/eine globale Struktur verweisen, die von ihnen gemeinsam genutzt werden (mit Ausnahme von Funktionssprachen, in denen Sie die Datenstruktur zurückgeben würden, anstatt nur eine globale Struktur zu ändern ... )

Wie wäre es mit einer Wiederverwendung von Code? Wenn Sie anfangen, allgemeine Ausdrücke in UDFs (oder noch schlimmer in Unterabfragen) einzufügen, werden Sie den Code zum Stillstand bringen. 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 Ihre Tabelle/Ihren Datensatz irgendwie). Um die bestmögliche Leistung zu erzielen, müssen Sie allgemeine Ausdrücke überall ausschneiden/einfügen, was ein Alptraum für die Wartung ist. Mit einer Programmiersprache können Sie eine Funktion erstellen, um das allgemeine SQL zu generieren und es dann beim Erstellen von überall aufzurufen die SQL-Zeichenfolge. Wenn Sie dann die Formel anpassen müssen, können Sie die Änderung an einem einzigen Ort vornehmen ...

Wie wäre es mit Fehlerbehandlung? SQL Server weist viele Fehler auf, die die Ausführung der gespeicherten Prozedur sofort verhindern, 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 Codeduplizierung des Fehlerbehandlungscodes, und Sie können Ausnahmen wirklich nicht so einfach weitergeben oder sie so einfach 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 lang 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-80x langsamer als C ist, SQL in der Leistung raucht, haben Sie definitiv kein Geschäft damit, zeilenorientierte Operationen in SQL zu schreiben.

Jetzt verfügt SQL Server über eine CLR-Integration, und viele dieser Probleme verschwinden, wenn Sie gespeicherte CLR-Prozeduren verwenden. Viele Datenbankadministratoren wissen jedoch aus Sicherheitsgründen nicht, wie sie .NET-Programme schreiben oder die CLR deaktivieren und sich an Transact SQL halten sollen. Auch bei den CLRs gibt es immer noch Probleme, Daten auf effiziente Weise zwischen mehreren Prozeduren auszutauschen .

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 zum Ausführen von .NET/Java viel billiger als der Kauf eines anderen Datenbankservers und die Lizenzierung von mehr SQL Server. SQL Server bietet jetzt jedoch mehr Clustering-Unterstützung, ursprünglich hatte 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 kostet dies viel mehr als nur ein Schreiben hinter dem Cache oder so.

Schauen Sie sich auch die Transact-SQL-Funktionen an. String-Manipulation? Ich nehme jeden Tag die Klassen Java String Class/Tokenizer/Scanner/Regex. Hash-Tabellen/verknüpfte Listen/usw.). Ich nehme die Java Sammlungsframeworks usw. Und das Gleiche gilt für .NET ... Sowohl C # als auch Java sind weitaus weiterentwickelte Sprachen als Transact SQL ... Heck-Codierung mit Transact-SQL macht mich neidisch C ...

Darüber hinaus sind gespeicherte Prozeduren effizienter, wenn Sie mit einem großen Datensatz arbeiten und mehrere Abfragen/Kriterien anwenden, um ihn zu verkleinern, bevor Sie ihn an die Geschäftsschicht zurückgeben. Wenn Sie eine Menge großer Datenmengen an die Clientanwendung senden und die Daten auf dem Client aufschlüsseln müssen, ist dies viel ineffizienter als nur 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 kürzen und den Zugriff nur über die gespeicherten Prozeduren zulassen. Mit einigen modernen Techniken wie XML können Sie Prozeduren speichern, die Stapelaktualisierungen durchführen. Dann wird jeder Zugriff über die gespeicherten Prozeduren gesteuert, solange die Daten sicher/korrekt sind und mehr Integrität aufweisen können.

Das SQL-Injection-Argument trifft nicht mehr so ​​sehr zu, da wir Abfragen auf der Seite der Programmiersprache parametrisiert haben. Auch wirklich, noch bevor parametrisierte Abfragen durchgeführt wurden, funktionierte ein wenig Ersetzen ("'", "' '") die meiste Zeit (obwohl es immer noch Tricks gibt, um über das Ende der Zeichenfolge 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 Durchführen von String-Manipulationen (oder zum Teufel mit Dateimanipulationen ... Sie wären überrascht, was Sie mit xp_cmdshell machen können ...), bitte nein. Ich hoffe, einen zukünftigen Ort zu finden, an dem meistens keine gespeicherten Prozeduren verwendet werden. Unter dem Gesichtspunkt 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/etc. 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 dieselbe. In der idealen Welt würden Sie die gesamte Logik in gespeicherte Prozeduren einfügen und diese zwischen Anwendungen teilen. Aber oft unterscheidet sich die Logik je nach Anwendung und Ihre gespeicherten Prozeduren werden zu übermäßig komplexen Monolithen, deren Änderung die Menschen fürchten und die nicht alle Auswirkungen verstehen. Während Sie mit einer guten objektorientierten Sprache eine Datenzugriffsschicht codieren können, die einige Standardschnittstellen/Hooks enthält, die jede Anwendung für ihre eigenen Anforderungen überschreiben kann.

18
Cervo

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 durchlebt habe, kann ich das Argument verstehen. Ich denke, es ist ein bisschen wie ein Canard - wie viele Orte wirklich aus einer Laune heraus von einer Datenbank in eine andere wechseln?

17
DaveE

Wie versionieren Sie gespeicherte Prozeduren auf dem Server?

Wenn Sie gespeicherte Prozeduren aus der Versionskontrolle erneut auf dem Server 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 zu schreiben. Sie müssten bei jedem Build bereitstellen (der Ausführungsplan muss möglicherweise anders sein).

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

Wenn Sie also Portabilität wünschen, erstellen Sie eine interne Datenzugriffs-API. Sie können dies wie Funktionsaufrufe aufrufen und intern mit parametrisierten Abfragen die gewünschte Umgangssprache einbauen und die Version steuern.

12

Das ist so im Gegensatz zu allem, was ich gelernt habe.

Möglicherweise müssen Sie mehr raus. [grinst] Im Ernst, gespeicherte Prozesse sind seit mindestens 10 Jahren rückläufig. So ziemlich seit n-tier den Client-Server ersetzt 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 Prozesse noch keine Befürworter und Befürworter haben - aber dies ist eine langjährige Diskussion und Debatte. Es ist nicht neu und wird wahrscheinlich noch einige Zeit andauern. IMO, die Gegner gespeicherter Prozesse gewinnen eindeutig.

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

Sehr richtig. Aber auch eine anständig strukturierte OO -Ebene).

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

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

schützen Sie sich vor SQL-Injection-Angriffen

Nicht mehr als parametrisierte Abfragen. Was du brauchst, um es trotzdem zu tun.

und auch bei der Geschwindigkeit helfen (obwohl dieser 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 viele 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 mit der Agile-Softwareentwicklungsmethode. Kann sich jemand gute Gründe vorstellen, warum er gespeicherte Prozesse nicht verwenden möchte?

Ich kann mir nicht viele Gründe vorstellen, warum Sie wollen zu. Java/C #/any 3rd GL Sprache ist in Bezug auf Kapselung, Wiederverwendung und Flexibilität usw. viel leistungsfähiger als T-SQL usw. Die meisten davon sind bei einem halbwegs anständigen ORM kostenlos.

Angesichts des Ratschlags, "nach Bedarf zu verteilen, aber nicht mehr" - ich denke, die Beweislast liegt heutzutage bei SP Befürworter. Ein häufiger Grund für die Speicherung von Proc Heavy ist, dass T- SQL ist einfacher als OO, und der Shop verfügt über bessere T-SQL-Entwickler als OO. Oder dass der DBA auf der Datenbankebene stoppt und gespeicherte Prozesse die Schnittstelle zwischen dev und DBA darstellen. Oder Sie liefern einen Semi-Custom Das Produkt und die gespeicherten Prozesse können vom Benutzer angepasst werden. Ohne solche Überlegungen denke ich, dass der Standard für jedes Agile SW-Projekt heutzutage ORM sein wird.

9
Mark Brackett

In Anbetracht aller oben genannten 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 und ich glaube, dass solche SP ist sehr komplex zu warten und zu debuggen. Selbst in vielen Fällen ist der Entwickler selbst konfrontiert) Problem beim Debuggen in Code dahinter (sagen wir Sprachteil) ist viel einfacher als in SP.

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

4
Rimbik

Ich möchte sowohl einige Vor- 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 Erleichterung der sprachübergreifenden Wiederverwendung von Abfragen. Es gibt keinen besseren Weg, dies ehrlich zu tun.

Am Ende geht es immer um Details. Gut verwendete, gespeicherte Prozeduren machen die Dinge viel einfacher und schlecht verwendete machen sie viel schwieriger.

Also weiter auf die Gegenseite.

  1. Wie traditionell verwendet, sind gespeicherte Prozeduren spröde. Alleine verwendet sie die Möglichkeit, Ihrem Code Fehler an Stellen hinzuzufügen, die Sie aus keinem anderen Grund erwartet haben, als dass sich die Aufrufsyntax geändert hat. Allein verwendet 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 dynamisches SQL ausgeführt wird. Es ist eine schlechte Sache, in diesem Bereich zu zuversichtlich zu sein, und folglich muss man über beträchtliche Erfahrung in der Sicherheit in diesem Bereich verfügen.

  3. Änderungen an Schnittstellen sind bei gespeicherten Prozeduren aus dem oben genannten Grund Nr. 1 etwas problematisch. Dies kann jedoch zu einem sehr großen 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 darüber. 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, um dies zu vermeiden) die oben genannten Probleme vollständig. Während wir nur PostgreSQL sind, könnte etwas Ähnliches für andere DBs getan werden).

Auf zu den positiven. Angenommen, Sie können die oben genannten Probleme lösen, erhalten Sie:

  1. Die Möglichkeit einer verbesserten Klarheit bei festgelegten Operationen. Dies gilt insbesondere dann, wenn Ihre Abfrage sehr umfangreich oder sehr flexibel ist. Dies führt auch zu einer verbesserten Testbarkeit.

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

  3. Wiederverwendung von Abfragen.

Oh und ein paar Dinge, die Sie in einem SP fast nie tun sollten:

  1. nicht-Transaktionslogik. Sie haben die E-Mail gesendet, dass die Bestellung versendet wurde, aber die Transaktion zurückgesetzt wurde ... oder jetzt warten Sie darauf, dass der E-Mail-Server online geschaltet wird ... oder schlimmer noch, Sie rollen Ihre Transaktion zurück, nur weil Sie die nicht erreichen können E-Mail-Server ....

  2. viele kleine Fragen, die lose aneinandergereiht und mit prozeduraler Logik bestreut sind ...

4
Chris Travers

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

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

Dies ist nichts weiter als ein Programmierer gegen DBA Pissing Contest.

3
JeffO

Für wen arbeiten Sie?

Die Antwort kann davon abhängen, bei wem Sie beschäftigt sind, bei der Beratungsfirma oder bei der Firma selbst. Was für ein Unternehmen am besten ist, ist für ein Beratungsunternehmen oder einen anderen Softwareanbieter oft nicht das Beste. z.B. Ein intelligentes Unternehmen möchte einen dauerhaften Vorteil gegenüber seinen Mitbewerbern haben. Im Gegensatz dazu möchte ein Softwareanbieter in der Lage sein, allen Unternehmen in einer bestimmten Branche die gleiche Lösung zu den niedrigsten Kosten anzubieten. Wenn dies gelingt, ergibt sich für den Kunden kein Wettbewerbsvorteil.

In diesem speziellen Fall kommen und gehen Anwendungen, aber sehr oft lebt die Unternehmensdatenbank für immer weiter. Eines der wichtigsten Dinge, die ein RDBMS tut, ist zu verhindern, dass Junk-Daten in die Datenbank gelangen. Dies kann gespeicherte Prozeduren beinhalten. Wenn die Logik eine gute Logik ist und sich höchstwahrscheinlich nicht von Jahr zu Jahr ändert, warum sollte sie nicht in der Datenbank enthalten sein und sie intern konsistent halten, 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 soll, und die beantwortet werden kann, wenn verhindert wurde, dass Junk in die Datenbank gelangt.

Vielleicht hat dies etwas damit zu tun, dass Ihr DBA für ein Beratungsunternehmen arbeitet. Je portabler sie ihren Code erstellen 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 sie werden das Durcheinander nie wieder sehen. In jedem Fall ist es ein Gewinn für sie.

enter image description here

Für (viele) weitere Diskussionen auf beiden Seiten des Zauns lesen Sie die Diskussion unter Coding Horror . FWIW Ich lehne mich an die Seite derer, die sich für SPs einsetzen.

3
user21007

Solo programmieren, ich kann nicht widerstehen gespeicherte Prozeduren schreiben.

Ich benutze hauptsächlich MySQL. Ich habe bisher noch keine objektorientierten Datenbanken wie PostGreSQL verwendet, aber was ich mit SPs in MySQL tun kann, ist, die Tabellenstruktur ein wenig zu abstrahieren. Mit SPs kann ich diese primitiven Aktionen entwerfen, deren Ein- und Ausgänge werden sich nicht ändern, auch wenn sich die darunter liegende Datenbank tut ändert.

Ich habe also eine Prozedur namens logIn. Wenn Sie sich anmelden, übergeben Sie immer nur username und password. Das zurückgegebene Ergebnis ist die Ganzzahl userId.

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

2
bobobobo

Es ist immer eine Quelle von Problemen, wenn die Geschäftslogik unter Verwendung verschiedener Programmiersprachen auf verschiedene Ebenen aufgeteilt wird. Das Aufspüren eines Fehlers oder das Implementieren einer Änderung ist viel schwieriger, wenn Sie zwischen Welten wechseln müssen.

Trotzdem kenne ich Unternehmen, die ziemlich gut abschneiden, indem sie all Geschäftslogik in PL/SQL-Pakete einfügen, die in der Datenbank leben. 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 wahrscheinlich ungläubig den Kopf ...)

2
user281377

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 Prozess tut. Gibt der Proc eine Ergebnismenge zurück? Mehrere Ergebnismengen? Ruft es seine Ergebnismengen aus mehreren Tabellen und temporären Tabellen ab? Ist der Prozess 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 eine DTO- und DAO-Ebene für Datenübertragungsobjekte automatisch zu erstellen (wie dies 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.

2
knb

IMO kommt es darauf an. Gespeicherte Prozeduren haben ihren Platz, sind jedoch weder eine bewährte Methode noch sollten sie um jeden Preis vermieden werden. Ein intelligenter Entwickler weiß, wie er eine bestimmte Situation richtig bewertet und feststellt, ob eine gespeicherte Prozedur die Antwort ist. Persönlich bin ich ein Fan davon, ein ORM zu verwenden (sogar ein grundlegendes wie rohes Linq zu SQL), anstatt gespeicherte Prozeduren, außer vielleicht für vordefinierte Berichte oder ähnliches, aber es ist wirklich eine Einzelfallbasis.

2
Wayne Molina

Ich stimme Mark zu, dass sich die Community seit einiger Zeit wirklich von gespeicherten Prozeduren entfernt. Während viele der Punkte, die das ursprüngliche Poster angesprochen hat, warum wir SPs verwenden möchten, zu einem bestimmten Zeitpunkt gültig waren, ist es eine ganze Weile her, und wie ein anderes Poster sagte, hat sich die Umgebung geändert. Ich erinnere mich zum Beispiel, dass ein Argument für die Verwendung von SPs "früher" die erzielten Leistungssteigerungen waren, 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 sich die wichtigsten Datenbanken geändert, verbessert, angepasst usw. haben.

Trotzdem verwenden wir SPs für mein aktuelles Projekt. Der Grund liegt einfach darin, dass wir neue Anwendungen auf einer vorhandenen Datenbank erstellen, die noch ältere Anwendungen unterstützt. Daher ist es sehr schwierig, Schemaänderungen vorzunehmen, bis wir die älteren Apps deaktivieren. Wir haben uns bewusst dafür entschieden, unsere neuen Anwendungen basierend auf dem für die Anwendung erforderlichen Verhalten und den für die Anwendung erforderlichen Regeln zu entwerfen und die SPs zu verwenden, um vorübergehend so mit der Datenbank zu kommunizieren, wie wir es möchten, und den SPs die Anpassung an das vorhandene SQL zu ermöglichen . Dies geht auf den Punkt eines früheren Posters zurück, dass SPs es einfacher machen, Änderungen auf Datenbankebene vorzunehmen, ohne dass Änderungen am Anwendungscode erforderlich sind. Die Verwendung von SPs als Implementierung des Adaptermusters ist für mich sicherlich sinnvoll (insbesondere angesichts meines aktuellen Projekts) und möglicherweise das einzige Argument, das ich für ihre heutige Verwendung wirklich sehen kann.

Fwiw, es ist unsere Absicht, 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]

1
SonOfPirate

Ich möchte auch darauf hinweisen, dass gespeicherte Prozeduren die CPU-Zeit auf dem Server verwenden. Nicht viel, aber einige. Einige der im Arbeitsablauf geleisteten Arbeiten können in der App ausgeführt werden. Es ist einfacher, die App-Ebene als die Datenebene zu skalieren.

1

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 Schreibvorgänge für verschiedene Anwendungen in der Funktionalität verwirrend werden und die Geschäftslogik der Anwendung trennen und dazu führen können, dass die Datenbank unorganisierter und restriktiver wird.

Daher würde ich eine gespeicherte Prozedur in relationalen datenorientierten Aufgaben verwenden, die für die Datenbank spezifisch sind. Mit anderen Worten, wenn für Datenbankoperationen eine 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 hierfü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, die dem starken Datenmodell der Datenbank folgen, sollten dann in einer anderen Ebene gespeichert werden, die die Geschäftslogik enthält. Kurz gesagt, datenbankspezifische Datenmanipulation für Konsistenz könnte gespeicherte Prozeduren verwenden, wobei die Konsistenz über das Modell des Datenbankintegritätsschemas hinausgeht.

0
Mark