Przetwarzanie danych po stronie bazy, czy w aplikacji?

0

Hej,

zacząłem się zastanawiać nad pewnym tematem. Otóż gdzie lepiej przetwarzać dane pobierane z bazy? Zauważyłem u siebie tendencję do wyciągania danych z bazy jakimś prostym zapytaniem, filtrując raczej po jednym, czy dwóch kryteriach, a następnie filtruję, zliczam, czy cokolwiek innego np. wrzucając listę w stream (Java) i operując na danych w aplikacji. Zacząłem się jednak zastanawiać co jest dobrą praktyką w takim przypadku. Czy lepiej napisać natywnie jakieś bardziej skomplikowane zapytanie do bazy i starać się jak najdokładniej przefiltrować dane po stronie DB do postaci najbliższej takiej, jaka mi jest potrzebna, czy własnie lepiej zrzucać tę odpowiedzialność na kod aplikacji. Jak to wygląda u was? Co jest lepszą praktyką?

1

Tutaj chyba nie ma jednoznacznej odpowiedz, jeżeli dane nie są wrażliwe i zabierają sporo CPU to lepiej przetworzyć je po stronie użytkownika(mam na myśli mało danych dużo obliczeń)
W większości przypadków jednak mamy do czynienia z prostymi zapytaniami i w takiej sytuacji lepiej wysłać jak najmniej danych, lepiej wykonać filtrowania po stronie serwera.

Jeżeli chodzi czy przetwarzać dane po stornie java czy DB to zdecydowanie DB. Dobrze zbudowane zapytanie jest dużo szybsze od java.

1

Dużo zależy, jakie to przetwarzanie i jaka struktura bazy (a raczej, to struktura bazy powinna być planowana jakoś  pod to jak się będzie tego używało potem).

Generalnie, najlepiej sprawdzić oba rozwiązania jakimiś testami wydajnościowym i zobaczyć.

3

Bierz pod uwage że dziś możesz mieć 10 rekordów a za kilka miesiący 100k, jeśli chcesz fltrować samemu po tych 100k to zaraz ci pamięci zabraknie :)

0
danek napisał(a):

Dużo zależy, jakie to przetwarzanie i jaka struktura bazy (a raczej, to struktura bazy powinna być planowana jakoś  pod to jak się będzie tego używało potem).

Generalnie, najlepiej sprawdzić oba rozwiązania jakimiś testami wydajnościowym i zobaczyć.

W praktyce chodzi mi o operacje typu wyciąganie z bazy jakiejśtam ilości obiektów, które powiedzmy mają z 10 pól, przy zapytaniu do bazy wybieram dość ogólnie parę warunków, natomiast później wykonuje jeszcze kilka filtrów na streamie zrobionym z listy wyników. Szczerze? Robię to z tego powodu, że zapomniałem jak kleić jakieś sensowniejsze zapytania niż SELECT FROM cośtam WHERE (NOT) coś = coś2 AND coś3 > coś4. Właśnie sobie serwuję przypomnienie SQLa i naszło mnie na takie przypomnienia.

2

Po nałożeniu odpowiednich indexów i struktury bazy, zapytanie będzie w przeważającej większości wydajniejsze. Możesz sobie sam napisać benchmark, zwykły pomiar szybkości przetwarzania + wykorzystania pamięci.

3

Pytanie jest inne - zastanów się, jakie są szanse, że Ty - jako samodzielny programista - będziesz w stanie zaprojektować system filtrowania/szukania tak samo wydajny (albo może nawet lepszy), niż silnik SQL, który jest na rynku przez kilkanaście/kilkadziesiąt lat, testowany na milionach serwerów, dedykowany do przechowywania i wyszukiwania danych oraz tworzony przez ogromną grupę osób zajmujących się tym zawodowo ;)

1

I jeszcze dodatkowa kwestia, czy chcesz trzymać logikę biznesową w SQLach ;) Przy prostych filtrach to jeszcze da radę, jakieś bardziej skomplikowane rzeczy to już zaczyna się problem np z testowaniem

2

Wczytywanie połowy bazy do pamięci, a następnie filtrowanie i projekcja po stronie aplikacji jest złą praktyką i praktycznie zawsze złym pomysłem.

danek napisał(a):

I jeszcze dodatkowa kwestia, czy chcesz trzymać logikę biznesową w SQLach ;)

Nie musi trzymać logiki biznesowej w SQL. Istnieją narzędzia, które pozwalają wygenerować zapytanie SQL i zwrócą kolekcję odfiltrowanych i zmapowanych obiektów.

2

Jeśli chodzi o filtrowanie to jak najbardziej lepiej po stronie bazy. Ale ABSOLUTNIE nie wrzucać tam logiki i robić jakichś procedur, bo ugryzie cię to w dupę i to bardzo mocno. Testowalność takich rzeczy jest zerowa, plus vendor lock over 9000.

0
Shalom napisał(a):

