Ist das Speichern von SQL-Anweisungen in einer Tabelle zur späteren Ausführung eine schlechte Idee?


21

Ist das Speichern von SQL-Anweisungen in einer MySQL-Tabelle zur späteren Ausführung eine schlechte Idee? Die SQL-Anweisungen sind zur Ausführung bereit, dh es müssen keine Parameter ausgetauscht werden DELETE FROM users WHERE id=1.

Ich denke, ich bin faul, aber ich habe an diese Idee gedacht, weil ich an einem Projekt arbeite, für das einige Cron-Jobs erforderlich sind, die regelmäßig SQL-Anweisungen ausführen.


Sie sollten klären, ob Sie diese SQL-Anweisungen einmal ausführen möchten oder ob Sie denselben Anweisungssatz wiederholt ausführen möchten.
GroßmeisterB

10
Diese ganze Frage scheint eine jener Situationen zu sein, in denen der grundlegende Ansatz falsch ist. Aber es ist schwierig, genau zu sagen, was passiert, weil wir so wenig über den Problemraum wissen.
Erick Robertson

Antworten:


46

Es ist sicher, wenn Sie danach fragen. Solange Sie genauso sorgfältig mit Ihrer Sicherheit umgehen wie mit der Sicherheit Ihrer Daten.

Aber erfinde das Rad nicht neu. Gespeicherte Prozeduren SIND SQL-Bits, die in einer Tabelle gespeichert sind. Und sie unterstützen, ja fördern die Parametrisierung.

Beachten Sie auch, dass Sie Ihre Sicherheit vereinfachen UND die Anzahl der Fehlerstellen UND die Netzwerkkommunikation verringern können, indem Sie den MySql Event Scheduler anstelle von cron verwenden.

Andere Datenbanken haben aus gutem Grund Entsprechungen zu diesen. Sie sind nicht der erste, der diese Funktionalität benötigt.


1
+1 bei Verwendung des Schedulers. Das Beschränken des Scheduler-Zugriffs auf nur die Procs ist besser als der Tabellenzugriff.
JeffO

Aber was ist, wenn Sie diese Abfragen dynamisch erstellen müssen, beispielsweise über eine Benutzeroberfläche? Zum Beispiel, wenn Sie Administratoren erlauben, Zugriffsregeln für Webinhalte basierend auf komplexen Abfragen dynamisch festzulegen. Sie möchten nicht, dass die Benutzeroberfläche einen neuen Proc in der Datenbank erstellt. Ich denke, unter bestimmten Umständen sind gespeicherte Abfragen besser als procs.
DiscipleMichael

32

Wenn Sie SQL-Anweisungen für eine spätere Ausführung in einer Datenbank speichern möchten, gibt es eine bessere Möglichkeit, als sie in einer Tabelle abzulegen: Verwenden Sie die für diesen speziellen Zweck bereitgestellten integrierten Funktionen. Versetzen Sie sie in gespeicherte Prozeduren.


2
Wo speichert der Cron-Job die Liste der auszuführenden gespeicherten Prozeduren?
JeffO

1
Dies kann nützlich sein stackoverflow.com/questions/6560639/… obwohl es nicht mit Cron
MetaFight

Ich weiß nicht, was ich gedacht habe. Eine Liste von Prozessen könnte alle von einem einzigen Prozess ausgeführt werden, so dass der Cron-Job nur einen ausführen muss.
JeffO

11

Nein, ich würde sagen, es ist keine gute Idee.

Dies bedeutet, dass jede "echte" Abfrage / Aktualisierung 2 Treffer in der Datenbank benötigt - einen, um die "echte" Abfrage / Aktualisierung zu erhalten, und einen, um sie auszuführen.

In einem kleinen System ist dies möglicherweise kein großes Problem, aber je mehr Benutzer / Transaktionen Ihr System erhält, desto weniger wird es skalieren.

Ich vermute, dies kommt von der Suche nach einer Alternative zum Einbetten von SQL in Ihren Code?

Das Einkapseln von SQL in eine gespeicherte Prozedur, wie es Mason Wheeler vorgeschlagen hat, wäre eine Möglichkeit, die viel besser ist als diese Idee.


