MySQL gespeicherte Prozeduren oder PHP-Code?

7

Eine allgemeine Frage, ohne einen konkreten Fall - ist es normalerweise vorzuziehen, gespeicherte MySQL-Prozeduren zu verwenden, anstatt ein PHP-Skript zu schreiben, das die gleichen Berechnungen und Abfragen durchführt?

Was sind die Vorteile der einzelnen Methoden?

    
Omri 05.08.2010, 22:09
quelle

11 Antworten

10

Point / Counter Point mit Jeff Atwoods "Wer Stored Procedures benötigt, Sowieso?" ab 2004 :

  

1) Gespeicherte Prozeduren werden in großen ironischen Datenbanksprachen wie PL / SQL (Oracle) oder T-SQL (Microsoft) geschrieben. Diese sogenannten Sprachen sind archaisch und voller verrückter, inkohärenter Designentscheidungen, die immer aus der quälenden Entwicklung von zehn Jahren Rückwärtskompatibilität resultieren. Du willst wirklich nicht viel Code in diesem Zeug schreiben. Für den Kontext ist JavaScript eine gewaltige Verbesserung von PL / SQL oder T-SQL.

Antwort : Das "S" in "SQL" bedeutet "Strukturiert", nicht "Standardisiert" - PLSQL und TSQL sind beide benutzerdefinierte Erweiterungen SQL, die auch ANSI SQL ins Spiel bringen, weil es sehr wenig SQL gibt, das datenbankunabhängig ist. Im Allgemeinen sollten Sie nicht ANSI SQL verwenden können, wenn Sie eine gut funktionierende Abfrage wünschen.

ORM ist kein Wundermittel - wegen der Datenbankabstraktion unterstützen die meisten native gespeicherte Prozeduren / Funktionen, um eine gut funktionierende Abfrage zu erhalten. Was schön ist, aber den Zweck von ORM völlig zunichte macht ...

Ich werde nie verstehen, warum Web-Entwicklung, eine Verschachtelung unzähliger Technologien (HTML, Javascript / AJAX, Flash ...) immer SQL als das schwarze Schaf der Familie trennt. Wie alle anderen musst du lernen, etwas daraus zu machen. Muss die sofortige Befriedigung sein, die Sie bekommen, wenn Sie die anderen Technologien verwenden ...

  

2) Gespeicherte Prozeduren können normalerweise nicht in derselben IDE debuggt werden, in der Sie Ihre Benutzeroberfläche schreiben. Jedes Mal, wenn ich eine Ausnahme in den Procs isoliere, muss ich aufhören, was ich gerade mache, meine Kopie von Toad ausstechen und die Datenbankpakete laden, um zu sehen, was schief läuft. Der Übergang zwischen zwei völlig verschiedenen IDEs mit völlig verschiedenen Schnittstellen und Sprachen ist nicht gerade produktiv.

Antwort : War ursprünglich ein Javascript-Debugger in Eclipse oder Visual Studio? Nein, sie erlauben Plugins, um das Produkt aus der Tür zu bekommen. beleben einen bisher nicht existierenden Markt. Die meisten haben kein Problem mit Firebug außerhalb von Visual Studio / Eclipse, warum sollte SQL-Debugging anders sein?

  

3) Gespeicherte Prozeduren liefern nicht viel Rückmeldung, wenn etwas schief läuft. Wenn der Proc nicht mit einer seltsamen T-SQL- oder PL / SQL-Ausnahmebehandlung interagiert wird, erhalten wir kryptische "Fehler", die auf der bestimmten Zeile innerhalb des Proc, die fehlgeschlagen ist, basieren, wie beispielsweise Tabelle keine Zeilen enthält. Äh, ok?

Antwort : Ihr Mangel an Vertrautheit macht keine schlechte Sprache. Wie Sie noch nie für einen seltsamen Fehler in Ihrer Sprache der Wahl googlen mussten ... Wenigstens Oracle & amp; MySQL gibt Ihnen Fehlerreferenznummern.

  

