Welche Vorteile bietet die Verwendung von SQL Query Buildern?


17

Gibt es irgendwelche Vorteile bei der Verwendung eines Abfrageerstellungsprogramms anstelle von unformatiertem SQL?

Z.B

$q->select('*')
  ->from('posts')
  ->innerJoin('terms', 'post_id')
  ->where(...)

vs:

SELECT * FROM posts WHERE ...

Ich sehe, dass viele Frameworks diese Art von Abstraktionsebenen verwenden, aber ich verstehe die Vorteile nicht.


Ich denke, man sollte Abfragen gegen Ansichten und nicht gegen Tabellen schreiben. Ich neige dazu zu glauben, dass Leute, die Query Builder verwenden, keine Views schreiben oder DBAs bitten, sie für sie zu erstellen. Dabei nutzen sie nicht die gesamte Leistung des RDBMS.
Tulains Córdova

1
@ user61852: Abgesehen von möglicherweise kostenlosen Sicherheits- und Filterfunktionen können Abfragen für Ansichten nicht auch Abfragen für Tabellen bereitstellen.
Robert Harvey

4
@RobertHarvey Dasselbe wie das Programmieren auf Interfaces anstelle konkreter Klassen. Entkopplung und Flexibilität. Das Design der zugrunde liegenden Tabellen könnte Zufall sein, solange der "Vertrag", die Ansicht, dieselben Spalten wie bisher "simuliert".
Tulains Córdova

@ user61852 Fair genug.
Robert Harvey

@RobertHarvey Ich habe daraus eine Antwort gemacht.
Tulains Córdova

Antworten:


20

Die Abstraktion des Schreibens der SQL über ein Framework gut, Abstracts.

SQL von Hand zu schreiben ist an sich nicht so schlimm, aber man bekommt Probleme mit dem Flüchten und Desinfizieren und dies wird zu einem Chaos. Eine Abstraktionsschicht kann sich hinter den Kulissen darum kümmern, dass Ihr Code sauber und frei von vielen mysql_real_escape_string()Anrufen oder Ähnlichem ist.

Darüber hinaus besteht die Möglichkeit, unterschiedliche SQL-Dialekte zu berücksichtigen. Nicht alle Datenbanken sind gleich aufgebaut und es kann Abweichungen bei den Schlüsselwörtern oder der Syntax einer bestimmten Funktionalität geben. Durch die Verwendung einer Abstraktionsebene können Sie die korrekte Syntax für Ihre Variante dynamisch generieren.

Ein Abstraktionslayer kann zwar zu Leistungseinbußen führen, ist jedoch im Vergleich zur Sauberkeit und Robustheit des Codes, den Sie im Gegenzug erhalten, im Allgemeinen vernachlässigbar.


1
Ich glaube nicht, dass sich die SQL-Dialekte in RDBMS unterscheiden. Und in PHP gibt es PDO, das die Desinfektion für u durchführt
Anna K.

12
SQL-Dialekte unterscheiden sich, deshalb werden sie Dialekte genannt. Was PDO betrifft, verbirgt die Abstraktionsschicht dieses Durcheinander einfach vor uns.

@GlennNelson Anna meinte einen beliebigen Dialekt mit verschiedenen Backends (PSQL / MySQL / SQLite ...)
Izkata

2
@AnnaK. Der Dialekt ändert sich möglicherweise nicht, aber manchmal unterscheiden sich die Funktionen. Beispielsweise unterstützt MySQL (mit der MyISAM-Engine) keine Fremdschlüsseleinschränkungen, während PostGres dies tut. Entweder muss der Dialekt so etwas selbst handhaben (was vollständige Kenntnisse der Datenstruktur erfordert, wie es der Django ORM tut), oder wahrscheinlicher: Der Benutzer muss schlau sein, wie er es verwendet, was dazu führen könnte, dass es so aussieht Wie sich der Dialekt ändert, hängt von den Umständen ab.
Izkata

1
+1 für ein gut gebautes Tool, das Ihre Flucht und Desinfektion für Sie erledigt. Wenn es auch validieren kann, dann noch besser.
Dan Ray

11

Abfrageersteller sind mein Lieblingshass, daher habe ich mein eigenes Framework (Apeel) geschrieben, um sie nicht zu verwenden!

Wenn Sie PDO verwenden (was ich definitiv empfehle), wird das Santizing der Eingabe für Sie gehandhabt.

