Der beste Weg, um in Ihrem Code gespeicherte SQL-Abfragen zu organisieren? (oder solltest du?) [geschlossen]


13

Ich bin mir sicher, dass ich nicht der einzige bin, der frustriert ist, wenn er eine Seite mit Code sieht, der mit SQL-Abfragen übersät ist. Das ActiveRecord-Muster und andere ORM-Muster tragen dazu bei, die in einem Projekt verwendete SQL-Menge zu verringern. In vielen Fällen komplexer Abfragen scheint die Verwendung von SQL jedoch unvermeidlich zu sein.

Ich bin auf der Suche nach Meinungen darüber, wie SQL-Abfragen mit dem Rest des Codes (oder extern dazu) organisiert werden sollten, um zu verhindern, dass er über den gesamten Bereich verteilt wird. Eine naheliegende Idee ist die Verwendung von Ansichten, aber häufig können Ansichten bei der Verarbeitung mehrerer großer indizierter Tabellen usw. zu Leistungsproblemen führen.

EDIT 1 - Ich gehe davon aus, dass Sie es bereits in die Modellebene getrennt haben


3
Diese Frage ist hier definitiv angemessen - Code-Organisation: "Inspirieren Sie Antworten, die das" Warum "und" Wie "erklären." und gehört zu den Themen 'Design Patterns' und 'Architecture' (aus der FAQ )
Michael K

1
Ich wollte gerade die gleiche Frage stellen. Ich wünschte, es gäbe hier mehr Antworten.
Michael Kristofik

Antworten:


10

Für mich ist SQL ein grundlegender Teil (in vielen Fällen die Mehrheit) des Geschäftslogikcodes. Wenn Sie versuchen, den Code von dem Code zu trennen, der für die zurückgegebenen Daten verwendet wird, besteht die Gefahr, dass die Verständlichkeit und Wartbarkeit des Codes beeinträchtigt wird.

Wenn ich es mir anschaue, wie Daten gelesen, verarbeitet, geschrieben oder durchsucht werden, handelt es sich um ähnliche Vorgänge, die sich am besten am selben Ort befinden.

Wenn Sie feststellen, dass Abfragen doppelt ausgeführt werden, benötigen Sie möglicherweise eine Datenbankansicht oder ein Objekt, das diesen Aspekt des Datenbankzugriffs kapselt.

Ein weiterer Tipp ist eine gute Datenbankabfragemethode. In der Software, die ich schreibe (PostgreSQL, MySQL, SQL Server), habe ich sichergestellt, dass der Großteil meiner Abfrageoperationen als einzelne Code-Anweisung ausgeführt werden kann.

GetValue(SQL, [transaction], [array_of_params])
GetRow(SQL, [transaction], [array_of_params])
GetRowList(SQL, [transaction], [array_of_params])
GetValueList(SQL, [transaction], [array_of_params])
Execute(SQL, [transaction], [array_of_params])

Dies sind (ungefähr) die Hauptfunktionsaufrufe, die ich als Teil meines "Verbindungsobjekts" sicherstelle. Es hängt von der Sprache ab, was Sie tatsächlich implementieren, aber es geht mir darum, es wirklich, wirklich einfach und schmerzlos zu halten.

Zusammenfassend lässt sich sagen, dass SQL ein nativer Bestandteil der Programmierung ist und nicht der Abstraktion zuliebe abstrahiert wird.


1
eine großartige Antwort. Vielleicht muss ich nur einen Schritt zurücktreten und anfangen, die SQL als Teil des Codes zu betrachten, nicht nur verstreut.
Quallenbaum

1
"nicht der Abstraktion zuliebe abstrahieren" - Guter Punkt. Auszug aus Gründen des verständlicheren Codes.
Jason Baker

'Ein weiterer Tipp ist, eine gute Datenbankabfragemethode zu haben': Ich stimme definitiv zu. Es ist sehr hilfreich, wenn es nur einen Ort gibt, an dem Code geändert werden kann, wenn sich die Geschäftslogik ändert.
Michael K

1
Woher nimmst du die SQL? Wird es in die Anwendung kompiliert und mit den oben genannten Methoden gesendet?
Johnny

Wie wird das Problem des Lesens großer SQL-Textblöcke gelöst, basierend auf dem Kommentar von OP zu Jason Bakers Antwort "Das Fass einer riesigen SQL-Abfrage hinunterstarren ..."?
JeffO

0

Im Allgemeinen ist eine separate Modellebene der beste Ansatz. Es gibt eine Reihe von Enterprise-Design-Mustern , mit denen dies möglich ist.


Entschuldigung, ich hätte präziser sein sollen ... Ich gehe bereits davon aus, dass Sie sie in eine Modellebene aufgeteilt haben. Aber eine Modellschicht kann mit SQL-Code immer noch ziemlich verstreut sein. Vielleicht ist das unvermeidlich. Die andere Sache , die ich Freaks im Modell - Code aus Code ist , dass auf einiger Logik „eine SQL - Abfrage baut“ ... vielleicht sollte dieser heraus in seine eigenen Fabrik oder etwas getrennt werden ...
jellyfishtree

2
@ Quallenbaum - Ich fürchte, ich verstehe nicht, was das Problem dann ist. Ich meine, Sie haben Angst, dass Ihre Modellebene zu viel Modellcode enthält?
Jason Baker

eine gültige Widerlegung. Ich mache mir Sorgen um die Lesbarkeit. Guter Modellcode ist in der Regel recht einfach zu verstehen, aber wenn man eine riesige SQL-Abfrage ausführt, hat das nicht gerade eine Bedeutung, die einem auffällt. Natürlich ist es das erste, was zu tun ist, diese Abfragen richtig zu kommentieren, aber es ist nicht dasselbe wie guter, selbstdokumentierender Code, und diese Art von Abschnitten wird über das Modell verteilt. Ich akzeptiere es, aber ich habe mich gefragt, ob es eine bessere Möglichkeit gibt, verrückte SQL-Anweisungen im Modell zu isolieren oder zu organisieren ...
jellyfishtree

0

Es könnte eine gute Idee sein, die Modellebene in drei Unterebenen zu unterteilen: "Entities", "Repositories" und "Services". Auf diese Weise können Sie Bedenken voneinander trennen und SQL aus Ihrer Geschäftslogik heraus an einem Ort sammeln.

In diesem Szenario befindet sich der gesamte Datenabrufcode, einschließlich komplexer SQL-Anweisungen, in Repositorys. Ziel von repository ist es also, komplexe SQL-Anweisungen hinter selbsterklärenden Methoden wie zu verstecken getUsersWithActiveSubscription().

Entität abstrahiert echte DB-Tabellenfeldnamen mit Gettern und Setzern und bietet möglicherweise eine Datenkonvertierung zwischen DB-Feldtypen und Typen, die in Ihrer Anwendung / Programmiersprache verfügbar sind. Wenn Ihr ORM dies unterstützt, können Entitäten mit Assoziationen umgehen.

Die Serviceschicht ist der Ort für die Geschäftslogik. Der Dienst ruft Entitäten mithilfe von Repositorys ab, verarbeitet sie und speichert sie zurück.

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.