Kiedy lepiej jest odciążyć pracę do RDBMS niż robić to w kodzie?

12

Dobra, poradzę sobie z tym: jestem lepszym programistą niż w bazach danych i zastanawiam się, gdzie myśli się o „najlepszych praktykach” na temat wykonywania „prostych” obliczeń w zapytaniu SQL vs. kod, taki jak ten przykład MySQL (nie napisałem go, muszę go tylko zachować!) - Zwraca nazwę użytkownika, a użytkownicy starzeją się od ostatniego zdarzenia.

SELECT u.username as user, 
       IF ((DAY(max(e.date)) - DAY(u.DOB)) < 0 ,   
       TRUNCATE(((((YEAR(max(e.date))*12)+MONTH(max(e.date)))
       -((YEAR(u.DOB)*12)+MONTH(u.DOB)))-1)/12, 0),  
       TRUNCATE((((YEAR(max(e.date))*12)+MONTH(max(e.date))) -            
       ((YEAR(u.DOB)*12)+MONTH(u.DOB)))/12, 0)) AS age   
FROM users as u
JOIN events as e ON u.id = e.uid
...

W porównaniu do „ciężkiego” podnoszenia kodu:

Pytanie:

SELECT u.username, u.DOB as dob, e.event_date as edate
FROM users as u
JOIN events as e ON u.id = e.uid

kod:

function ageAsOfDate($birth, $aod)
{    //expects dates in mysql Y-m-d format...
     list($by,$bm,$bd) = explode('-',$birth);
     list($ay,$am,$ad) = explode('-',$aod);

     //Insert Calculations here 
     ...
     return $Dy; //Difference in years
}

echo "Hey! ". $row['user'] ." was ". ageAsOfDate($row['dob'], $row['edate']) . " when we last saw him."; 

Jestem pewien, że w tak prostym przypadku nie miałoby to większego znaczenia (oprócz przerażającego poczucia przerażenia, gdy muszę wprowadzać zmiany w zapytaniach takich jak ten pierwszy), ale myślę, że to wyjaśnia, co ja ” szukam.

Dzięki!

GeminiDomino
źródło
1
To dobre pytanie - natknąłem się na ten sam problem.
Michael K,
Oto dobry przykład, kiedy tego nie robić: calendar.sql (Tak, to moja potworność, tak, to był zły pomysł i nie, nie jest powolny.)
greyfade
Rzucacie bogów ... Założę się, że MD5 to „CthulhuFhtagn”
GeminiDomino

Odpowiedzi:

13

Chcesz wykonywać wszystkie operacje na bazie danych w bazie danych ze względu na wydajność. Więc funkcje agregujące, funkcje sortujące, złączenia itp.

To obliczenie wieku zrobię w kodzie. Jedynym powodem, dla którego mógłbym zrobić coś takiego w zapytaniu do bazy danych jest to, że wymagałoby to wielu kolumn, których w innym przypadku nie wybrałbym, które mogłyby w rzeczywistości stanowić wystarczającą ilość danych, aby znacząco spowolnić moje zapytanie. Wybór kilku wartości całkowitych nie spowoduje znaczącej różnicy wydajności. I nawet jeśli spowoduje to umiarkowaną różnicę wydajności, będę skłonny do zachowania tej logiki w kodzie aplikacji.

Jeremy
źródło
Zgadzam się. Kod, który manipuluje wartościami do celów wyświetlania, powinien znajdować się w kodzie aplikacji.
TehShrike
4

Każda sprawa jest inna

Czy logika ...

  • potrzebne innym klientom? OSUSZANIE: w bazie danych
  • używane do dalszego przetwarzania? np. sortuj według wieku malejącego: w bazie danych
  • wymaga ustawień regionalnych? dd / mm / rrrr lub mm / dd / rrrr: w kliencie
  • często używane? Po co ciągle go obliczać: użyj obliczonej i utrwalonej kolumny w bazie danych

W takim przypadku mogę użyć obliczonej i utrwalonej kolumny w bazie danych

Mogło być gorzej: możesz mieć to w bazie danych:

"Hey! ". u.username." was ". <datecalc>. " when we last saw him."
gbn
źródło
3

Zasadniczo powinieneś spojrzeć na dwie rzeczy: użycie procesora i ruch sieciowy. Nie powinieneś generować ogromnych odpowiedzi, przesyłać je przez sieć, a następnie podsumowywać w interfejsie, ponieważ baza danych może to zrobić znacznie lepiej.

W przypadku manipulacji danymi jest to zamiana. Jeśli baza danych wydaje porównywalną liczbę cykli procesora do kodu frontonu, robiąc to samo - biorąc pod uwagę, że ilość przesłanych danych jest w przybliżeniu równoważna), nie ma znaczenia, gdzie. Następnie zrób to tam, gdzie masz największą wiedzę programistyczną. Często możesz uzyskać BARDZO długą drogę dzięki starannemu wyborowi, co może być bardzo przydatne.


źródło
1

Wspomniałeś jeden: obszar specjalizacji. Być może struktura bazy danych nie jest zbyt intensywna, więc decydujesz się przenieść część rozwoju logiki na członka zespołu, który jest bardziej zorientowany na bazę danych. Może nie być idealny, ale jeśli masz ochotę na czas ...

Sprzęt bazy danych ma znacznie więcej zasobów niż inne serwery i nie można tego zmienić. Może to nie dotyczyć tej konkretnej sytuacji, ale może wymagać rozważenia.

Istnieją inne aplikacje, które mogą wymagać logiki poza twoim kodem. Niektóre narzędzia do pisania raportów mogą nie być w stanie korzystać z usługi internetowej lub interfejsu API. Możesz powielić logikę lub jeśli uważasz, że wymagania mogą się różnić.

JeffO
źródło
„Sprzęt bazy danych ma znacznie więcej zasobów niż inne serwery i nie można tego zmienić”. - co? Skąd te dwie wypowiedzi?
Peter Boughton
Myślę, że Jeff może mówić o samodzielnych serwerach baz danych. Prawdopodobnie powinienem był sprecyzować, że pracuję głównie w konfiguracjach LA [MP] P.
GeminiDomino,
1
Konfiguracja LAMP nie jest powodem, aby nie mieć autonomicznego serwera bazy danych, ani też autonomiczny serwer bazy danych nie jest gwarancją większej ilości zasobów ani niemożności zmiany tego.
Peter Boughton
Hmm. Nie jestem pewien.
GeminiDomino
@Peter Boughton, DB i aplikacja na tym samym serwerze mają o rząd wielkości mniej czasu na podłączenie interfejsu i wielkości większe IO w całym, istnieją prawdziwe powody, aby je zlokalizować razem.
Jé Queue
0

Zawsze mylę się, wkładając tyle samo przetwarzania w DB. Twoja powyższa składnia może być również napisana z funkcjami DB, które byłyby IMO bardzo czystym rozwiązaniem.

Jé Queue
źródło