Inżynierowie baz danych już dawno umarli ...

"… albo zostali inżynierami danych (data engineers) i na szczęście nie tworzą już aplikacji."

Ostatnio usłyszałem takie stwierdzenie w jednym z podcastów o tworzeniu oprogramowania. I generalnie wydawało mi się, że rzucone zostało nieironicznie i z pewną dozą satysfakcji z przedstawionego stanu rzeczy. I muszę przyznać, że zmroziło mnie to niczym skok do zimnych wód Bałtyku.

START TRANSACTION

Niestety ciągle powszechne jest podejście wśród niemłodych stażem programistów (w sensie takich z doświadczeniem > 15 lat), że baza danych to worek, do którego się coś wrzuca i jak trzeba, to się coś z niego "zaczerpuje dłonią". Podejście do bazy danych, z którego wynika tytułowe stwierdzenie jest przyczyną, dla której powstaje 9/10 niewydajnych, źle napisanych systemów. Myślący w ten sposób programiści, czy jeszcze gorzej architekci / projektanci systemów, którzy naczytają się dużo książek o żabkach, tudzież magicznych architekturach traktują obszar bazy danych jak jakiś opuszczony cmentarz, do którego tylko wariat by zaglądał.

SELECT * FROM EVENTS (-- 123456789 rows in set (1588 seconds)), czyli ORMy wszędzie

"Po co mi baza? Przecież mamy ORMy i tam języki zapytań i wszystko obiektowe, a nie jakieś relacyjne". Wszystko fajnie, ale tak długo jak ludzie nie rozumieją jak te ORMOwskie zapytania ("dawaj mi gnoju co wiesz" 1) przekładają się na kwerendy SQL i ich liczbę (osławiony problem N+1 zapytań, na który programiści regularnie się łapią jak co poniektórzy na reklamy magicznej pastylki, która sprawi, że schudniesz 15 kg w tydzień), tak długo nie są w stanie optymalnie wykorzystać podstawowego narzędzia, z którego korzystają (czyli bazy danych).

I to by jeszcze było pół biedy jakby już dostali z tych ORMów to co chcieli, ale zazwyczaj dalej jest tylko gorzej. Zadają szerokie zapytanie do bazy i później zajmują się przetwarzaniem dużej ilości danych w pamięci aplikacji, zamiast od razu zapytać bazę o to co chcą, albo zlecić bazie, żeby zrobiła skomplikowane obliczenia i zwróciła tylko ich wynik. Szerokie, ORMOWskie zapytania działają oczywiście rzędy wielkości wolniej. Jeśli takich operacji pod jednym kliknięciem w aplikacji dzieje się więcej, to różnice się kumulują i czas przetwarzania wydłuża się poza granice akceptowalne dla użytkownika.

Interluda wspominkowa: Ciekawie oglądało się kiedyś wynik audytu jednej takiej aplikacji (JavaEE z ORMem Hibernate), która działała dokładnie sposób opisany wyżej i było wielką tajemnicą wiary, dlaczego przy zalogowaniu piątego użytkownika aplikacja wywraca serwer. Tajemnica się rozwikłała, gdy mój znajomy fachowiec przejrzał zrzuty pamięci i okazało się, że dla jakiejś trywialnej operacji, która wykonywana była zaraz po zalogowaniu, rzeczona aplikacja ładowała przez ORMa do pamięci ~100tys. rekordów z bazy (oczywiście wszystkich nie potrzebowała, zaledwie garstki).

EXCEPTION

WHEN "BUSY DATABASE" THEN

Zaraz się zlecą tu na mnie wszyscy puryści, którzy będą twierdzić, że purystami nie są, że to po prostu takie standardy, żeby przesyłać w te i z powrotem spore wolumeny danych i obrabiać je w aplikacji. Oni są pragmatykami, 20 lat doświadczenia i nie przekonasz ich, że może być inaczej. Bo co to by było, gdyby logika przetwarzania danych była blisko tych danych (znaczy się w bazie, w procedurach składowanych). Przecież to obciach, a poza tym, nikt już tak nie robi. Oprócz pewnie X milionów programistów, o których ja wiem, a ci pragmatyczni-puryści zdają się celowo zapominać.

I żeby nie było - jestem świadomy tzw. antywzorca "busy database", gdzie baza jest zmuszana do robienia wielu rzeczy poza jej przeznaczeniem, co może niepotrzebnie dociążać ten element infrastruktury. Ale jak to zwykle bywa, to kwestia rozłożenia odpowiednio akcentów w projektowaniu systemu i brania pod uwagę np. środowiska w jakim pracujemy - czy to cloud (potencjalnie więcej kosztuje skalowanie bazy danych) czy on-premise (jak już gdzieś mamy gigantyczny klaster pod bazy, a przydzielenie dodatkowych zasobów pod serwera aplikacji to droga przez mękę), czy innych uwarunkowań (np. standardy w organizacji).

WHEN OTHERS THEN

No i co w związku z tym ktoś mógłby zapytać? No niby nic, bo jak to mówią Amerykanie jest więcej niż jeden sposób, żeby oskurować kota (swoją drogą ciekawa musi być etymologia tego przysłowia). Ale jednak "coś", bo tacy programiści-puryści będą z jednej strony mówić, że w [losowa platforma do kontenerów] (np. test containers) postawią sobie dockera z relacyjną bazą w 5 sekund, ale z drugiej będą optować za heksagonalną architekturą (bo, jak gdzieś nawinął Sokół, - "to tera modne") i adapterami i portami, żeby wymienić sobie driver (np. "mogę sobie napisać drivery do hashmapy / bazy w pamięci do testów i do relacyjnej bazy danych na produkcję i sobie to wymieniać dynamicznie").