+1, dies ist der Hauptgrund, warum die Lösung von @Mason Wheeler die richtige ist - er hat es nur versäumt, dies hervorzuheben. Obwohl es meiner Meinung nach nicht um die Leistung geht, sehe ich hier das Wichtigste - es ist nicht notwendig, Dinge zu komplizieren, indem man eine SQL-Anweisung aus der Datenbank extrahiert und sie dann zur Ausführung zurücksendet.
Doc Brown

Warum muss die Liste der SQL-Anweisungen in derselben Datenbank / auf demselben Server usw. gespeichert werden?
JeffO

1
Das OP ist dasjenige, das 2 Treffer in der Datenbank vorschlägt. Ich sage, er sollte es nicht tun. Dann fragen Sie, warum es sich um dieselbe Datenbank / denselben Server handeln muss. Ich frage, wer hat das gesagt? du fragst dann, wie sonst bekommst du 2 treffer auf die DB. Warum stellst du nicht deine eigentliche Frage, anstatt was immer du tust?
ozz

1
@ JeffO Auch wenn es sich um eine andere Datenbank handelt, sind es immer noch 2 Datenbankabfragen für 1 Abfrage, was eine unnötige Verlangsamung darstellt
Izkata

1
@Ozz: Sie geben dem Leistungsaspekt Ihrer Antwort zu viel Gewicht - die Leistung ist in den meisten realen Szenarien höchstwahrscheinlich vernachlässigbar. Die Notwendigkeit von zwei Aktionen (erstens, um die "echte" Abfrage / Aktualisierung zu erhalten, zweitens, um sie auszuführen) macht die Dinge jedoch nur komplizierter als nötig.
Doc Brown

4

Entschuldigung, das halte ich nicht für eine gute Idee.

Betrachten Sie den Fall, in dem sich die betreffende Tabelle ändert. Angenommen, Ihre ID- Spalte wird in new_id umbenannt .

Neben der Änderung selbst gibt es eine Version Ihres Codes, die für einen alten Jahrgang der Datenbank geschrieben wurde und möglicherweise nicht mehr ausgeführt wird. Sicher, Sie könnten wissen, dass Sie die Codetabelle einchecken müssen, aber es ist für jemanden anderen nicht sofort offensichtlich.

Bei einer Änderung, wie ich sie beschrieben habe, würde ich mich normalerweise mit eigenständigen SQL-Dateien, gespeicherten Prozeduren, Triggern und Inline-SQL im Client-Code (VB, C #, C ++ usw.) befassen ist in den Datenbanktabellen. Obwohl ich es jetzt vielleicht werde! :)


2

Es gibt triftige Gründe, SQL in einer Tabelle zu speichern. Die Software, mit der ich bei der Arbeit arbeite, enthält jetzt ein System zum Generieren von Dokumenten, und die Dokumente müssen ziemlich komplexe Berechnungen unter Verwendung von Daten in einer Datenbank enthalten. Die Dokumente werden häufig aktualisiert, unterscheiden sich häufig erheblich in Bezug auf die benötigten Daten und die durchzuführenden Berechnungen. Grundsätzlich wird SQL als Skriptsprache für diese Berechnungen verwendet, und SQL wird in Tabellen gespeichert, in denen auch andere Informationen für diese Dokumente gespeichert sind. Die Personen, die diese Dokumente verwalten, sind keine Programmierer oder Datenbankadministratoren, aber sie kennen das Datenbankschema und beherrschen SQL. Es wäre ein erheblicher Aufwand für sie, diesen SQL-Code in Form von gespeicherten Prozeduren zu verwalten.

Für das, was Sie beschrieben haben - "... ein Projekt, das eine ganze Reihe von Cron-Jobs erfordert, die regelmäßig SQL-Anweisungen ausführen" -, schlagen die anderen Antworten wahrscheinlich vor , dass Sie für das DBMS, das Sie verwenden, Speicherprozeduren oder Ähnliches verwendet haben. wieder verwenden.

Ein gutes Kriterium für die Entscheidung, ob das Speichern von SQL in einer Tabelle im Vergleich zu einer gespeicherten Prozedur sinnvoll ist, ist die Bestimmung, wer dieses SQL verwaltet. Wenn Benutzer diese SQL pflegen, dh sie schreiben und ändern, wann immer sie möchten, ist es möglicherweise vollkommen in Ordnung und am besten, diese SQL in einer Tabelle zu speichern. Wenn Entwickler dieses SQL beibehalten, sollte es in einer Form gespeichert werden, die durch Ihre (hoffentlich automatisierten) Erstellungs- und Bereitstellungsprozeduren aktualisiert werden kann, z. B. als Objekt wie eine gespeicherte Prozedur in der Datenbank selbst gespeichert.


1
Danke für die Antwort. Am Ende habe ich MySQL-Ereignisse verwendet, um die auszuführenden Abfragen zu planen. Nicht wenige Leute dachten, "der grundlegende Ansatz ist falsch" :), als ich nur ein paar SQL-Anweisungen nach 15 Minuten von einer bestimmten Benutzeraktion aus ausführen musste.
Amged Rustom

