![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 247 Pomógł: 11 Dołączył: 5.09.2009 Ostrzeżenie: (0%) ![]() ![]() |
Do tej pory używałem relacyjnych baz danych, niedawno wielce się zdziwiłem gdy spotkałem się z nosqlową bazą danych MongoDB. Ktoś tego używał i ma porównanie jakie to ma wady i zalety w porównaniu do relacyjnych baz danych? Chyba wszystkie duże serwisy są oparte o bazy relacyjne więc to MongoDB jest wykorzystywane tylko w małych serwisach czy jak to wygląda?
|
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 634 Pomógł: 14 Dołączył: 27.05.2006 Skąd: Berlin Ostrzeżenie: (0%) ![]() ![]() |
Widzę, że muszę interweniować bo tu niektórzy Panowie nie za bardzo rozumieją pojęcia bazy relacyjnej ;-)
Weźmy sobie jako prosty przykład bazę danych która ma dane o użytkownikach, podzieloną na kilka tabel: Użytkownik, Adresy użytkownika, Kupione produkty. Żeby takie coś zaprojektować w relacyjnej bazie danych muszę przechować dane mniej-więcej w takiej strukturze: - Tabela "Użytkownik" - Tabela "AdresyUżytkowników" - Tabela "Produkty" - Tabela "KupioneProdukty" Teraz - jeśli wykonamy zapytanie: Zwróć mi wszystkie adresy użytkowników którzy kupili produkty o cenie wyższej niż 100zł. Co silnik bazy danych zrobi z takim zapytaniem? 1. Przeleci po całej tabeli "Produkty" i przefiltruje ją pod względem ceny i zwróci kolekcję produktów która ma kolumnę "Cena" > 100 zł. 2. Listę produktów z podzapytania numer 1, wykorzysta, żeby przelecieć po tabeli "KupioneProdukty" i będzie porównywać elementy kolumny "Identyfikator Produktu" i sprawdzać czy należy do zbioru szukanych danych następnie utworzy nową kolekcję i dla każdego pozytywnego wyniku porównania identyfikatorów produktu, wrzuci do tej kolekcji wartość kolumny "Identyfikator Użytkownika". 3. Kolekcję identyfikatorów użytkownika uzyskaną z podzapytania numer 2, wykorzysta aby przeskanować tabelę AdresyUżytkownika i będzie porównywać każdy wiersz tamtej tabeli i sprawdzać czy wartość kolumny identyfikator użytkownika należy do tego zbioru. 4. Utworzy nową kolekcję do której będzie wrzucać wszystkie wiersze które pomyślnie przejdą porównanie w kroku numer 3. (faktyczny query plan jest ciut bardziej skomplikowany - to jest delikatne uproszczenie) Żeby zrealizować takie zapytanie, wszystkie wiersze wszystkich tych tabel muszą znajdować się w "zasięgu" tego silnika bazy danych - w zasięgu znaczy, że musi mieć szybki dostęp do wszystkich tych wartości - więc albo dysk albo RAM. Tak się dzieję, ponieważ takie zapytania wymagają scanu po wszystkich dostępnych danych. To nie skaluję się dobrze/łatwo jeśli mamy miliony sprzedanych produktów, miliony użytkowników i miliony adresów (jak np. Amazon.com czy podobnych rozmiarów bazy danych). W takich przypadkach jedna maszyna nie jest w stanie udźwignąć całość danych z rożnych względów - czy to pojemnościowych czy wydajnościowych. Wtedy stosuję się bazy danych NoSQL. Bazy danych NoSQL przechowałyby te dane w inny sposób, zależnie od rodzaju bazy NoSql (jest ich mnóstwo - t.j grafowe, klucz/wartosc, dokumentowa, drzewiasta/hierarchiczna, itd..) i np. przechowałaby: Kod Użytkownik: [ "Imie" : "Jasio", "Nazwisko": Kowalski" "Adresy" : [ "15 Ulica, Miasto", "18 Ulica, Miasto" ], "Kupione Produkty": [ "Nazwa Produktu 1", "Nazwa produktu 2", "Nazwa produktu 3" ] ] W tak ułożonych danych, nie ma zależności pomiędzy różnymi zestawami danych, dlatego, nie muszą one być natychmiastowo dostępne do zwrócenia wyniku zapytania: Zwróć mi listę wszystkich produktów kupionych przez użytkownika o nazwisku "Kowalski". Koszt jaki płaci się przy takiej strukturze danych to mocno ograniczona elastyczność zapytań. Żeby zwrócić wartość zapytania z wyżej podanego przykładu: "Adresy użytkowników którzy kupili produkty > 100zł", musimy własnoręcznie wykonać te wszystkie kroki podzapytania. Co to nam daję? Daje to możliwość łatwego skalowania. Jak przechowujemy niezależne dane, to możemy zaprogramować farmę serwerów load-balancerów w taki sposób: Jeśli będzie zapytanie o użytkownia i ten użytkownik będzie miał nazwisko zaczynające się na literkę "K", to przekieruj to zapytanie to farmy serwerów znajdującej się w tu i tu. Jeśli będzie zapytanie o użytkownika o nazwisku zaczynającego się na "M" to przekieruj do serwerowni gdzieś indziej. I w taki sposób można bardzo łatwo odciążyć serwery i znieść potrzebę dostępu do całego zestawu danych na raz. Daję stabilność i fault-tolerance. Jeśli panie nam serwer z użytkownikami na literkę "J" to nam padnie tylko mała część danych, zapytania o "K", "G", "F" dalej będą działać poprawnie i będą zwracać poprawne i pełne wyniki. Czego to nam nie daję? Nie daję nam elastyczności zapytań - możemy zadawać tylko takie zapytania do bazy danych jakie przewidzieliśmy podczas jej projektowania pod daną aplikację i pod dany przypadek (chyba, że chcemy, żeby nam zapytanie wykonywało się bardzo wolno). Nie daję nam łatwego sprawdzania konsystencji danych. Jasio Kowalski może mieć w swojej liście kupionych produktów produkt o nazwie "Nazwa produktu 2" który zmienił nazwę na "Nazwa Produktu 7". Żeby ten update odzwierciedlił się wszędzie, musimy ręcznie pozmieniać te wartości w zestawie użytkowników (przelecieć po zbiorze użytkowników i zobaczyć czy tam jest nasz szukany produkt i jeśli tak to zmienić jego nazwę). Bazy NoSQL istnieją od bardzo dawna. Powstały dużo wcześniej niż relacyjne. Bardzo dobrym przykładem nierelacyjnej bazy danych jest wasz system plików - zapytania możecie zadawać tylko i wyłącznie podając ścieżkę do pliku. Inne typy zapytań są bardzo wolne (np szukanie plik po pliku). NoSQL przydaję się zazwyczaj wtedy kiedy zwykła relacyjna baza danych nie wyrabia (powyżej kilka Terabyte). Ten post edytował nasty 10.07.2012, 12:18:29 |
|
|
![]() ![]() |
![]() |
Aktualny czas: 3.10.2025 - 17:48 |