Jeśli więc postawienie prawdziwej bazy trwa 5 sekund to po co w takim razie ta hashmapa jako proteza? "No przecież mówię, że do testów". Ale po co w takim razie testować coś, co ma zupełnie inny interfejs niż baza relacyjna (a taka będzie chodzić na produkcji)? "Bo testujemy logikę, a nie robimy testy integracyjne". Jeśli możemy odpalić relacyjna bazę w dosłownie chwilę to po co cały cyrk? "Ale Ty nie rozumiesz, bo tak jest szybciej i testy mi szybciej przechodzą".

No pewnie, że nie rozumiem, bo uważam, że i testy i development warto robić na środowisku maksymalnie zbliżonym do tego, co będzie na produkcji (np. te same wersje Java, te same wersje bazy, serwera aplikacji, powłoki, systemu operacyjnego czy czego tam jeszcze używacie), bo to już z definicji ogranicza potencjalne problemy. Za dużo razy już widziałem jak aplikacja pisana z wykorzystaniem OpenJDK przestaje działać na IMBowskim albo Oracle'owym JDK, albo zmiana systemu operacyjnego np. z AIXa na Linuxa sprawia, że wczoraj działało, a dzisiaj nie (i te przykłady, pozornej "przenośności" można by mnożyć).

"Ale bo ty nie rozumiesz - ja sobie wtedy mogę szybko podmienić bazę danych na inną". W mojej pełnoletniej karierze zawodowej nie trafiłem na zmianę silnika bazy danych, a przy rozwoju jednego czy drugiego systemu zdarzało się pracować latami. Po co zatem to zamieszanie? Tego nikt nie wie, ale rzeczeni architekci dalej będą pchali, że są pragmatykami i lubią praktyczne zastosowania schematów, wzorców, czy architektur.

Jakby jeszcze taki jeden z drugim powiedział - "Nie lubię baz danych. Za to kocham mój język programowania, w zasadzie ten język jest częścią mnie" (jak piła była częścią ciała Buzzsawa w "The Running Man"2, ale co mu z tego wyszło to trzeba film obejrzeć) i nie chcę poza niego wychodzić. Zrozumiałbym. Ale jak swoje projekcje, lęki i przyzwyczajenia próbują serwować jako prawda objawiona, dyskredytując przy okazji pracę ludzi (bazodanowców), na której wiele firm zarabia rokrocznie dziesiątki miliardów dolarów to trzeba mieć, szukam odpowiedniego słowa, …, tupet?.

Czy z jedną z miar jakości oprogramowania nie powinna być przede wszystkim użyteczność wobec celów biznesowych, które ma pomóc, jako narzędzie, realizować? Jeśli zgodzimy się, że software ma pomóc firmie działać sprawniej, żeby oszczędzać / zarabiać pieniądze to warto podchodzić z rezerwą do sytuacji, gdy przychodzi taki architekt "pragmatyk" i mówi - "Panie, kto panu to tak s…łabo zakodował? Ja Wam zrobię tak, że mucha nie usiądzie". Niestety przyszłość nierzadko pokazuje, żeby ta mucha w ogóle mogła się zastanowić, czy jest na czym usiąść, to są długie lata orki na ugorze, żeby stworzyć nowe oprogramowanie, które robi to samo co stare (nie zawsze lepiej).

Nie zrozumcie mnie źle - zdaję sobie sprawę z potrzeby wychodzenia legacy systemów. Przepisywanie (aktualizowanie) rozwiązań, czy ich całkowita wymiana powinna dziać się raz na jakiś czas (jeśli soft nie jest aktywnie rozwijany, to 5-7 lat myślę jest dobrym horyzontem, ale będą pewnie uzasadnione przypadki, gdzie i dłuższy okres działania będzie miał sens). Nie stawiajmy jednak wozu przed koniem i nie róbmy z ciągłego przepisywania na "najnowsze technologie" celu samego w sobie (to już dygresja na osobny wpis).

Podsumowanie, albo COMMIT

Ktoś przeczyta powyższe wywody i powie - o bazodanowiec się objawił ukryty i ma ból w okolicy dołu pleców, który nie jest atakiem kamicy nerkowej. Fakt - moje komercyjne doświadczenie rozpoczęło się od sytemu tworzonego dla telco na Oracle'owym RDBMS i w PL/SQLu (ale była przy tym też później i Java i mnóstwo basha i parę innych cudów). I trochę mnie to ukształtowało, ale głownie dlatego, że jedyne w czym chciałem robić wtedy to Microsoftowy C# i praca w Visual Studio, a basha szczerze nienawidziłem. No i po tym projekcie mi przeszło, bo zrozumiałem, że narzędzie to narzędzie - najbardziej obrażają się na nie ludzie, którzy nie potrafią go używać, nierzadko pomimo idealnego dopasowania tegoż narzędzia do rozwiązywanego problemu. Podsumowując ten przydługi wywód:

  • Bazodanowcy na szczęście jeszcze żyją i paru się uchowało takich, co przykładają się do roboty nad porządnie napisanymi aplikacjami
  • Jeśli projektant aplikacji po macoszemu traktuje obszar bazy danych, to oznacza, że "something is no yes" i możesz już szykować wytłumaczenia dla użytkowników, dlaczego ten twój nowy system, co miał im ułatwić robotę tak strasznie wolno działa
Niektóre linki z artykułu:

1 Dla młodzieży link do Wikipedii co to było to ORMO, żeby skumali mój wyborny żart

2 "The Running Man - Buzzsaw i jego piła - klip na Youtube


A może jeszcze jeden?