NoSQL

mjedrzejewski.wordpress.com 7 lat temu

Wstęp

Od jakiegoś czasu, dużą uwagę poświęcam rozwiązaniom NoSQL. Nie jest to łatwy temat, ponieważ wymaga od programisty kompletnego przestawienia się z myślenia relacyjnego na agregacyjne. Do tego dochodzi mnóstwo “kruczków”, typów do wyboru i wreszcie dostawców rozwiązań. Pojawia się w głowie wiele pytań, tj. Jakim cudem moja baza danych może nie posiadać schematów? Tym i innym zagadnieniom przyjrzę się w dzisiejszym wpisie.

Co to jest NoSQL? (nie NOSQL!)

Przede wszystkim jest to odpowiedź na coraz szybszy rozrost baz danych. W pewnym momencie zauważono, iż bardzo dobrym pomysłem jest przechowywanie bardzo dużej ilości danych, głównie w celach marketingowych. Bazując na konkretnych informacjach, różne firmy rozpoczęły swoje kampanie, wychodząc naprzeciw potrzeb użytkowników ich aplikacji.

Wszystko wyglądało pięknie do momentu, gdy ilość danych przechowywanych na serwerach wykorzystujących bazy relacyjne, zaczęła znacznie wychodzić ponad dotychczasowe limity (Big Data). Pojawiły się problemy z wydajnością zapytań – żeby odczytać niektóre dane, trzeba było czekać parę minut, a niekiedy dużo więcej. Trzeba było znaleźć inne rozwiązanie.

Głównym celem było rozłożenie dużej ilości danych pomiędzy wiele serwerów, czyli tzw. horizontal scaling oraz odpytywanie konkretnych serwerów w celu uzyskania konkretnych danych. Takie rozwiązanie mogłoby pozwolić na znaczne zwiększenie wydajności.

Sam termin NoSQL – w kontekście współczesnego znaczenia – powstał w 2009 roku – na twitterze została zorganizowana dyskusja na temat nazwy dla opisywanego rozwiązania. Oficjalnie, nazwa ta nie ma żadnego znaczenia. Wiele osób związanych ze światem programowania używała definicji Not Only SQL jednak nie jest ono prawdziwe – gdyby tak było, mogłoby również opisywać bazy relacyjne, a tego twórcy na pewno chcieli uniknąć. Poprzez taką definicję powszechnie nadużywany jest skrót NOSQL (z wielkim “O”), który również jest błędny.

Ponadto nazywanie czegoś NoSQL w znaczeniu „nie tylko SQL” nie jest poprawne, ponieważ wtedy także Oracle i Postgres pasowałyby do tej definicji, udowodnilibyśmy, iż białe równa się czarne, i wszyscy zostalibyśmy przejechani na przejściu dla pieszych. – NoSQL. Kompendium wiedzy, Pramod J. Sadalage, Martin Fowler

Główną siłą NoSQL jest przede wszystkim skalowalność, brak modelu relacyjnego – co nie zawsze jest dobre oraz brak schematów dla danych.

Skalowalność

Istnieją dwie główne skalowalności:

  • pionowa (eng. vertical scaling)
  • pozioma (eng. horizontal scaling)

Pionowa

Polegająca na coraz droższym rozbudowywaniu jednego serwera w celu zwiększenia jego wydajności, co i tak w pewnym momencie najprawdopodobniej doprowadzi do technologicznej ściany i będziemy mieć duży problem.

Pozioma, zwana również shardingiem:

Polegająca na dywersyfikacji danych, w celu przechowywania ich na wielu serwerach. Takie rozwiązanie jest dużo tańsze niż skalowanie pionowe. Każdy z serwerów może mieć słabe parametry, ponieważ to do nas należy decyzja, jak wiele danych chcemy na nim przechowywać. W momencie pojawienia się nowych encji w naszej bazie, możemy zdecydować, iż będą one przechowywane na nowym, dodatkowym serwerze.

Kolejną zaletą jest to, iż w momencie, gdy serwer odpowiadający np. za produkty w naszym systemie przestanie działać, reszta serwerów będzie przez cały czas umożliwiała korzystanie z aplikacji. I tutaj możliwe są 2 scenariusze:

  • dane dot. produktów trzymamy na kilku serwerach, przez co aplikacja może przez cały czas wyświetlać listę niektórych produktów
  • dane dot. produktów trzymamy na jednym serwerze, przez co aplikacja nie może wyświetlać listy produktów, ale za to umożliwia operacje związane z innymi encjami, jak np. zarządzanie użytkownikami, czy koszykiem

To, który scenariusz wybierzemy zależy od nas samych, specyfiki oraz wymagań naszego systemu.

Typy NoSQL

Wyróżniamy 4 podstawowe typy. Każdy z nich jest przeznaczony do konkretnych rozwiązań, aczkolwiek mogą być używane zamiennie, o ile lubimy komplikować sobie życie.

Dokument (eng. Document)

  • Kolekcja jest odpowiednikiem tabeli
  • Dokument jest odpowiednikiem wiersza
  • Można aktualizować dane częściowo
  • Wiele dokumentów może być przedstawionych dzięki jednej agregacji
  • Transakcje – brak wsparcia dla kompletnego ACID (eng. Atomicity, Consistency, Isolation, Durability)
  • Najbardziej popularne rozwiązanie
  • Przykładowi dostawcy: MongoDb, RavenDb, CouchDb