Wie jemand anderes sagte, unterstützen sie die Funktionalität "Niedrigster gemeinsamer Nenner", obwohl sie das Wechseln zwischen Datenbanken erleichtern, und sie unterstützen entweder keine oder eine schlechtere Leistung für erweiterte Funktionen.

Ich habe seit 1986 Systeme mit Datenbanken entwickelt und in der ganzen Zeit bin ich selten auf ein Unternehmen gestoßen, das die von ihnen verwendete Datenbank geändert hat, außer wenn eine bessere Leistung erforderlich war. Wenn Sie Datenbanken ändern, um eine bessere Leistung zu erzielen, ist es viel sinnvoller, Ihre Abfragen manuell zu optimieren, um das Beste aus der neuen Datenbank herauszuholen, als der Einfachheit halber den Treffer eines Abfrageerstellers zu nehmen.

Die Zeit, die Sie damit verbringen, sich mit den qwirks eines Query Builders zu beschäftigen (und dann neu zu lernen, wenn Sie zu einem besseren wechseln), wäre weitaus produktiver, wenn Sie lernen, wie Sie Ihr SQL optimieren.

Aus diesem Grund sollte man sowieso KEINEN benutzen, manche Leute lieben sie jedoch.


4

Theoretisch? Ja. Glenn Nelson wies darauf hin, wie oft sie Ihnen helfen werden. (Wenn es ein guter Query Builder ist).

In der Praxis? Entspricht nicht immer der Theorie und kann tatsächlich Probleme verursachen. Angenommen, Sie verwenden einen Abfrage-Generator für einige gängige DBMS und alles ist pfirsichfarben. Dann bittet Sie ein Kunde, sein DBMS zu aktivieren, das einige Fehler aufweist, die Ihr ausgewählter Abfrage-Generator einfach nicht verarbeiten kann. (Ich bin auf dieses Problem gestoßen, als ich mit einer älteren Version von Pervasive arbeiten musste.)

ABER! Was Sie unbedingt tun sollten, ist die Datenzugriffsschicht zu trennen und sicherzustellen, dass Sie bei Bedarf eine neue austauschen können. Auf diese Weise können Sie den coolen Query Builder mit allen Funktionen erstellen, aber wenn Sie einen neuen einstecken müssen, der diese seltsame Pseudo-SQL für die betreffende Datenbank verwendet.


2
Sollte nicht schon vorher so etwas wie die DB-Quirk-Situation geklärt werden? Ich meine, herauszufinden, welche Datenbank Ihr Client verwendet und die richtigen Frameworks / Bibliotheken entsprechend auszuwählen, ist etwas, das behandelt werden sollte, bevor Sie eine einzelne Codezeile schreiben.

3

Ich denke, der praktische, alltägliche Vorteil von Query Builder ist die Wiederverwendung von Code und die Fähigkeit, dem DRY-Prinzip zu folgen.

Mit dem Abfrage-Generator können Sie sich wiederholende Teile von SQL in Methoden einfügen. Verwenden Sie diese Methoden, um komplexes SQL zu erstellen. Ein Beispiel wäre zB eine wiederverwendbare JOIN-Klausel:

function joinTaskWithClient($queryBuilder) {
    $queryBuilder->join('task', 'contract', 'task.contract_id = contract.id')
                 ->join('contract', 'client', 'contract.client_id = client.id');
}

Die Verwendung wäre also:

$queryBuilder->select('client.name')
             ->from('client')
             ->where('task.id=:task')->setParameter('task', 42);
joinTaskWithClient($queryBuilder);

Wie Sie vielleicht bemerken, können Sie mit dem Abfrage-Generator Teile von SQL in beliebiger Reihenfolge hinzufügen (z. B. JOIN-Teil nach WHERE-Teil), im Gegensatz zu dem Fall, in dem Sie SQL-Zeichenfolgen manuell erfassen. Sie können auch Informationen zum Builder-Muster lesen , um die Absichten und Vorteile zu sehen.

Ich bin damit einverstanden, was das Flüchten und Desinfizieren betrifft, aber dies könnte auch ohne Abfrageerstellung erreicht werden. In Bezug auf die DB-Typ- / Dialekt-Abstraktion ist dies ein theoretischer und fragwürdiger Vorteil, der in der Praxis kaum verwendet wird.