2
@AmgadSuliman - Es ist wichtig, dass alle gemeinnützig sind, insbesondere auf den SE-Standorten. Es ist gut, starke Meinungen zu haben, aber es ist zu leicht, Muster zu übertreffen, gegen die wir gerne abwägen. Ein Teil der Gemeinnützigkeit für andere auf diesen Websites besteht darin, genügend Kontext bereitzustellen. Zu viel kann die eigentliche Frage verdecken, aber im Allgemeinen lässt sich dies durch nachfolgende Bearbeitung relativ einfach beheben.
Kenny Evitt

1

Der einfache Ausweg wäre, über eine INI- Datei oder eine andere Konfigurationsdatei zu verfügen , in der die Abfragen gespeichert werden. Auf diese Weise können Sie sie an einem Ort aufbewahren und alles ändern, ohne dafür auf die Datenbank zugreifen zu müssen Außerdem möchten / müssen Sie möglicherweise irgendwann Parameter verwenden oder Bedingungen zu Ihren Abfragen hinzufügen (um sie mit komplexeren Informationen für einen bestimmten Fall in Ihrem Code zu ergänzen).

Natürlich können Sie sie auf Datenbankebene behalten (entweder in einer Tabelle oder, besser gesagt, als gespeicherte Prozeduren), aber wenn Sie so faul sind wie ich ;-), aber auch mit der Leistung, einer INI- Datei und PHPs befasst sind Die geliebte parse_ini- Methode zum Lesen ist der richtige Weg (wenn Sie sich für eine andere Programmiersprache entscheiden, sind Sie auf eigene Faust dabei, ähnliche Ansätze zu finden)! Normalerweise lese ich diese Datei im Bootloader der Anwendung und behalte sie in einem statischen Objekt (möglicherweise mit einer Cache-Ebene darüber), um die Dinge wirklich zu beschleunigen, wenn es sich um eine sehr große Anzahl unterschiedlicher Abfragen handelt.


1

Wenn Sie die SQL-Anweisung nur einmal benötigen, z. B. wenn Sie eine Reihe von Vorgängen in die Warteschlange stellen, die außerhalb der Geschäftszeiten ausgeführt werden sollen, funktioniert es einwandfrei, wenn Sie sie in eine Tabelle einfügen.

Wenn Sie dieselbe SQL-Anweisung in festgelegten Intervallen ausführen müssen, ist die von anderen angegebene Route für gespeicherte Prozeduren wahrscheinlich die bessere Wahl.

Das heißt, was Sie fragen, ist ziemlich ungewöhnlich und kann ein Hinweis auf ein anderes Problem sein. Wenn Sie beispielsweise darauf warten, einen Benutzer aus einer Datenbank zu löschen, ist es möglicherweise besser, ein geplantes Skript aufzurufen, das den Vorgang über Ihren Anwendungscode ausführt, als die tatsächlichen SQL-Anweisungen aufzuzeichnen. Auf diese Weise sind SQL und Code niemals nicht synchron.

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.