Jeśli chodzi o filtrowanie to jak najbardziej lepiej po stronie bazy. Ale ABSOLUTNIE nie wrzucać tam logiki i robić jakichś procedur, bo ugryzie cię to w dupę i to bardzo mocno. Testowalność takich rzeczy jest zerowa, plus vendor lock over 9000.

Czyli - biorąc po lupę bardzo prosty przykład - lepiej po stronie bazy wyszukać wszystkie wypłaty danego pracownika, ale np. zsumować je wszystkie lepiej po stronie aplikacji? Bo w sumie takie sumowanie to już jest jakaś (biedna, bo biedna ale zawsze jakaś) logika. Dobrze rozumiem?

1

Wiem, że przykład banalny, ale ja bym mimo wszystko już sumował po stronie aplikacji, bo za chwile dojdą Ci jakieś przypadki, wyjątki itp. Dodatkowo szybciej (w pamięci) przetestujesz taką logikę jeśli jest po stronie aplikacji.

3

Wszystko, co możesz, robisz po stronie SQLa. Dlatego że jest wydajniej, mniej przepychasz do klienta, serwera aplikacyjnego. I to baza sobie lepiej poradzi z tym niż jakiś nawet wypasiony algorytm po stronie klienta, bo np. nie ma statystyki, indeksy itp.

4
Shalom napisał(a):

Jeśli chodzi o filtrowanie to jak najbardziej lepiej po stronie bazy. Ale ABSOLUTNIE nie wrzucać tam logiki i robić jakichś procedur, bo ugryzie cię to w dupę i to bardzo mocno. Testowalność takich rzeczy jest zerowa, plus vendor lock over 9000.

W bazach robie już kilkanaście lat i przez ten czas nie widziałem aplikacji "vendor free" ponad sklep internetowy. I to tak obsługiwał tylko PostgreSQL i MySQL. Jak chcesz zrobić wydajną aplikacje, która działa wydajnie przy milionach rekordów to raczej musisz zacząć wykorzystywać funkcjonaliści zależne od konkretnego dostawcy. Spotkałem się z próbami zrobienia taki aplikacji które z czasem spełzły na niczym z tego względu, że wspieranie kilku vendorów jest strasznie kosztowne — programiści muszą być świadomi i wyedukowani, że wszystko musi działać na różnych bazach, kilka razy więcej testów (na każdego vendora osobno ) itp itd. Tak czy inaczej, kończy się na tym, że wygrywa wiodący dostawca, który dostarcza najlepsze rozwiązanie dla danego typu danych i logiki.

0

Dobierasz implementację pod konkretny problem.

Baza poradzi sobie z dużymi zbiorami danych (łączenia, filtrowanie, agregacje itd.), ale ciężko będzie w czystym SQLu mieć logikę, która będzie przechodzić po jakichś złożonych strukturach (np. grafach cyklicznych) i coś tam wyliczać.

W drugą stronę, pamięć będzie ograniczać max. zbiór danych jakich jesteś w miarę bezboleśnie przetworzyć po stronie aplikacji (rozwiązania typu spark, zakładają, że umiesz podzielić duży zbiór danych na małe, mieszczące się w pamięci i operować na małych, ale jaki sens jest implementowanie własnego partycjonowania danych, nested loopa czy hash joina w oparciu sparka, jeśli baza sobie z tym radzi bez problemu?)

6
Belka napisał(a):
Shalom napisał(a):

Jeśli chodzi o filtrowanie to jak najbardziej lepiej po stronie bazy. Ale ABSOLUTNIE nie wrzucać tam logiki i robić jakichś procedur, bo ugryzie cię to w dupę i to bardzo mocno. Testowalność takich rzeczy jest zerowa, plus vendor lock over 9000.

Czyli - biorąc po lupę bardzo prosty przykład - lepiej po stronie bazy wyszukać wszystkie wypłaty danego pracownika, ale np. zsumować je wszystkie lepiej po stronie aplikacji? Bo w sumie takie sumowanie to już jest jakaś (biedna, bo biedna ale zawsze jakaś) logika. Dobrze rozumiem?

To nie jest logika tylko CRUDowe zapytanie


SELECT sum(payment) FROM payment WHERE payment.user_id = 1985; 

Logika może być wyliczanie np. opłaty za czas na siłce w zależności od sposobu zapłaty (jesli karnet to 0, jeśli multisport to 0 za 1 h a później 10h za każdą)

6

Póki coś się da zapisać jednym query to jest ok. Ale jak zaczynasz klepać procedurę w bazie to zalecam rozpędzić się i walnąć głową w ścianę. Testowalność jest zerowa, wsparcie IDE zerowe, debugowalność zerowa. Może pewne rzeczy nawet byłby szybsze, tylko to trochę jak argument żeby klepać jakiś algorytm w asemblerze. Może będzie milisekundę szybciej, ale niestety write-only i za jakiś czas ten fragment będzie obłożony // here be dragons, magic, do not touch

0

