w obecnej firmie siedzimy na oracle'u od początku i raczej nie będzie zmiany na inną bazę sqlową. natomiast mamy też bazy nosql, czyli mongodb i tam jest coraz więcej danych.
problemem z bazami sqlowymi jest sam sql przede wszystkim. mało kto ma dobrą intuicję jak robić sensowne zapytania. z drugiej strony, jak ktoś lubi zaszaleć z sqlem (jak ja) to oracle losowo sobie zapytania przeoptymalizuje (tzn. w zależności od humoru execution plan może być zupełnie inny) i trudno jest przewidzieć czy sprytne (tzn. przekombinowane do pewnego stopnia) zapytanie zacznie masakrycznie zwalniać. do tego dochodzi protokół jdbc, gdzie wiersze z wynikowego zapytania są pobierane batchami domyślnie po 10 wierszy, tzn. dla każdych 10 wierszy mamy roundtrip delay, więc jeśli apka i baza są mocno oddalone to mamy mocno spowolnione wczytywanie wyników żądania. rozwiązaniem jest zwiększenie tego batcha o rzędy wielkości, ale takie rozproszenie apek i baz po różnych regionach świata i tak mamy tylko na środowiskach testowych.
problemów z sqlem jest dużo, ale taki jeden, na który mało kto zwraca uwagę jest to, że ludziom tak mocno wchodzi w głowę problem n+1 zapytań, że mają tendencję do upychania wszystkiego do jednego zapytania. dla przykładu, załóżmy że mamy jedną tabelę z wieloma kolumnami i drugą z zaledwie dwiema, z relacją 1:n między nimi. trzeba je zjoinować. jak to zrobić, żeby nie zaciągać masy zduplikowanych danych z serwera? ja bym zjoinował już po pobraniu danych. tymczasem typowy programista joinuje wszystko jak leci i pobiera masę zduplikowanych danych.
mój sposób to najpierw zaciągnięcie niezduplikowanych danych:
Kopiuj
select * from tabela_z_wieloma_kolumnami where <cośtam>;
select * from tabela_z_niewieloma_kolumnami where foreign_id in (select id from... i tutaj reszta powyższego zapytania, tzn. jest id zamiast gwiazdki);
wyciągnięte w ten sposób dane są względnie kompaktowe, bo dane z każdego wiersza wyciągam raz, bez duplikowania danych w wyniku
potem robię joina po stronie apki i wszystko gra
nie ma n+1 zapytań, bo są 2 zapytania, niezależnie od rozmiaru danych w bazie
sposób moich kolegów to natomiast:
Kopiuj
select * from tabela_z_wieloma_kolumnami szeroka, tabela_z_niewieloma_kolumnami waska where waska.foreign_id == szeroka.id and <cośtam>;
wyciągnięte w ten sposób dane mają masę duplikatów, jeśli dla typowego wiersza z szerokiej tabeli jest wiele odpowiedników w wąskiej tabeli.
w bazach dokumentowych (nosql, mongodb) generalnie nie ma takich dylematów, więc jest koncepcyjnie prościej.
sqlowe schematy trudniej zaprojektować pod kątem wydajności niż nosqlowe, więc w moim projekcie jest tendencja ku zapisywaniu danych do mongodb, a nie oracle'a. w sumie to lepiej, bo nie mam się nad czym załamywać.