Wpis z mikrobloga

#programowanie #bazydanych #webdev #csharp

Stoimy z chłopakami przed pewnym dylematem i brakuje nam wiedzy aby być w stanie go jakoś rozstrzygnąć. Obecnie sprawa wygląda tak, że jest sobie baza MSSQL która ma od pyty procedur składowanych w których to dzieje się cała magia. Danych jest bardzo dużo i przychodzą non stop, backend jest szczątkowy - właściwie tylko przewala gotowce z bazy do frontu. Mówimy o potencjalnie setkach gigabajtów danych, które to mogą być niekiedy pobierane w ilości wielu gb na raz celem zrobienia np. agregacji do wykresów. Obecnie robi to baza w wewnętrznej procce i backend dostaje tylko mały zagregowany już odpowiednio pakiet danych, więc działa to jako tako.

No ale procedury składowane śmierdzą, bo uwiązują jajca do konkretnego silnika baz danych a w dzisiejszych czasach można się zastanawiać czy baza na pewno szybciej przeliczy. NoSQL nie ma procek składowanych, jest dosyć szybkie i masz podejście "code-first" w gratisie bez żadnych dziwnych tańców, aczkolwiek sam model danych to jeden wielki burdel i w pewnym momencie jak to spuchnie, to może się zrobić chaos nad którym normalnie panowałyby relacje.

Macie jakieś doświadczenia z tym związane aby mieć porównanie?

Co byś wybrał?

  • NoSQL + agregowanie w backendzie 19.0% (8)
  • SQL (db-first) + agregowanie w backendzie 61.9% (26)
  • SQL (db-first) + agregowanie w prockach 19.0% (8)

Oddanych głosów: 42

  • 43
  • Odpowiedz
@Khaine: to bierzesz sobie TimescaleDB lub jakąś DB kolumnową i lecisz. Zawsze możesz mieć nawet 2 DB, i używać tej, która ma w danym momencie większy sens.
  • Odpowiedz
@Hauleth: tak, tylko tutaj zachodzi problematyka językowa. Relacja to jest owszem tabela, ale zazwyczaj mówiąc relacja mamy na myśli właśnie te jak to nazwałeś "JOINY" czyli związki co wprowadza jeszcze większe zamieszanie o czym można przeczytać w tym artykule.

Samo określenie RELACJA w nomenklaturze języka polskiego, może być trochę tutaj mylące. W końcu RELACJA i ZWIĄZEK to synonimy a jak widać dotyczą dwóch zupełnie różnych światów RELACJA=TABELA a ZWIĄZEK to
  • Odpowiedz
@ksiak: @Hauleth: No generalnie można mieć bazę SQL "bez relacji", wystarczy że nie ma żadnych kluczy obcych pozakładanych. Wtedy nie ma dużej różnicy wobec NoSQLowego wiadra, bo i tak trzeba robić selecty z wielu tabel i łączyć przez WHERE.
  • Odpowiedz
@ksiak: tyle, że JOIN nie jest relacją, tylko operacją w algebrze relacji. Tutaj dane wewnątrz tabeli są w "relacji", bo są ze sobą silnie związane (wewnątrz wierszy i kolumn). "Relacje" jako JOINy istnieją tylko na wysokim poziomie dla "człowieka". Więc to jest problem z tłumaczeniem algebry a nie nomenklaturą, bo JOIN nie oznacza ani "relacji" ani "związku".
  • Odpowiedz
@Hauleth: W sumie to się straci tylko agregację w trybie ciągłym, ale to chyba akurat wiele nie zmieni, bo dane są potrzebne na żądanie z nie wiadomo jakiego okresu i zawsze trzeba będzie liczyć w locie, interpolacja i tak nie jest nam potrzebna raczej. Jak już to się po prostu dopisze samemu ( ͡° ͜ʖ ͡°)
  • Odpowiedz
@Hauleth: Swoją drogą trochę mnie zastanawia skąd tyle głosów za agregacjami w backendzie a nikt z tych ludzi się nie wypowiedział czemu akurat tak, kiedy przypadek jest raczej nie za bardzo po myśli liczenia w backendzie? ¯\_(ツ)_/¯ Brzmi jak "liczyłbym w backendzie z lenistwa, bo mi się nie chce pisać procedur i nie mówię czemu akurat tak, bo też mi się nie chce" xD
  • Odpowiedz
@Hauleth: jak widzisz, podałem Ci jeden z przykładowych artykułów w którym ładnie wyjaśniono problematykę nazewnictwa. Teraz Ty próbujesz to dalej tłumaczyć co wykracza już całkowicie poza pytanie OP.
  • Odpowiedz
@ksiak: Problem w tym, że ten artykuł też miesza pojęcia z algebry relacji (relacje) z pojęciami z samej implementacji w DB (klucze) przez co powoduje jeszcze większe zamieszanie. Nic nie stoi na przeszkodzie, by mieć JOINy w nierelacyjnych DB (np. w CouchBase mamy JOINy).
  • Odpowiedz
@Khaine: wszystko zależy od tego co dokładniej ma się dziać. baza jest bezpieczniejsza, bo nie będziesz pobierać zbędnych danych. Jak źle napiszesz backend, to taka agregacja może się skończyć 15 zagnieżdżonymi pętlami, które będą się wykonywać cholernie długo. Baza jakoś sobie zoptymalizuje, C# będzie wykonywał dokładnie co mu napiszesz.
Zastanów się jak dobrze u was z optymalizacją takich rzeczy w kodzie. Jeżeli np, często zdarza się że wewnątrz jednej pętli kusi was żeby napisać drugą pętlę (czytaj - użyć LINQ), to raczej zostań przy bazie, chyba że dokładnie wiesz co jaki będzie miało koszt obliczeniowy.
Jeżeli tak jak piszesz, jedna kwerenda będą tysiące lub miliony rekordów - głosowałbym za bazą.
Pisanie agregacji w kodzie bywa ciężkie. Baza ma już indeksy, których może użyć, Ty w kodzie nie masz, musisz je zrobić żeby ich użyć, co może chwilę trwać. Możliwe nawet że będziesz musiał stworzyć kilka własnych dziwnych rozwiązań, żeby to jakoś działało.

Jeśli chodzi o backend, zamierzasz używać jakiegoś ORM-a? Zakładam że tak, to też może mieć duże znaczenie. Odpowiednio zoptymalizowany ORM będzie działał naprawdę dobrze, ale dobre zoptymalizowanie ORM (nawet pod konkretne kwerendy) może zająć duuużo czasu i trzeba się tym zająć od samego
  • Odpowiedz