4) Gespeicherte Prozeduren können keine Objekte übergeben. Also, wenn Sie nicht vorsichtig sind, können Sie mit einer Zillion Parameter enden. Wenn Sie eine Tabellenzeile mit 20+ Feldern mit einem Proc füllen müssen, sagen Sie Hallo zu 20+ Parametern. Am schlimmsten ist, wenn ich einen schlechten Parameter übergebe - entweder zu viele, nicht genug oder schlechte Datentypen - erhalte ich einen generischen "Bad Call" -Fehler. Oracle kann mir nicht sagen, welche Parameter fehlerhaft sind! Also muss ich über 20 Parameter von Hand poren, um herauszufinden, welcher der Täter ist.

Antwort : SQL basiert auf SET, ganz im Gegensatz zur prozeduralen / OO-Programmierung. Typen sind nah an Objekten, aber irgendwann muss eine Zuordnung zwischen prozeduralen / OO-Objekten und Datenbank-Entities erfolgen.

  

5) Gespeicherte Prozeduren verbergen Geschäftslogik. Ich habe keine Ahnung, was ein Proc tut, oder welche Art von Cursor (DataSet) oder Werte es mir zurückgibt. Ich kann den Quellcode des Procs nicht anzeigen (zumindest, ohne auf Nummer 2 zurückzugreifen, wenn ich entsprechenden Zugriff habe), um zu verifizieren, dass er tatsächlich tut, was ich denke, oder was der Entwickler beabsichtigt hat. Inline-SQL ist zwar nicht hübsch, aber zumindest kann ich es neben der anderen Geschäftslogik im Kontext sehen.

Antwort : Dies ist eine gute Sache (tm) - so erhalten Sie den Model-View-Controller (MVC), so dass Sie in jedem ein Frontend haben können Vielzahl von Sprachen, ohne die Logik jedes Mal duplizieren zu müssen, während sie sich mit den Eigenarten jeder Sprache befassen, um diese Logik zu replizieren. Oder ist es gut, dass die Datenbank ermöglicht, dass fehlerhafte Daten hinzugefügt werden, wenn sich jemand direkt mit der Datenbank verbindet? Ausflüge zurück & amp; zwischen der Anwendung und der Datenbank Verschwendung Zeit & amp; Ressourcen, die Ihre Anwendung niemals wiedererlangen wird.

    
OMG Ponies 10.08.2010 18:12
quelle
4

Ich denke, Jeff Atwood traf 2004 den Nagel auf den Kopf bezüglich gespeicherter Procs:

Wer braucht schon gespeicherte Prozeduren?

Nachdem ich sowohl Stored Procedures als auch dynamisches SQL ausgiebig verwendet habe, bevorzuge ich letzteres: leichter zu verwalten, bessere Kapselung, keine BL in der Datenzugriffsschicht, größere Flexibilität und vieles mehr. Praktisch jedes größere Open-Source-PHP-Projekt verwendet dynamisches SQL über gespeicherte Procs (siehe: Drupal, Wordpress, Magento und viele mehr).

Diese Konversation scheint fast archaisch zu sein: Besorg dir ein gutes ORM , hör auf, dir über deinen Datenzugriff Sorgen zu machen und fange an, großartige Anwendungen zu erstellen.

    
leepowers 05.08.2010 23:13
quelle
3

Für uns ist die Verwendung von gespeicherten Prozeduren absolut entscheidend. Wir haben eine ziemlich große .net App. Die erneute Bereitstellung der gesamten App kann unsere Benutzer für einen kurzen Zeitraum offline schalten, was einfach nicht erlaubt ist.

Während die Anwendung läuft, müssen wir jedoch manchmal kleinere Korrekturen an unseren Abfragen vornehmen. Einfache Dinge wie das Hinzufügen oder Entfernen eines NOLOCK oder vielleicht sogar das Ändern der Joins. Es ist fast immer aus Leistungsgründen. Gerade heute hatten wir einen Fehler, der durch einen fremden NOLOCK verursacht wurde. 2 Minuten, um das Problem zu lokalisieren, Lösung zu bestimmen und neue proc: Null Ausfallzeit zu implementieren. Dies mit Anfragen im Code zu tun, hätte zumindest einen kleinen Ausfall verursacht, der möglicherweise viele Leute verärgert.