Klucz – wartość (eng. Key – value)

  • Wiadro jest odpowiednikiem tabeli
  • Klucz – wartość jest odpowiednikiem wiersza
  • Najprostsze w użyciu bazy NoSQL (z pkt. API)
  • Wiadro zawiera wiele obiektów klucz – wartość
  • Każdą wartość można uzyskać dzięki konkretnego klucza
  • Bazy nie interesuje wartość, jej odczyt odbywa się z poziomu aplikacji
  • Wartość jest usuwana dzięki klucza
  • Bardzo wydajne ze względu na wykorzystanie klucza głównego
  • Transakcje – brak wsparcia dla kompletnego ACID (eng. Atomicity, Consistency, Isolation, Durability)
  • Przykładowi dostawcy: BerkeleyDb, RiakDb

Rodzina kolumn (eng. Column family)

  • Rodzina kolumn jest odpowiednikiem tabeli
  • Wiersz jest odpowiednikiem wiersza
  • Dane są przechowywane w rodzinach kolumn w postaci wierszy, do których przypisany jest konkretny klucz
  • Na jedną kolumnę składa się para nazwa – wartość, w której kluczem jest nazwa
  • Pobieramy dane, które są ze sobą w jakiś sposób powiązane – jedna rodzina kolumn to samochody, druga to silniki i zwykle chcemy pobrać je razem. Trzecia, niepowiązana rodzina to lista fabryk i jej pobierać w obrębie wyżej zdefiniowanej rodziny nie chcemy
  • Transakcje – brak wsparcia dla kompletnego ACID (eng. Atomicity, Consistency, Isolation, Durability)
  • Przykładowi dostawcy: Cassandra

Graf (eng. Graph)

  • Rozwiązanie używane głównie w aplikacjach social media, w których stawia się na wiele relacji pomiędzy użytkownikami, grupami itp. oraz bazujących na algorytmach do wyznaczania tras
  • Pobierając dane np. jednego użykownika, znamy jego powiązania z innymi użytkownikami oraz ich potencjalne powiązania
  • Transakcje -jako jedyny typ wspiera kompletny ACID (eng. Atomicity, Consistency, Isolation, Durability)
  • Przykładowi dostawcy: FlockDb, OrientDb

Brak schematów dla danych – wada czy zaleta?

W przeciwieństwie do relacyjnych baz danych, w przypadku NoSQL nie definiujemy żadnych schematów dla przechowywanych danych. Tyle teorii. Jak to wygląda w praktyce?

Powiedzmy, iż mamy zdefiniowane 2 różne obiekty tego samego typu – Pojazd. Samochód oraz Samolot. Samolot posiada skrzydła, ogon, wyjścia awaryjne, ster. Samochód ma np. kierownicę. Nie definiując schematu, możemy obydwa obiekty przechowywać w obrębie jednego dokumentu. I będą one traktowane jako Pojazd. Bez względu na to co zawierają. O to musi się już martwić aplikacja.

Zaletą takiego rozwiązania jest na pewno niski stopień skomplikowania struktur bazodanowych, co przekłada się na zwiększenie wydajności zespołu pracującego nad rozwiązaniem w obszarze bazy danych. Czy przypadkiem nie jest tak, iż większość nas programistów ma w głębokim poważaniu to, co dzieje się w bazie danych? 😉

Niestety taka zaleta generuje również wiele problemów, a podstawowym jest to, iż ktoś musi nad taką bazą czuwać, żeby nie okazało się, iż w dokumentach przechowujących obiekty typu Pojazd, przechowujemy po jakimś czasie np. użytkowników 🙂

Wadą takiego rozwiązania jest na pewno problem przy bazach integracyjnych – wyobraźmy sobie, iż z jednej bazy korzysta kilka aplikacji. Dane nie mają schematów. Deweloperzy jednej z aplikacji dodali kilka adekwatności, inni kolejne itp. nie informując innych o zmianach. Prędzej, czy później wszystko legnie w gruzach. Dlatego NoSQL w takich przypadkach nie jest zalecany. Oczywiście, istnieje możliwość, iż będziemy w posiadaniu zespołu do monitorowania takich zmian, ale po co sobie komplikować życie?

Czy relacyjne bazy danych umierają?

Nie. Mają i w najbliższych latach będą się miały bardzo dobrze. Dlaczego? przez cały czas w wielu przypadkach jest to rozwiązanie lepsze od NoSQL, a najlepszym przykładem są integracyjne bazy danych, o których wspominałem w poprzednim akapicie. Kolejnymi argumentami przeciwko jest to, iż większość obecnych programistów wychowała się na relacyjnych bazach danych, większość aplikacji biznesowych przez cały czas na nich operuje i przez cały czas wiele potencjalnych rozwiązań będzie na nich bazować.

Podsumowanie

  • Eleganckie operowanie na Big Data
  • Rozwiązanie zaprojektowane do równoległego przetwarzania danych
  • Brak schematów dla danych
  • W zdecydowanej większości brak wsparcia dla transakcji
  • Mniejsze koszty niż w przypadku baz relacyjnych dla Big Data
  • Niepopularne rozwiązanie dla baz integracyjnych – zwłaszcza ze względu na brak schematów dla danych
Idź do oryginalnego materiału