Najlepszy sposób na organizowanie zapytań SQL przechowywanych w kodzie? (a może powinieneś?) [zamknięty]

13

Jestem pewien, że nie tylko ja denerwuję się, gdy widzą stronę kodu zaśmieconą zapytaniami SQL. ActiveRecord i inne wzorce ORM pomagają złagodzić dużą liczbę SQL używanych w projekcie, ale w wielu przypadkach złożonych zapytań użycie SQL wydaje się być nieuniknione.

Szukam opinii na temat tego, jak zapytania SQL powinny być zorganizowane z resztą kodu (lub zewnętrznie do niego), aby nie rozproszyć go po całym miejscu? Jednym oczywistym pomysłem jest użycie widoków, ale często widoki mogą być źródłem problemów z wydajnością w przypadku wielu dużych tabel indeksowanych itp.

EDYCJA 1 - Zakładam, że już go rozdzieliłeś na warstwę modelu

jellyfishtree
źródło
3
To pytanie jest tu zdecydowanie właściwe - organizacja kodu: „inspiruj odpowiedzi, które wyjaśniają„ dlaczego ”i„ jak ”. i jest z przedmiotów „Wzorce projektowe” i „Architektura” (z Faq )
Michael K
1
Właśnie miałem zadać to samo pytanie. Chciałbym, żeby było tu więcej odpowiedzi.
Michael Kristofik,

Odpowiedzi:

10

Dla mnie SQL jest podstawową częścią (w wielu przypadkach większości) kodu logiki biznesowej. Jeśli spróbujesz oddzielić go od kodu, który działa na zwracanych danych, będziesz bardziej podatny na niezrównoważenie zrozumiałości i możliwości utrzymania kodu.

Gdy na to patrzę, odczytywanie danych, przetwarzanie danych, zapisywanie danych, wyszukiwanie danych ... to wszystko są podobne operacje i najlepiej trzymać je w tym samym miejscu.

Jeśli zaczniesz wyczuwać powielanie wysiłków za pomocą zapytań, być może potrzebujesz widoku bazy danych lub obiektu, który może obejmować ten aspekt dostępu do bazy danych.

Inną wskazówką jest posiadanie dobrej metody zapytania do bazy danych. W oprogramowaniu, które piszę (PostgreSQL, MySQL, SQL Server), zapewniłem, że większość moich zapytań może odbywać się jako pojedyncza instrukcja kodu.

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])

Są to (z grubsza) główne wywołania funkcji, które, jak zapewniam, są częścią mojego „obiektu połączenia”. To zależy od języka, co faktycznie wdrażasz, ale moim celem jest, aby było naprawdę, naprawdę proste i bezbolesne.

Podsumowując, traktuj SQL jako natywną część programowania, a nie abstrakty dla samej abstrakcji.

gahooa
źródło
1
świetna odpowiedź. może po prostu muszę cofnąć się i zacząć patrzeć na SQL jako część kodu, a nie tylko na jego część.
jellyfishtree
1
„nie abstrakcji dla samej abstrakcji” - Dobra uwaga. Streszczenie ze względu na bardziej zrozumiały kod.
Jason Baker,
„Inna wskazówka to mieć dobrą metodę zapytania do bazy danych”: zdecydowanie się zgadzam. Bardzo pomaga, gdy jest tylko jedno miejsce do modyfikowania kodu, gdy zmienia się logika biznesowa.
Michael K
1
Gdzie umieścisz SQL? Czy jest wkompilowany w aplikację i wysłany przy użyciu powyższych metod?
Johnny
W oparciu o komentarz OP dotyczący odpowiedzi Jasona Bakera: „wpatrując się w beczkę gigantycznego zapytania SQL ...”, jak to rozwiązuje problem czytania dużych bloków tekstu SQL?
JeffO
0

Ogólnie rzecz biorąc, najlepszym rozwiązaniem jest posiadanie oddzielnej warstwy modelu. Istnieje wiele wzorców projektowych dla przedsiębiorstw, które dają sposoby na zaprojektowanie tego.

Jason Baker
źródło
przepraszam, powinienem był bardziej konkretny ... Już zakładam, że podzieliłeś je na warstwę modelową. Ale warstwa modelu nadal może być dość rozproszona za pomocą kodu SQL. Może jest to nieuniknione. Inną rzeczą, która mnie przeraża w kodzie modelu, jest kod, który „buduje zapytanie SQL” w oparciu o jakąś logikę… może to powinno zostać wydzielone do własnej fabryki lub coś w tym stylu…
jellyfishtree
2
@jellyfishtree - Obawiam się, że nie rozumiem, na czym polega problem. Boisz się, że twoja warstwa modelu może skończyć się zbyt dużą ilością kodu modelu?
Jason Baker,
ważny obalenie. Martwię się o czytelność. Dobry kod modelu jest zazwyczaj dość łatwy do zrozumienia, ale wpatrywanie się w lufę gigantycznego zapytania SQL nie ma dokładnie takiego znaczenia, jak wyskoczyć na ciebie. Oczywiście pierwszą rzeczą do zrobienia jest właściwe skomentowanie tych zapytań, ale to nie to samo, co dobry, samodokumentujący się kod i tego rodzaju sekcje są rozproszone w całym modelu. Akceptuję to, ale zastanawiałem się, czy istnieje lepszy sposób na wyizolowanie lub uporządkowanie szalonych instrukcji SQL w modelu ...
jellyfishtree,
0

Dobrym pomysłem może być podzielenie warstwy modelu na 3 podwarstwy - „podmioty”, „repozytoria” i „usługi”. Zapewni to rozdzielenie problemów i zebranie SQL w jednym miejscu, poza logiką biznesową.

W tym scenariuszu cały kod pobierania danych, w tym złożony SQL - będzie znajdować się w repozytoriach. Dlatego celem repozytorium jest ukrycie złożonych instrukcji SQL za oczywistymi metodami, takimi jak getUsersWithActiveSubscription().

Encje streszczają prawdziwe nazwy pól tabeli DB z modułami pobierającymi i ustawiającymi, mogą zapewniać konwersję danych między typami pól DB i typami dostępnymi w języku aplikacji / programowania. Jeśli twój ORM to obsługuje - podmioty mogą obsługiwać powiązania.

Warstwa serwisowa to miejsce logiki biznesowej. Usługa pobiera podmioty korzystające z repozytoriów, działa na nie i przechowuje je z powrotem.

GerKirill
źródło