Ein weiterer Grund ist die Sicherheit. Mit proc's übergeben wir die Benutzerkennung (nicht sequentiell, nicht erratbar) in jeden proc-Aufruf. Wir validieren, dass der Benutzer Zugriff hat, um diese Funktion in der Web-App und wieder in der Datenbank selbst auszuführen. Dies stellt die Barriere für Hacker radikal in Frage, wenn unsere Web-App kompromittiert wurde. Nicht nur konnten sie keine SQL laufen, die sie wollen, sondern sogar um einen Proc auszuführen, müssten sie einen bestimmten Autorisierungsschlüssel haben. Was schwer zu erwerben wäre. (Und nein, das ist nicht unsere einzige Verteidigung)

Wir haben unsere Procs unter Kontrolle, das ist also kein Problem. Außerdem muss ich mir keine Gedanken darüber machen, wie ich Dinge benenne (bestimmte ORM-Schemas hassen bestimmte Benennungsschemata) und ich muss mir keine Sorgen über die Flugleistung machen. Sie müssen mehr als nur SQL wissen, um ein ORM richtig zu tunen. Sie müssen die besonderen Verhaltensweisen des ORM kennen.

    
NotMe 10.08.2010 17:44
quelle
2

Gespeicherte Prozedur 99 mal von 100. Wenn ich topick 1 Grund wäre, dann wäre es, dass, wenn Ihre php Web App alle Datenbankzugriffe über gespeicherte Prozeduren hat und Ihr Datenbankbenutzer nur Permision hat, die gespeicherten Prozeduren auszuführen, dann sind Sie 100 % gegen SQL-Injection-Angriffe geschützt.

    
Ben Robinson 05.08.2010 22:13
quelle
2

Für mich ist der Vorteil, alles mit der Datenbank in der Datenbank zu tun, das Debugging. Wenn Sie Ihre Berechnungen (mindestens die meisten) innerhalb der gespeicherten Prozedur durchgeführt haben und eine Änderung vornehmen müssen, ändern Sie sie einfach, testen Sie sie und speichern Sie sie. Es würde keine Änderungen an Ihrem PHP-Code geben.

Wenn Sie wichtige Berechnungen in Ihrem PHP-Code speichern, müssen Sie die SQL-Anweisungen aus dem Code übernehmen, sie bereinigen, dann modifizieren, testen und dann wieder hineinkopieren und erneut testen.

>

Es fällt einem eine leichte Wartung ein, die Dinge getrennt zu halten. Der Code sieht sauberer aus und ist einfacher zu lesen, wenn Sie gespeicherte Prozeduren verwenden, weil wir alle wissen, dass SQL-Skripts nur lächerlich groß werden. Behalte die gesamte Datenbanklogik in der Datenbank.

Wenn die Datenbank richtig eingestellt ist, haben Sie wahrscheinlich etwas schnellere Zeiten für die Ausführung der Abfrage, denn anstatt PHP die Zeichenfolge analysieren zu lassen, senden Sie sie an die Datenbank, dann führt die Datenbank sie aus und sendet sie zurück, Sie können einfach Parameter in die Datenbank mit der gespeicherten Prozedur einfügen, es wird einen zwischengespeicherten Ausführungsplan für die gespeicherte Prozedur haben, und die Dinge werden etwas schneller sein. Ein paar sorgfältig platzierte Indizes können dazu beitragen, den Datenabruf zu beschleunigen, denn der Webserver ist nur ein Conduit und PHP-Skripte laden ihn nicht so sehr auf.

    
user174624 05.08.2010 22:43
quelle
1

Ich würde sagen: "Mach nicht zu viel Magie mit der Datenbank". Der schlimmste Fall wäre für einen neuen Entwickler des Projekts, der bemerkt, dass ** eine Operation ** durchgeführt wird, aber er kann nicht sehen, wo im Code es ist. Also sucht er weiter danach. Aber es ist in der Datenbank gemacht.

Wenn Sie also "unsichtbare" Datenbankoperationen durchführen (ich denke über Trigger nach), schreiben Sie sie einfach in eine Codedokumentation.

%Vor%

Auf der anderen Seite ist das Schreiben von Funktionen für die DB eine gute Idee und würde dem Entwickler eine gute Abstraktionsschicht bieten.

%Vor%

Natürlich ist das alles Pseudo-Code, aber ich hoffe, Sie verstehen meine obskure Idee.

    
Aif 05.08.2010 23:01
quelle
1