Für mich ist das auch ein Hauptvorteil. Eine andere ist, dass Sie durch Abstrahieren in Methoden den Methoden aussagekräftigere Namen geben und sogar eine domänenspezifische Sprache daraus erstellen können, um die Absicht viel klarer zu machen. Sie können den Abfrage-Generator auch weitergeben und verschiedene Komponenten die it-spezifischen Bits hinzufügen lassen. Last but not least habe ich festgestellt, dass es mir erlaubt ist, Muster hinter Methoden mit aussagekräftigen Namen zu kapseln .... Ich habe einige Abfrage-Builder gefunden, bei denen das Hinzufügen von Spalten dummerweise frühere überschrieb, was eine Menge der oben genannten nutzlosen ...
malte macht

2

Ich werde eine Antwort auf der Grundlage der Readme-Datei eines benutzerdefinierten SQL-Builders von mir ( Dialekt ) bereitstellen.

(Klartext folgt, bibliotheksspezifische Verweise entfernt)

Bedarf

  1. Unterstützung mehrerer Datenbankanbieter (z. B. MySQL, PostgreSQL, SQLite, MS SQL / SQL Server, Oracle, DB2 usw.)
  2. Einfache Erweiterung auf neue DBs (vorzugsweise über eine implementierungsunabhängige Konfigurationseinstellung)
  3. Modularität und implementierungsunabhängige Übertragbarkeit
  4. Flexible und intuitive API

Eigenschaften

  1. Grammatik-basierte Vorlagen
  2. Unterstützung für benutzerdefinierte Soft Views
  3. db Abstraktion, Modularität und Übertragbarkeit
  4. vorbereitete Vorlagen
  5. Daten entkommen

Ich denke, die oben genannten Funktionen und Anforderungen skizzieren die Gründe, warum man einen SQL-Abstraktions-Builder verwenden würde

Die meisten der oben genannten Funktionen werden von den meisten SQL-Buildern unterstützt (obwohl meines Wissens nicht alle aufgelisteten Funktionen unterstützt werden).

Anwendungsbeispiele:

  1. Die CMS-Plattform kann (ohne Änderung des zugrunde liegenden Codes) mit mehreren Datenbankanbietern zusammenarbeiten
  2. Benutzerdefinierter Anwendungscode, bei dem sich der DB-Anbieter ändern kann und / oder dB-Schemata dynamisch sind (dies bedeutet, dass viele Abfragen nicht fest codiert werden können, aber dennoch abstrahiert werden müssen, damit der Code Änderungen standhält)
  3. Prototyping mit einer anderen Datenbank als der in der Produktion verwendeten (würde zumindest für einen Teil des Codes eine doppelte Codebasis erfordern)
  4. Der Anwendungscode ist nicht eng an einen bestimmten DB-Anbieter und / oder eine bestimmte Implementierung gekoppelt (auch nicht innerhalb desselben DB-Anbieters, z. B. verschiedener Versionen des DB-Anbieters). Daher ist er robuster, flexibler und modularer
  5. Viele übliche Fälle von Abfragen und Datenflucht werden vom Framework selbst behandelt. In der Regel ist dies sowohl optimal als auch schneller

Zum Schluss ein Beispiel für einen Anwendungsfall, den ich hatte. Ich baute eine Anwendung, in der das zugrunde liegende DB-Schema (WordPress) nicht für die Art von Datenabfragen geeignet war, die durchgeführt werden mussten, und einige der WP-Tabellen (z. B. Posts) verwendet werden mussten (also völlig neue Tabellen hatten) für alle Bewerbungsdaten war keine Option).

In diesem Fall war es fast ein Albtraum, eine MVC-ähnliche Anwendung zu erstellen, in der das Modell durch benutzerdefinierte / dynamische Bedingungen abgefragt werden konnte. Stellen Sie sich vor, Sie müssen das Abfragen von bis zu 2-3 Tabellen mit Joins unterstützen und die Bedingungen filtern, um zu sehen, welche Tabelle mit welchen verknüpft werden soll, und sich auch um die erforderlichen Aliase usw. kümmern.

Offensichtlich war dies ein Anwendungsfall für die Abfrage-Abstraktion, und noch wichtiger war die Fähigkeit, benutzerdefinierte Soft Views (ein Konglomerat verknüpfter Tabellen, als ob sie eine für das Modell geeignete benutzerdefinierte Tabelle wären ) zu definieren (oder zumindest stark davon zu profitieren ). . Dann war es viel einfacher, sauberer, modularer und flexibler. In einem anderen Aspekt verwendete die Anwendung (Code) auch die Abfrageabstraktionsschicht als ein (DB-Schema-) Normalisierungstool . Wie manche sagen, war es zukunftssicher .

