„Nigdy nie rób w kodzie tego, co możesz zrobić, aby serwer SQL robił dla ciebie dobrze” - Czy to przepis na zły projekt?

204

To pomysł, który słyszałem wielokrotnie w kilku miejscach. Niektórzy mniej lub bardziej uznają, że gdy próba rozwiązania problemu czysto w języku SQL przekracza pewien poziom złożoności, rzeczywiście powinieneś poradzić sobie z nim w kodzie.

Logika leżąca u podstaw tego pomysłu polega na tym, że w większości przypadków silnik bazy danych wykona lepszą pracę w znalezieniu najbardziej wydajnego sposobu wykonania zadania niż w kodzie. Zwłaszcza jeśli chodzi o uzależnienie wyników od operacji wykonywanych na danych. Prawdopodobnie dzięki nowoczesnym silnikom skutecznie JIT'ing + buforowanie skompilowanej wersji twojego zapytania, miałoby to sens na powierzchni.

Pytanie brzmi, czy wykorzystanie silnika bazy danych w ten sposób jest z natury złą praktyką projektową (i dlaczego). Linie zamazują się jeszcze bardziej, gdy cała logika istnieje w bazie danych i po prostu uderzasz ją za pomocą ORM.

PhonicUK
źródło
60
To jedno z tych powiedzeń, które należy wziąć pod rozwagę. Jest wyrzucany za każdym razem, gdy ktoś znajdzie innego inżyniera wykonującego „select * from table”, a następnie przeczesującego zestaw wyników zamiast używać klauzuli where i określającego kolumny. Ale jeśli posuniesz się za daleko, skończysz z innym bałaganem.
Michael Kohne
154
Rozpoczęcie frazy od „nigdy” lub „zawsze” jest prawie zawsze przepisem na zły projekt.
vsz
34
Chociaż z pewnością można próbować robić za dużo w SQL, mogę szczerze powiedzieć, że w ciągu 30 lat rozwoju i konsultacji nigdy nie spotkałem się z poważnym przypadkiem (kilka drobnych). Z drugiej strony widziałem dosłownie setki poważnych przypadków programistów próbujących zrobić wiele w „kodzie”, które powinni byli zrobić w SQL. I nadal je widzę. Często ...
RBarryYoung
2
@MrEdmundo Zabierz to do meta.
ta.speot.is
4
To pytanie jest dwa w jednym - myślę, że należy je podzielić. 1) Ile należy zrobić w SQL? 2) Ile należy zrobić w DBMS? Procedury składowane znajdują się na środku. Widziałem całe aplikacje zakodowane w procedurach przechowywanych.
reinierpost

Odpowiedzi:

321

Słowami laika:

Są to rzeczy, które wykonuje SQL, i wierzcie lub nie, widziałem to w kodzie:

  • joins - kodewise wymagałoby to złożonej manipulacji tablicami
  • filtrowanie danych (gdzie) - według kodu wymagałoby to intensywnego wstawiania i usuwania elementów z list
  • wybieranie kolumn - kodowanie wymagałoby dużej manipulacji listami lub tablicy
  • funkcje agregujące - kodowe wymagałoby tablic do przechowywania wartości i złożonych przypadków przełączania
  • integralność klucza obcego - kodowo wymagałoby zapytań przed wstawieniem i zakłada, że ​​nikt nie będzie korzystał z danych poza aplikacją
  • integralność klucza podstawowego - kodowanie wymagałoby zapytań przed wstawieniem i zakłada, że ​​nikt nie będzie korzystał z danych poza aplikacją

Wykonanie tych czynności zamiast polegania na SQL lub RDBMS prowadzi do napisania ton kodu bez dodatkowej wartości , co oznacza więcej kodu do debugowania i utrzymania. Niebezpiecznie zakłada się, że dostęp do bazy danych będzie możliwy tylko za pośrednictwem aplikacji.