Nun, es gibt eine Seite dieses Arguments, die ich sehr selten höre, also werde ich es hier schreiben ...

Code ist versionsgesteuert. Datenbanken sind nicht. Wenn Sie also mehr als eine Instanz Ihres Codes haben, benötigen Sie eine Möglichkeit, Migrationen automatisch durchzuführen, wenn Sie das Update durchführen, oder Sie riskieren, Dinge zu brechen. Und selbst damit sind Sie immer noch mit den Problemen konfrontiert, dass Sie vergessen haben, dem Migrationsskript einen aktualisierten SP hinzuzufügen und dann einen Build zu brechen (möglicherweise ohne es zu merken, wenn Sie nicht wirklich IDEHT testen).

Aus Debugging und Wartung finde ich SPs 100x so schwer zu zerlegen wie rohe SQL. Der Grund ist, dass es mindestens drei Schritte erfordert. Schauen Sie zuerst in PHP-Code, um zu sehen, welcher Code aufgerufen wird. Dann gehen Sie in die Datenbank und finden Sie diese Prozedur. Dann schau dir endlich den Code der Prozedur an.

Ein weiteres Argument (im Sinne der Versionskontrolle), gibt es keinen svn st -Befehl für die SPs. Wenn Sie also einen Entwickler erhalten, der einen SP manuell ändert, werden Sie eine Menge Zeit damit verbringen, dies herauszufinden (vorausgesetzt, sie werden nicht alle von einem einzigen DBA verwaltet).

Wo SP wirklich ist, wenn mehrere Anwendungen mit demselben Datenbankschema kommunizieren. Dann haben Sie nur eine Stelle, an der DDL und DML gespeichert sind, und beide Anwendungen können sie gemeinsam nutzen, ohne dass eine Kreuzabhängigkeit in einer oder mehreren Bibliotheken hinzugefügt werden muss.

Kurz gesagt, meine Ansicht ist wie folgt:

Gespeicherte Prozeduren verwenden:

  1. Wenn mehrere Anwendungen mit demselben Datensatz arbeiten
  2. Wenn Sie Abfragen durchlaufen und andere Abfragen ausführen müssen (das Vermeiden von TCP-Schichtverlusten kann die Effizienz erheblich verbessern)
  3. Wenn Sie einen wirklich guten DBA haben, da er die gesamte SQL-Verarbeitung durch ihn erzwingt.

Benutze rohen SQL / ORM / Generated SQL so ziemlich in jedem anderen Fall (Ungefähr, da es Grenzfälle sind, über die ich nicht nachdenke) ...

Noch einmal, das sind nur meine $ 0,02 ...

    
ircmaxell 05.08.2010 23:33
quelle
1

Ich verwende gespeicherte Prozeduren so oft wie möglich aus verschiedenen Gründen.

Reduzieren Sie die Anzahl der Round-Trips zur Datenbank

Wenn Sie mehrere verknüpfte Tabellen gleichzeitig ändern müssen, können Sie eine einzige gespeicherte Prozedur verwenden, sodass nur ein Aufruf an die Datenbank erfolgt.

Geschäftslogik klar definieren

Wenn bestimmte Dinge über eine Abfrage wahr sein müssen, dann sorgt eine Speicherprozedur dafür, dass jemand, der SQL (eine ziemlich einfache Sprache) kennt, sicherstellt, dass alles richtig gemacht wird.

Erstellen Sie einfache Schnittstellen für andere Programmierer

Ihre nicht-kompetenten Teamkameraden können viel einfachere Schnittstellen zur Datenbank verwenden und Sie können sicher sein, dass sie Beziehungen nicht versehentlich in einen schlechten Zustand versetzen können.

Überlegen Sie:

%Vor%

Im Vergleich zu:

%Vor%

Schreiben Sie ihnen einen netten kleinen Wrapper, der sich um die Behandlung von Stored Procedure-Aufrufen kümmert und sie im Geschäft sind.

Aktualisiert alle Verwendungen in einem System auf einmal

Wenn alle Benutzer gespeicherte Prozeduren verwenden, um die Datenbank abzufragen, und Sie müssen ändern, wie etwas funktioniert, können Sie die gespeicherte Prozedur aktualisieren und sie wird überall aktualisiert, solange Sie die Schnittstelle nicht ändern.