Obecnie odchodzi się od procedur po stronie bazy bo zmieniła się typowa architektura z monolitów na mniejsze serwisy. Kolejna przyczyna to łatwiejsza możliwość pozyskania programisty javy niż baz danych - po co płacić dwóm osobom jak można jednej :) . W większości przypadków wydajność i tak nie ma znaczenia do momentu, aż ktoś mocno nie skopie zaprojektowanej funkcjonalności, albo dotrzemy do limitu maszyny, która pierwotnie została kupiona z dużym zapasem mocy.

4

@Shalom, to się da zrobić. Np. w Visual Studio da się debugować SQL krok po kroku, pisać "unit testy" do procedur składowanych (są takie szablony projektów) i nawet się da odpalać to w continous integration. Tylko nie wiem po co. :P
Kiedyś nawet byłem w projekcie, w którym takie rzeczy stosowano, w życiu tak szybko nie uciekałem.

3

Mówienie, że coś jest złą praktyką (procedury w bazie), bo się nie zna lub słabo zna języki i narzędzia, które to umożliwiają, oraz uznaje je za mało modne i mało "ninja" w CV, to jest w sumie świetna odpowiedź dla gościa, który dofiltrowuje sobie dane w Javie (czy czym tam), bo nie zdążył jeszcze douczyć się, jak zapisać warunki w SQL. ;)
Ja bym poszedł dalej - programowanie jest złą praktyką, jak się nie umie programować. Co tam mało debugowalne, testowalne, utrzymywalne. Nie bójmy się powiedzieć, po prostu męczące, upierdliwe i kiedyś się znudzi. ;P

2

@xy ano masz racje, to na pewno dlatego. I to zupełny przypadek że odchodzi się od wielkich baz danych na rzecz polyglot persistence i że już od dawna odchodzi się od klepania logiki w bazie ;) Na przykład ci ludzie: ewidentnie nie mają pojęcia co robią. Brakuje im tam ciebie! xD

0

Obrabianie danych po stronie bazy danych ZAWSZE będzie zdecydowanie bardziej wydajne. Chyba, że mówimy o jakiś małych programikach z małą ilością danych, to może być różnie.

0
Juhas napisał(a):

Obrabianie danych po stronie bazy danych ZAWSZE będzie zdecydowanie bardziej wydajne. Chyba, że mówimy o jakiś małych programikach z małą ilością danych, to może być różnie.

Oczywiście bzdura.

Bywa wydajne jak akurat podpasują indeksy i jest to typowe filtrowanie, agregowanie - pasujące do danych i danej bazy.
SQL / Bazy nie sa jezykami programowania ogólnego przeznaczenia i czasami, nawet w prostych przypoadkach sa tragicznie powolne.

Swego czasu przypadkiem udało mi się ośmieszyć kilka razu różne procedury oraclowe (PLSQL) , kiedy napisałem - zupełnie na wariata prosty naiwny algorytm w javie.
Sam się zdziwiłem. (wszelkiego rodzaju pętle LOOP. END LOOP zwykle nie wychodzą na zdrowie enginom bazodanowym).

Ogólnie jak komuś zależy na szybkości to po prostu najlepiej w ogóle bazy danych (głównie SQL) omijać szerokim łukiem to nie do szybkości służy. (Mimo, że może ktoś kiedyś zrobi wolfensteina 3d w SQLu...).
Większość algorytmów, dzięki którym bazy są szybkie jest też dostępna w popularnych jezykach programowania. Można też ich użyć w C#/Javie itp. (przykłady: https://github.com/npgall/cqengine , https://rosettacode.org/wiki/Hash_join)

1

Nawet zakładając, że baza danych ma wydajny model obliczeniowy do wykonania obliczeń, to trzeba uważać, aby jej nie zapchać. Zwykle dodanie CPU/RAM do bazy SQL jest trudne, a dodanie instancji aplikacji trochę prostsze. Jak kod aplikacji wywróci się z OutOfMemoryError, to skutki są mniej dotkliwe niż crash serwera bazy danych.

0

Raczej są małe szanse, że baza się totalnie wychrzani. Jak będzie przeładowana to raczej będzie zamulać, plus może ubijać poszczególne zapytania/wywalać timeouty, ale samego silnika raczej to nie uwali.

0

Mi to trochę przypomina sytuację przegięcia "nie wymyślania koła od nowa". System baz danych są na tyle wygodne , że sporo programistów przyzwyczaiła się do nich i nie potrafiłoby zaimplementować prostych algorytmów złączeń, które wykorzystują bazy, już nawet pomijając efektywność odczytów, zapisów i reprezentacji fizycznej danych.

Jakby systemy relacyjnych baz danych nie miały problemów ze skalowalnością, to nie byłoby w ostatnich latach takiego natłoku systemów przetwarzania dla dużych zbiorów danych, zapewniających dostępność na poziomie paru 9, rezygnujących z pewnych założeń co do spójności by być w stanie operować przy danych założeniach czy będących w stanie operować będąc rozproszonym w różnych centrach danych na całym świecie. To tylko kolejne aplikacje i jak się okazuje nie zawsze istnieje gotowe rozwiązanie, które pasuje idealnie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1