61852
źródło
88
+10000000000 za wskazanie, że niebezpiecznie zakłada, że ​​wszystko wydarzy się tylko poprzez aplikację.
HLGEM
11
@skynorth Prowadzi to do złego projektu bazy danych. W dolnej linii znajduje się baza danych, do której dostęp może uzyskać tylko ta aplikacja, ze względu na całą jej obróbkę końcową .
Sirex,
21
@skynorth Jeśli polegasz na kodzie, aby mieć pewność, że twoje klucze zachowują integralność, to usuwasz podstawową zasadę RDBMS z bazy danych. To nie ma sensu, ponieważ wtedy każda aplikacja, która uzyskuje dostęp do bazy danych, musi dokładnie replikować tę funkcjonalność. Dlaczego nie po prostu pozwolić DB to obsłużyć, ponieważ do tego jest przeznaczony. Baza danych może na przykład zapobiegać natywnemu duplikowaniu kluczy.
Buttle Butkus
10
nie zapomnij transakcji!
Sklivvz
24
@skynorth: tl; dr: Reguły zapewniające spójność danych powinny zostać zaimplementowane w bazie danych. tj. dla 99% aplikacji, które kiedykolwiek napisano, dane (a zatem baza danych) żyją długo, po tym jak aplikacja zniknęła. Widziałem to wiele, wiele razy w ciągu ostatnich lat (hej, musimy wdrożyć wersję na Windows / iPhone / Android / cokolwiek-nowa-rzecz-jest, ponieważ {wstaw tutaj starą platformę} umiera, my ' ll hosta lub bazy danych Oracle tu i utworzyć nowy UI tam ). Nie ma powodu, aby ten trend ustał dzisiaj lub w najbliższym czasie.
Binary Worrier
122

Chciałbym sformułować inaczej: „Nigdy nie rób w kodzie tego, co SQL Server może dla Ciebie zrobić dobrze ”.

Rzeczy takie jak manipulowanie ciągami, praca wyrażeń regularnych i takie, których nie zrobiłbym w SQL Server (z wyjątkiem SQL CLR).

Powyżej zwykle mówi się o takich rzeczach - przyłącza się, ustawia operacje i zapytania. Zamiarem tego jest przekazanie dużej części ciężkiego podnoszenia do SQL Server (w rzeczach, w których jest dobry) i zmniejszenie ilości IO tak bardzo, jak to możliwe (więc pozwól SQLowi wykonywać sprzężenia i filtrować za pomocą WHEREklauzuli, zwracając dużo mniejszy zestaw danych niż w innym przypadku).

Oded
źródło
27
Jeśli wszystko, co SQL zrobiłby lepiej niż kod aplikacji, zostałoby umieszczone w warstwie SQL, istnieje dużo logiki biznesowej, która trafiłaby do bazy danych, na lepsze lub gorsze. Widziałem to i tak, wydajność była znakomita. Ale na szczęście wszyscy deweloperzy doskonale znali tworzenie aplikacji i SQL, ponieważ granica między nimi stała się bardzo amorficzna. Nie sugerowałbym tego jako punktu wyjścia, ale raczej punktu końcowego po tym, jak system staje się niezwykle popularny, a wydajność spada z czasem.
Jimmy Hoffa
3
Konie na kursy innit guv?
StuperUser
28
@NathanLong Nie wiem, dlaczego tak wiele osób nadal uważa, że ​​nie możesz utrzymać kodu SQL w kontroli źródła. Na początku mieliśmy wszystkie nasze procedury składowane / skrypty tabel / itp. Niezbędne do utworzenia bazy danych od zera w kontroli źródła, a następnie wykorzystaliśmy projekty baz danych Visual Studio. Działało dobrze bez projektów i lepiej z nimi. SQL, podobnie jak każda inna zmienna rzecz niezbędna do utworzenia systemu, powinna być pod kontrolą wersji! Wdrożenie można wykonać za pomocą narzędzi redgate dla większości RDBMS, jeśli utrzymujesz skrypty tworzenia pod kontrolą wersji, nie utrzymuj skryptów różnicowych przy użyciu narzędzi
Jimmy Hoffa
3
Jeśli Twój SQL obsługuje operacje REGEX i manipulacje ciągami, wykonanie ich w SQL może być dobrym wyborem.
kevin cline
3
@NathanLong: pomyśl o tym w ten sposób, tablica DB jest zdefiniowana przez fragment kodu zapisany w pliku tekstowym, składnia jest zgodna z „tworzenie tabeli ...”. Teraz możesz przechowywać ten plik tekstowy w dowolnym SCM, tak jak chcesz, jeśli masz kod tworzenia tabeli DB w swoim ulubionym języku aplikacji, który wywołuje dowolny wymagany interfejs API, a ty przechowujesz ten plik tekstowy w SCM. Myślę, że problem polega na tym, że niektórzy ludzie myślą, że DB są w jakiś sposób magicznymi zwierzętami i wiedzą tylko, jak pisać kod VB (lub cokolwiek innego), więc myślą tylko w języku, który znają.
gbjbaanb
47

Nigdy nie rób w kodzie tego, co możesz zrobić, aby serwer SQL dobrze dla ciebie robił (nacisk jest mój)

Kluczem do odpowiedzi jest to, że musisz poszukać SQL, który robi coś dobrze, a nie po prostu coś dla Ciebie. SQL jest niezwykle potężnym językiem. W połączeniu z wbudowanymi funkcjami może potencjalnie robić wiele rzeczy. Jednak fakt, że możesz zrobić coś w SQL, nie powinien być usprawiedliwieniem do tego, aby to robić w SQL.

Moim konkretnym kryterium przy podejmowaniu decyzji jest przyjrzenie się ilości danych, które odzyskasz, i liczbie podróży w obie strony: czy możesz zmniejszyć ilość danych, wysyłając zadanie do serwera, bez zwiększania liczby transakcji w obie strony wyłącza się, a następnie zadanie należy do serwera; jeśli ilość danych pozostaje taka sama lub wzrasta bez równoczesnego spadku liczby podróży w obie strony, zadanie należy do Twojego kodu.

Rozważ te przykłady:

  • Przechowujesz datę urodzenia i musisz obliczyć wiek dla grupy użytkowników. Możesz poprosić SQL Server o odejmowanie lub możesz to zrobić w swoim kodzie. Liczba podróży w obie strony pozostaje taka sama, a liczba przesyłanych do Ciebie danych rośnie. Dlatego wygrywa rozwiązanie oparte na kodzie
  • Przechowujesz datę urodzenia i musisz znaleźć użytkowników w wieku od 20 do 30 lat. Możesz załadować wszystkich użytkowników z powrotem do klienta, odjąć, aby znaleźć wiek, a następnie wykonać filtrowanie, ale wysyłać logikę do SQL Server zmniejszyłoby ilość danych bez konieczności dodatkowych podróży w obie strony; dlatego wygrywa rozwiązanie oparte na SQL.
dasblinkenlight
źródło
1
Kiedy gdzieś pracowałem, logika biznesowa stała się amorficzna z SQL, nie mieliśmy problemów z wieloma podróżami w obie strony; po prostu użyliśmy wielu zestawów wyników podczas jednej podróży w obie strony, aby zasada tam się załamała, chociaż duch reguły jest całkiem dobry w dążeniu do złotego środka
Jimmy Hoffa
2
+1 to fantastyczna odpowiedź, ponieważ daje konkretne przykłady wsparcia w obu kierunkach.
Brandon
1
Na twoim drugim przykładzie. co powiesz, jeśli scenariusz jest taki jak poniżej- Użytkownicy i bday są pamięciami podręcznymi i mówią, że rozmiar rekordu mieści się w zakresie 1000-2000. Czy nie jest to szybsze, aby zrobić to w pamięci, nie jest wymagane wywołanie bazy danych, ponieważ dane są buforowane, dzięki czemu unika się operacji „sql” pomiędzy nimi. Przetwarzanie będzie iterowało listę ponad 1000 użytkowników w pamięci i znajdowało miejsce, w którym występuje dopasowanie. Czy to nie będzie szybsze niż robienie tego w db
user4677228
1
@ user4677228 Ale spróbuj zwiększyć skalę :-p. Jeśli Twój kod musi zeskanować wszystkie dane, aby obliczyć wszystkie grupy wiekowe, a pożądany wynik to „ilu użytkowników ma co najmniej 20 i mniej niż 30 lat?”, Pamięci podręczne w ogóle ci nie pomogą. Nadal będziesz przesyłać strumieniowo całą tabelę do swojego klienta, ale serwer bazy danych może zrobić to wszystko w swojej pamięci / pamięciach podręcznych i dać szybką odpowiedź niezależnie od tego, czy klient db łączy się przez gniazda lokalne, czy zdalnie przez sieć, jeśli po prostu chcesz obliczyć wiek w WHEREklauzuli.
binki 27.07.16
21

Krótko mówiąc , poprawne byłoby powiedzenie: „Nigdy nie wykonuj operacji specyficznych dla bazy danych w bazie kodu”, ponieważ są one lepiej adresowane w bazie danych.

Spójrz na przykład ustawionych operacji podstawowych . Jak zapewne wiesz, RDBMS są zbudowane do obsługi typowych operacji przechowywania danych i manipulacji.

Ponadto wybór projektu bazy danych odgrywa ważną rolę . Posiadanie RDBMS (MS SQL, Oracle itp.) Różni się od baz danych NoSQL, takich jak RavenDB.

ElYusubov
źródło
Nigdy nie umieszczanie operacji ustawiania w bazie kodu oznaczałoby absolutnie wszystko, co zrobiono w LINQ do kolekcji (select, sum, where, single) powinno odbywać się w SQL, a nie w Twojej aplikacji, spowodowałoby to dużo logiki biznesowej w twojej bazie danych.
Jimmy Hoffa
4
Rzeczy, które opisujesz, nie są kodem klienta. Jest to warstwa biznesowa, w której możesz mieć własną logikę manipulacji. Jednak wykonanie tej logiki w przypadku rekordów 1M + może cię zaskoczyć.
EL Yusubov
@JimmyHoffa: To nieprawda, czasami generujesz przejściowe informacje, które trzeba przetworzyć z danymi, które już masz w pamięci aplikacji. Linq działa na tym cuda.
Fabricio Araujo
@FabricioAraujo Zdaję sobie sprawę z tego, dlaczego linq jest świetny, ale ta odpowiedź brzmi: Nigdy nie ustawiaj operacji opartych na kodzie aplikacji, jeśli nigdy nie ustawiałeś operacji w kodzie aplikacji, nigdy nie użyłbyś linq, ponieważ taki jest cały cel linq. Mówię o tym, że nigdy nie robienie operacji ustawiania w kodzie aplikacji jest złą zasadą
Jimmy Hoffa
@ JimmyHoffa: Nie, reguła mówi: „nigdy nie rób w aplikacji tego, co RDBMS może dla Ciebie zrobić”. I mówię o przejściowych informacjach - nie informacje przechowywane w bazie danych. Pracowałem na systemach, w których aby wypełnić reguły biznesowe, musiałem wykonać przetwarzanie kodu. Pamiętam regułę biznesową, którą miałem, po intensywnym przetwarzaniu w DB, wykonuję dodatkowe przetwarzanie tych danych, aby wygenerować (bardzo ważny) raport. Mogłem na tym użyć linq (zrobiono to w nieistniejącym już Delphi.Net). Innymi słowy, linq może być używany nawet zgodnie z tą zasadą.
Fabricio Araujo
13

Z reguły twoja baza danych ma więcej informacji do pracy niż aplikacja i może efektywniej wykonywać typowe operacje na danych. Baza danych przechowuje na przykład indeksy, a aplikacja musiałaby indeksować wyniki wyszukiwania na bieżąco. Tak więc wszystko inne jest równe, całkowite obciążenie pracą można zmniejszyć, przesuwając pracę do bazy danych, a nie do aplikacji.

Ale w miarę skalowania produktu zwykle łatwiej jest skalować aplikację niż skalować db. W dużych instalacjach często zdarza się, że liczba serwerów aplikacji przewyższa liczbę serwerów baz danych 10 do 1 lub więcej. Dodanie większej liczby serwerów aplikacji jest często prostą sprawą klonowania istniejącego serwera na nowy sprzęt. Z drugiej strony dodanie nowych serwerów baz danych jest znacznie trudniejsze.

W tym momencie mantra staje się ochroną bazy danych . Okazuje się, że buforując bazę danych memcachedlub umieszczając ją w kolejce aktualizacji w dzienniku po stronie aplikacji, lub pobierając dane raz i obliczając statystyki w aplikacji, możesz radykalnie zmniejszyć obciążenie bazy danych, unikając konieczności uciekania się do jeszcze bardziej skomplikowana i delikatna konfiguracja klastra DB.

tylerl
źródło
1
Pieniądze mogą rozwiązać problemy ze skalowalnością sprzętu, natomiast żadna kwota nie może rozwiązać złożoności oprogramowania.
Tulains Córdova
3
@ user1598390 Rzeczywiście: sprzęt jest tani, programiści są kosztowni . Pieniądze mogą rozwiązać złożoność oprogramowania. Pieniądze wydane na programistów. Ale zauważ, że nie mówimy o czystym kodzie kontra speghetti. Mówimy o wykonywaniu pracy po stronie aplikacji, a po stronie DB. Złożoność oprogramowania jest tylko nieznacznie powiązana, ponieważ obie opcje mogą być zgodne z zasadami dobrego projektowania. Lepszym pytaniem jest: „ który projekt kosztuje więcej? ”.
tylerl
Gdy masz bazę kodu, która jest ogromna i pełna tłuszczu, z czego większość robi rzeczy niezwiązane z biznesem, jedyną rzeczą, którą możesz zrobić, jest matka wszystkich przeprojektowań, które kosztują więcej niż sprzęt i wiążą się ze zbyt dużą niepewnością, poza tym zawsze będziesz wiedział, gdzie znaleźć dobry sprzęt, ale dobrzy programiści to inna historia ... tymczasem twoi konkurenci wykorzystują swój czas na ulepszanie, dostosowywanie się do zmian i zadowolenie klientów.
Tulains Córdova
1
+1 za to, że jako jedyna wspomniała o skalowaniu w odpowiedzi.
Matt
Sprzęt był tani, już nie jest - w centrum danych energia elektryczna i sprzęt stanowią 88% kosztów bieżących (cytowane przez Microsoft), więc większe wydatki na programistów w celu napisania wydajnego kodu są bardzo opłacalne i będą dostępne do momentu uzyskania nieograniczonej liczby tania energia syntezy jądrowej.
gbjbaanb
12

Myślę, że źle byłoby nie wykorzystywać bazy danych do celów, do których jest przeznaczona. Nigdy nie widziałem żadnej bazy danych, w której reguły byłyby egzekwowane poza bazą danych zawierającą dobre dane. Przejrzałem setki baz danych.

Więc rzeczy, które należy zrobić w bazie danych:

  • Kontrola (kontrola tylko aplikacji nie śledzi wszystkich zmian w bazie danych i dlatego jest bezwartościowa).

  • Ograniczenia związane z fałszowaniem danych obejmują wartości domyślne, ograniczenia klucza obcego i reguły, które zawsze muszą być stosowane do wszystkich danych. Wszystkie dane nie zawsze są zmieniane lub wstawiane przez aplikację, istnieją jednorazowe poprawki danych, szczególnie dużych zestawów danych, które nie są praktyczne do wykonania jednego rekordu na raz (zaktualizuj te 100 000 rekordów, które zostały źle oznaczone jako status 1, kiedy powinny być 2 z powodu błędu kodu aplikacji lub zaktualizuj wszystkie rekordy od klienta A do klienta B, ponieważ firma B kupiła firmę A) oraz import danych i inne aplikacje, które mogą dotykać tej samej bazy danych.

  • ŁĄCZY SIĘ i filtrowanie klauzul gdzie (aby zmniejszyć liczbę rekordów wysyłanych przez sieć)

HLGEM
źródło
6

„Przedwczesna optymalizacja jest źródłem wszelkiego zła (w większości zresztą) w programowaniu komputerowym” - Donald Knuth

Baza danych jest dokładnie taka; warstwa danych Twojej aplikacji. Jego zadaniem jest dostarczenie do aplikacji wymaganych danych i przechowywanie podanych danych. Twoja aplikacja to miejsce na kod, który faktycznie działa z danymi; wyświetlanie, sprawdzanie poprawności itp.

Chociaż sentyment w linii tytułowej jest godny podziwu i dokładny do pewnego punktu (drobiazgowe filtrowanie, rzutowanie, grupowanie itp. Powinno się pozostawić w przeważającej liczbie przypadków DB), definicja „studni” może być zamówienie. Istnieje wiele zadań, które SQL Server może wykonywać przy wysokim poziomie wydajności, ale zadania, które można wykazaćże SQL Server działa poprawnie w izolowany, powtarzalny sposób, jest bardzo mało. SQL Management Studio to świetne IDE dla bazy danych (szczególnie biorąc pod uwagę inne opcje, z którymi pracowałem, jak TOAD), ale ma swoje ograniczenia, po pierwsze, że prawie wszystko, czego używasz do tego (lub dowolnego kodu proceduralnego, który wykonujesz w DB poniżej) jest z definicji „efektem ubocznym” (zmiana stanu leżącego poza domeną przestrzeni pamięci twojego procesu). Ponadto kod proceduralny w SQL Server jest dopiero teraz, z najnowszymi IDE i narzędziami, w stanie zmierzyć sposób, w jaki zarządzany kod może korzystać z metryk pokrycia i analizy ścieżki (dzięki czemu możesz wykazać, że to właśnie w przypadku wystąpienia instrukcji X , Y i Z, a test X ma na celu spełnienie warunku i wykonanie tej połowy, podczas gdy Y i Z wykonają „else” . To z kolei zakłada, że ​​masz test, który może ustawić bazę danych z określonym stanem początkowym, wykonać kod proceduralny bazy danych przez jakąś akcję i zapewnić oczekiwane wyniki.

Wszystko to jest o wiele trudniejsze i wymaga więcej niż rozwiązanie zapewniane przez większość warstw dostępu do danych; zakładamy, że warstwa danych (i, w tym przypadku, DAL) wiedzą, jak wykonać swoją pracę, jeśli otrzymają prawidłowe dane wejściowe, a następnie przetestują, czy kod zapewnia prawidłowe dane wejściowe. Trzymając kod proceduralny, taki jak SP i wyzwalacze poza DB, i zamiast tego robiąc takie rzeczy w kodzie aplikacji, wspomniany kod aplikacji jest znacznie łatwiejszy do wykonania.

KeithS
źródło
Czekaj, czekaj co? Jak przeszedłeś od testów poprawności do testów, które mogą udowodnić, że istnieją błędy, ale nigdy nie mogą udowodnić, że kod jest poprawny?
Mason Wheeler
2
procedura przechowywana nie jest kodem proceduralnym. SP to wstępnie obliczone zapytanie SQL przechowywane i uruchamiane w bazie danych. To nie jest kod aplikacji.
gbjbaanb
1
Jeśli dodatek SP jest ograniczony do zapytania SQL, masz rację. Jeśli jest to T-SQL lub PL / SQL, w tym przerwy warunkowe, pętle, kursory i / lub inna logika niezwiązana z zapytaniami, jesteś w błędzie. Wiele SP, funkcji i wyzwalaczy w bazach danych w całej cyberprzestrzeni ma te dodatkowe elementy.
KeithS,
5

Jedną z rzeczy, o których ludzie nie zdają sobie sprawy, jest to, że wykonywanie całego przetwarzania na serwerze SQL niekoniecznie jest dobre, niezależnie od wpływu na jakość kodu.

Na przykład, jeśli chcesz pobrać niektóre dane, a następnie obliczyć coś z danych, a następnie zapisać te dane w bazie danych. Istnieją dwie możliwości:

  • Chwyć dane do aplikacji, wykonaj obliczenia w aplikacji, a następnie odeślij dane z powrotem do bazy danych
  • Stwórz procedurę przechowywaną lub podobną, aby pobrać dane, obliczyć je, a następnie zapisać wszystko od jednego wywołania do serwera SQL.

Możesz pomyśleć, że drugie rozwiązanie jest zawsze najszybsze, ale to zdecydowanie nie jest prawda. Ignoruję, nawet jeśli SQL nie pasuje do problemu (tj. Regex i manipulacja ciągiem). Udawajmy, że masz SQL CLR lub coś podobnego, aby mieć nawet potężny język w bazie danych. Jeśli wykonanie podróży w obie strony zajmuje 1 sekundę i pobranie danych oraz 1 sekunda na ich przechowanie, a następnie 10 sekund na wykonanie obliczeń w poprzek. Robisz to źle, jeśli robisz to wszystko w bazie danych.

Jasne, golisz się 2 sekundy. Czy jednak zmarnowałeś 100% (przynajmniej) jednego rdzenia procesora na serwerze bazy danych przez 10 sekund, czy raczej zmarnowałeś ten czas na swoim serwerze internetowym?

Serwery WWW są łatwe do skalowania, bazy danych z drugiej strony są wyjątkowo drogie, szczególnie bazy danych SQL. Przez większość czasu serwery sieciowe są również „bezstanowe” i można je dodawać i usuwać według własnego uznania, bez dodatkowej konfiguracji niczego poza modułem równoważenia obciążenia.

Pomyśl więc nie tylko o stracie 2 sekund operacji, ale także o skalowalności. Po co marnować drogie zasoby, takie jak zasoby serwera bazy danych, kiedy można korzystać ze znacznie tańszych zasobów serwera WWW przy stosunkowo niewielkim wpływie na wydajność

Earlz
źródło
1
zapominasz także o podróżach sieciowych - nie możesz skalować w poziomie, dodając serwery bez obniżenia wydajności. Tak więc zmniejszenie obciążenia danych przez dodanie klauzuli where jest oczywiste - ale inne operacje sql niekoniecznie zmniejszają wydajność. Twój punkt jest jednak ogólnie poprawny, ale nie do tego stopnia, że ​​traktujesz DB jako głupi magazyn danych. Najbardziej skalowalna aplikacja, nad którą kiedykolwiek pracowałem, korzystała z procedur przechowywanych dla każdego połączenia danych (z wyjątkiem 2 złożonych zapytań). Trzecie rozwiązanie jest najlepsze - „przechowywany proc, aby pobrać tylko niezbędne dane”, nie jestem pewien, czy miałeś na myśli to „obliczenie” czy nie.
gbjbaanb
4

Lubię na to patrzeć, ponieważ SQL powinien zajmować się tylko danymi. Reguły biznesowe, które decydują o tym, jak może wyglądać zapytanie, mogą wystąpić w kodzie. Ponowne wyrażenie lub sprawdzenie poprawności informacji powinno odbywać się w kodzie. Należy pozostawić SQL, aby po prostu dołączyć do tabeli, zapytać o dane, wstawić czyste dane itp.

To, co dostaje się do SQL, powinno być czystymi danymi, a SQL nie powinien tak naprawdę wiedzieć nic więcej niż musi go przechowywać, aktualizować, usuwać lub odzyskiwać. Zauważyłem, że zbyt wielu programistów chce rzucać swoją logiką biznesową i kodowaniem w SQL, ponieważ traktują dane jako swoją działalność. Oddziel swoją logikę od danych, a zobaczysz, że kod staje się czystszy i łatwiejszy w zarządzaniu.

Tylko moje 0,02 $.

Stanley Glass Jr
źródło
Dlaczego miałbyś uruchamiać wyrażenie regularne lub sprawdzanie poprawności danych, które są już w bazie danych? Ograniczenia powinny uniemożliwić dostęp do złych danych, a użycie wyrażenia regularnego prawdopodobnie oznacza, że ​​potrzebujesz bardziej przydatnych kolumn.
Brendan Long,
Nie mówiłem, że użyję wyrażenia regularnego lub sprawdzania poprawności danych pochodzących z bazy danych. Chyba powinienem był wyjaśnić, że chodzi o dane idące do bazy danych. Chodzi mi o to, że dane powinny zostać wyczyszczone i sprawdzone, zanim dotrą do DAL.
Stanley Glass Jr
3

Ogólnie zgadzam się, że kod powinien kontrolować logikę biznesową, a DB powinien być hashem wolnym od logiki. Ale oto kilka kontrapunktów:

Kod główny może wymuszać ograniczenia podstawowe, obce i wymagane (nie zerowe). Ograniczenia są logiką biznesową. Czy należy je pominąć w bazie danych, ponieważ duplikują kod?

Czy inne podmioty poza twoją kontrolą dotykają bazy danych? Jeśli tak, dobrze jest mieć ograniczenia narzucone blisko danych. Dostęp może być ograniczony do usługi sieciowej, która implementuje logikę, ale zakłada to, że byłeś tam „pierwszy” i masz moc egzekwowania korzystania z usługi na innych stronach.

Czy Twój ORM wykonuje osobne operacje wstawiania / aktualizacji dla każdego obiektu? Jeśli tak, wystąpią poważne problemy z wydajnością podczas przetwarzania wsadowego dużych zestawów danych. Ustaw operacje to droga. ORM będzie miał problem z dokładnym modelowaniem wszystkich możliwych połączonych zestawów, na których można wykonywać operacje.

Czy uważasz, że „warstwa” jest fizycznym podziałem na serwery, czy logicznym? Uruchamianie logiki na dowolnym serwerze teoretycznie może nadal wchodzić w jej warstwę logiczną. Możesz zorganizować podział, kompilując go do różnych bibliotek DLL, a nie tylko dzieląc serwery. Może to radykalnie wydłużyć czas reakcji (ale poświęcenie wydajności) przy jednoczesnym zachowaniu separacji obaw. Podzieloną bibliotekę DLL można później przenieść na inne serwery bez nowej wersji w celu zwiększenia przepustowości (kosztem czasu odpowiedzi).

mike30
źródło
dlaczego głosowanie negatywne?
mike30
5
Nie przegłosowałem, ale jakikolwiek specjalista od bazy danych powie ci, że uznanie bazy danych za logiczny hash jest bardzo kiepskim pomysłem. Powoduje to problemy z integralnością danych, problemy z wydajnością lub oba.
HLGEM
1
@HLGEM. Odpowiedź opisuje powody, dla których logikę należy przechowywać w bazie danych lub na serwerze DB. Nadal tego nie wyjaśnia.
mike30
Być może nie dotarli do kontrapunktu tak jak ja, dlatego nie głosowałem za nimi.
HLGEM
3

Ten idiom dotyczy raczej utrzymywania reguł biznesowych, danych i relacji (danych, struktury i relacji). Nie jest to kompleksowe rozwiązanie dla każdego problemu, ale pomaga unikać rzeczy takich jak ręcznie utrzymywane liczniki rekordów, ręcznie utrzymywana integralność relacji itp., jeśli te rzeczy są dostępne na poziomie bazy danych. Więc jeśli ktoś inny przyjdzie i rozszerzy programy lub napisze inny program, który współdziała z bazą danych, nie będzie musiał wymyślić, jak zachować integralność bazy danych z poprzedniego kodu. Przypadek ręcznie utrzymywanego licznika rekordów jest szczególnie istotny, gdy ktoś inny chce stworzyć nowy program do interakcji z tą samą bazą danych. Nawet jeśli nowo utworzony program ma dokładnie odpowiedni kod dla licznika, oryginalny program i nowy uruchomiony mniej więcej w tym samym czasie mogą go uszkodzić. Istnieje nawet kod, który pobiera rekordy i sprawdza warunki przed zapisaniem nowego lub zaktualizowanego rekordu (w kodzie lub jako osobne zapytania), jeśli to możliwe, często można to osiągnąć bezpośrednio w instrukcji insert lub update. Ponownie może dojść do uszkodzenia danych. Silnik bazy danych gwarantuje atomowość; aktualizacja lub wstaw zapytanie z warunkami ma wpływ tylko na rekordy spełniające warunki i żadne zapytanie zewnętrzne nie może zmienić danych w połowie naszej aktualizacji. Istnieje wiele innych okoliczności, w których kod jest używany, gdy silnik bazy danych lepiej służy. Chodzi o integralność danych, a nie o wydajność. jest nawet dostępny kod, który pobiera rekordy i sprawdza warunki przed zapisaniem nowego lub zaktualizowanego rekordu (w kodzie lub jako osobne zapytania), jeśli to możliwe, często można to osiągnąć bezpośrednio w instrukcji insert lub update. Ponownie może dojść do uszkodzenia danych. Silnik bazy danych gwarantuje atomowość; aktualizacja lub wstaw zapytanie z warunkami ma wpływ tylko na rekordy spełniające warunki i żadne zapytanie zewnętrzne nie może zmienić danych w połowie naszej aktualizacji. Jest wiele innych okoliczności, w których kod jest używany, gdy silnik bazy danych lepiej służy. Chodzi o integralność danych, a nie o wydajność. jest nawet dostępny kod, który pobiera rekordy i sprawdza warunki przed zapisaniem nowego lub zaktualizowanego rekordu (w kodzie lub jako osobne zapytania), jeśli to możliwe, często można to osiągnąć bezpośrednio w instrukcji insert lub update. Ponownie może dojść do uszkodzenia danych. Silnik bazy danych gwarantuje atomowość; aktualizacja lub wstaw zapytanie z warunkami ma wpływ tylko na rekordy spełniające warunki i żadne zapytanie zewnętrzne nie może zmienić danych w połowie naszej aktualizacji. Jest wiele innych okoliczności, w których kod jest używany, gdy silnik bazy danych lepiej służy. Chodzi o integralność danych, a nie o wydajność. Silnik bazy danych gwarantuje atomowość; aktualizacja lub wstaw zapytanie z warunkami ma wpływ tylko na rekordy spełniające warunki i żadne zapytanie zewnętrzne nie może zmienić danych w połowie naszej aktualizacji. Istnieje wiele innych okoliczności, w których kod jest używany, gdy silnik bazy danych lepiej służy. Chodzi o integralność danych, a nie o wydajność. Silnik bazy danych gwarantuje atomowość; aktualizacja lub wstaw zapytanie z warunkami ma wpływ tylko na rekordy spełniające warunki i żadne zapytanie zewnętrzne nie może zmienić danych w połowie naszej aktualizacji. Istnieje wiele innych okoliczności, w których kod jest używany, gdy silnik bazy danych lepiej służy. Chodzi o integralność danych, a nie o wydajność.

Więc to właściwie dobry idiom lub zasada. Żadna wydajność nie pomoże w systemie z uszkodzonymi danymi.

Chris
źródło
0

Jak wspomniano wcześniej, celem jest wysyłanie i odbieranie jak najmniej danych z bazy danych, ponieważ podróże w obie strony są bardzo kosztowne pod względem czasowym. Ciągłe wysyłanie instrukcji SQL to strata czasu, szczególnie w przypadku bardziej złożonych zapytań.

Korzystanie z procedur przechowywanych w bazie danych pozwala programistom na interakcję z bazą danych, podobnie jak interfejs API, bez martwienia się o skomplikowany schemat z tyłu. Zmniejsza to również dane wysyłane do serwera, ponieważ wysyłane są tylko nazwa i kilka parametrów. W tym scenariuszu większość logiki biznesowej może nadal znajdować się w kodzie, ale nie w formie SQL. Kod zasadniczo przygotowuje to, co ma zostać wysłane lub wysłane z bazy danych.

Laurent Goderre
źródło
0

Jest kilka rzeczy do zapamiętania:

  • Relacyjna baza danych powinna zapewniać integralność referencyjną za pomocą kluczy obcych
  • Skalowanie jednej bazy danych może być trudne i kosztowne. Skalowanie serwera WWW jest o wiele łatwiejsze po prostu poprzez dodanie większej liczby serwerów WWW. Baw się dobrze, próbując dodać więcej mocy serwera SQL.
  • Dzięki C # i LINQ możesz wykonywać swoje „dołączenia” i inne czynności za pomocą kodu, dzięki czemu w wielu przypadkach możesz uzyskać to, co najlepsze z obu światów.
Joe Phillips
źródło
0

„Przedwczesna optymalizacja jest źródłem wszelkiego zła” - Donald Knuth

Użyj narzędzia najbardziej odpowiedniego dla danego zadania. W celu zapewnienia integralności danych często jest to baza danych. W przypadku zaawansowanych reguł biznesowych jest to system oparty na regułach, taki jak JBoss Drools. W przypadku wizualizacji danych byłoby to ramy sprawozdawczości. itp.

Jeśli masz jakiekolwiek problemy z wydajnością, powinieneś następnie sprawdzić, czy jakieś dane mogą być buforowane lub czy implementacja w bazie danych byłaby szybsza. Ogólnie rzecz biorąc, koszt zakupu dodatkowych serwerów lub dodatkowej mocy w chmurze będzie znacznie niższy niż dodatkowy koszt konserwacji i wpływ dodatkowych błędów.

parasietje
źródło