Erzwungene Sicherheit

Wenn Sie nur gespeicherte Prozeduren verwenden können, um alles innerhalb Ihres Systems zu erledigen, können Sie dem Benutzerkonto, das auf die Daten zugreift, streng eingeschränkte Berechtigungen erteilen. Keine Notwendigkeit, ihnen UPDATE, DELETE oder sogar SELECT-Berechtigungen zu geben.

Einfache Fehlerbehandlung

Viele Leute wissen es nicht, aber Sie können Ihre gespeicherten Prozeduren so erstellen, dass das Aufspüren der meisten Probleme sehr einfach wird.

Sie können sogar Ihre Codebasis integrieren, um die zurückgegebenen Fehler ordnungsgemäß zu behandeln, wenn Sie eine gute Struktur verwenden.

Hier ist ein Beispiel, das Folgendes macht:

  • Verwendet einen Exit-Handler für schwerwiegende Probleme
  • Verwendet einen Continue-Handler für weniger schwerwiegende Probleme
  • Prüft die Validierung von Nicht-Tabellen-Scans von vornherein
  • Wenn die Validierung nicht fehlgeschlagen ist, wird die Überprüfung der Tabellenüberprüfung durchgeführt.
  • Führt die Verarbeitung in einer Transaktion durch, wenn die Dinge validiert werden
  • Rollt alles zurück, wenn es ein Problem gibt
  • Gibt alle gefundenen Probleme an
  • Vermeidet unnötige Updates

Hier sind die Interna einer erfundenen gespeicherten Prozedur, die eine Konto-ID, die schließende Konto-ID und eine IP-Adresse akzeptiert und sie dann verwendet, um sie entsprechend zu aktualisieren. Das Trennzeichen wurde bereits auf $$ gesetzt:

%Vor%

Bedeutung des Statuscodes:

  • 0: sollte nie passieren - schlechtes Ergebnis
  • 1: Erfolg - Der Account wurde entweder bereits geschlossen oder ordnungsgemäß geschlossen
  • 2XXXX - Probleme mit Logik oder Syntax
  • 3XXXX - Probleme mit unerwarteten Datenwerten im System
  • 4XXXX - fehlende Pflichtfelder

Statt Programmierern zu vertrauen, die mit Datenbanken nicht vertraut sind (oder einfach nicht mit dem Schema vertraut sind), ist es viel einfacher, ihnen Schnittstellen zur Verfügung zu stellen.

Anstatt alle oben genannten Prüfungen durchzuführen, können sie einfach Folgendes verwenden:

%Vor%

Und dann überprüfen Sie den Ergebniscode und ergreifen Sie die entsprechenden Maßnahmen.

Persönlich glaube ich, dass wenn Sie Zugriff auf gespeicherte Prozeduren haben und Sie sie nicht verwenden, sollten Sie wirklich darauf achten, sie zu verwenden.

    
Privateer 09.12.2015 01:52
quelle
0

Wo immer möglich, wird der Endbenutzer von der Abstraktion der Daten von der Benutzeroberfläche profitieren. Daher sollten Sie versuchen, gespeicherte Prozeduren so gut wie möglich zu nutzen.

    
websch01ar 05.08.2010 22:12
quelle
0

Sie benötigen die zugrunde liegenden Werte nicht unbedingt, wenn die Berechnungen in der Datenbank ausgeführt werden, und lassen Sie sie dann von der Datenbank ausführen. Dadurch wird das Datenvolumen zwischen der Datenbank und einem PHP-Skript auf ein Minimum reduziert. Im Allgemeinen werden Berechnungen mit Datenbankdaten jedoch am besten von der Datenbank selbst durchgeführt.

    
Mark Baker 05.08.2010 22:14
quelle
0

Ich habe Leute sagen hören "lass die Datenbank so viel wie es geht" und andere riefen wie "wtf, was machst du mit meiner Datenbankleistung".

Also denke ich, dass es meistens eine Entscheidung über die Nutzungsrate sein sollte (gespeicherte Prozeduren werden den MySQL-Prozess belasten und PHP-Code wird den Webserver-Prozess belasten).

    
Andreas Linden 05.08.2010 22:20
quelle