Wenn die Leute morgen entscheiden, dass sie zusätzliche Optionen oder Daten benötigen, ist es sehr einfach, dies in ein paar Zeilen zum Modell hinzuzufügen und es funktioniert einwandfrei. Außerdem ist es relativ einfach, die Modelle in ein paar Zeilen zu ändern ( nur die Definition ) , wenn die Leute morgen entscheiden, dass sie WordPress nicht mehr verwenden möchten (da die Anwendung lose an WordPress als Plugin gekoppelt ist ) von Code an das neue Schema anzupassen.

Verstehst du, was ich meine?


1

Nicht selten sind das Argument für diese Abfragen eher Werte als Konstanten. Viele von ihnen wurden im Wesentlichen von Benutzerformularen abgeleitet. Daher gibt es viele Möglichkeiten für SQL-Injection-Angriffe. Die eigentümliche Abfrageerstellung erfordert daher eine vollständige Validierung.

Das soll nicht heißen, dass wir dem Entwickler nicht vertrauen, aber das Erstellen von Abfragen könnte einfach sein, aber das Wiederholen aller möglichen Überprüfungen überall könnte bedeuten, dass Sie manchmal zufällig etwas verpassen oder die Abfrage ändern, aber nicht die Abfrage ändern, sondern nicht kann die Validierungsprüfung nicht aktualisieren. Einige Neulinge kennen vielleicht sogar die Gefahren, die entstehen können, wenn sie dies verpassen. Daher ist die Abstraktion des Abfrageerstellers sehr wichtig.


0

Früher dachte ich, Query Builder seien GUI-Apps, mit denen Sie Tabellen auswählen und Verknüpfungen grafisch erstellen können, während Sie SQL unter der Haube generieren. Jetzt verstehe ich, dass Sie Query Builder auch APIs nennen, mit denen Sie keine reinen SQL-Abfragen erstellen müssen , so abstrahieren Sie sich von möglichen Unterschieden in SQL-Aromen.

Die Verwendung solcher Abfrage-Builder ist gut , aber ich neige dazu zu glauben, dass Leute, die sich stark auf sie verlassen, DBAs nicht fragen: "Hey, das ist eine Abfrage, die ich häufig verwende, bitte erstelle daraus eine Ansicht."

Versteh mich nicht falsch.

Ich denke, dass Sie Abfragen gegen Ansichten und nicht Tabellen schreiben sollten. Nicht aus Sicherheits- oder Filtergründen, sondern aus demselben Grund sollten Sie gegen Schnittstellen und nicht gegen konkrete Klassen codieren: Entkopplung. Ansichten sind wie "Verträge", genauso wie Schnittstellen in OOP "Verträge" sind. Sie können die zugrunde liegenden Tabellen ändern, aber solange Sie die Ansichten zwingen, den Programmierern denselben "Vertrag" anzuzeigen, sollte der Code nicht beschädigt werden.

Versteht mich auch nicht falsch, Sie können Abfrage-Builder verwenden, um Ansichten abzufragen, aber viele Ansichten entstehen als ein Prozess, bei dem Sie Abfragen schreiben und Ihren Datenbankadministrator fragen müssen: "Mann, schaffen Sie das, bitte". .

Bin ich falsch, wenn Sie keine Abfragen schreiben, erkennen Sie nicht, dass bestimmte Ansichten erstellt werden müssen?

Eine andere Sache, die mich beschäftigt, sind unerfahrene Programmierer, die SQL nicht beherrschen, eine der schönsten Technologien, die der Mensch geschaffen hat, weil er dies nicht tun muss.


Wie wäre es mit einem DBA, der sagt: "Diese Abfrage läuft schlecht, lassen Sie uns zusammenarbeiten und sie verbessern." Anfangs hat es vielleicht prima geklappt, aber jetzt treten Probleme auf. Wenn alles, was benötigt wird, ein Index ist, warum den Entwickler damit belästigen?
JeffO

Das ist eine völlig andere Situation und vollkommen in Ordnung.
Tulains Córdova

Ich habe einfach das Gefühl, den DBA jedes Mal einzubeziehen, wenn eine Abfrage einen einzelnen Datensatz aus einer Tabelle oder Sicht abruft, was zu einem Engpass im Entwicklungsprozess führt.
JeffO
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.