Wszystkie odpowiedzi (w momencie pisania tego tekstu) zakładają, że każda z Redis, MongoDB i być może relacyjna baza danych oparta na SQL są zasadniczo tym samym narzędziem: „przechowuj dane”. W ogóle nie biorą pod uwagę modeli danych.
MongoDB: złożone dane
MongoDB to magazyn dokumentów. Aby porównać z relacyjną bazą danych opartą na SQL: relacyjne bazy danych upraszczają indeksowane pliki CSV, przy czym każdy plik jest tabelą; magazyny dokumentów upraszczają indeksowane pliki JSON, przy czym każdy plik jest dokumentem, z wieloma plikami zgrupowanymi razem.
Pliki JSON mają podobną strukturę do plików XML i YAML oraz do słowników jak w Pythonie, więc pomyśl o swoich danych w takiej hierarchii. Podczas indeksowania kluczem jest struktura: dokument zawiera nazwane klucze, które zawierają kolejne dokumenty, tablice lub wartości skalarne. Rozważ poniższy dokument.
{
_id: 0x194f38dc491a,
Name: "John Smith",
PhoneNumber:
Home: "555 999-1234",
Work: "555 999-9876",
Mobile: "555 634-5789"
Accounts:
- "379-1111"
- "379-2574"
- "414-6731"
}
Powyższy dokument ma klucz PhoneNumber.Mobile
, który ma wartość 555 634-5789
. Możesz przeszukiwać zbiór dokumentów, w których klucz PhoneNumber.Mobile
ma pewną wartość; są indeksowane.
Ma także tablicę, w Accounts
której znajduje się wiele indeksów. Możliwe jest zapytanie o dokument, w którym Accounts
znajduje się dokładnie pewien podzbiór wartości, cały podzbiór wartości lub dowolny podzbiór wartości. Oznacza to, że możesz wyszukiwać Accounts = ["379-1111", "379-2574"]
i nie znajdować powyższych; możesz wyszukać Accounts includes ["379-1111"]
i znaleźć powyższy dokument; i możesz wyszukać Accounts includes any of ["974-3785","414-6731"]
i znaleźć powyższy dokument oraz dowolny dokument zawierający konto „974-3785”, jeśli istnieje.
Dokumenty sięgają tak głęboko, jak chcesz. PhoneNumber.Mobile
może pomieścić tablicę lub nawet dokument podrzędny ( PhoneNumber.Mobile.Work
i PhoneNumber.Mobile.Personal
). Jeśli Twoje dane są wysoce ustrukturyzowane, dokumenty stanowią duży krok naprzód w stosunku do relacyjnych baz danych.
Jeśli Twoje dane są głównie płaskie, relacyjne i mają sztywną strukturę, lepiej jest z relacyjną bazą danych. Ponownie, wielkim znakiem jest to, czy Twoje modele danych najlepiej nadają się do zbioru powiązanych ze sobą plików CSV, czy zbioru plików XML / JSON / YAML.
W przypadku większości projektów trzeba pójść na kompromis, akceptując drobne obejście w niektórych małych obszarach, w których nie pasuje ani SQL, ani Dokumenty; w przypadku niektórych dużych, złożonych projektów przechowujących szeroki zakres danych (wiele kolumn; wiersze są nieistotne), sensowne będzie przechowywanie niektórych danych w jednym modelu, a innych danych w innym modelu. Facebook używa zarówno SQL, jak i graficznej bazy danych (gdzie dane są umieszczane w węzłach, a węzły są połączone z innymi węzłami); Craigslist zwykł używać MySQL i MongoDB, ale starał się całkowicie przenieść na MongoDB. Są to miejsca, w których rozpiętość i relacja danych napotykają znaczne utrudnienia, jeśli są objęte jednym modelem.
Redis: klucz-wartość
Redis to przede wszystkim sklep z kluczowymi wartościami. Redis pozwala ci dać klucz i wyszukać pojedynczą wartość. Redis może przechowywać ciągi, listy, skróty i kilka innych rzeczy; jednak wyszukuje tylko według nazwy.
Unieważnienie pamięci podręcznej jest jednym z trudnych problemów informatycznych; drugi nazywa rzeczy. Oznacza to, że będziesz używać Redis, jeśli chcesz uniknąć setek nadmiaru odnośników do zaplecza, ale będziesz musiał dowiedzieć się, kiedy potrzebujesz nowego wyszukiwania.
Najbardziej oczywistym przypadkiem unieważnienia jest aktualizacja przy zapisie: jeśli czytasz user:Simon:lingots = NOTFOUND
, możesz SELECT Lingots FROM Store s INNER JOIN UserProfile u ON s.UserID = u.UserID WHERE u.Username = Simon
i zapisać wynik 100
, jak SET user:Simon:lingots = 100
. Wtedy, kiedy przyzna Simon 5 Lingots, można przeczytać user:Simon:lingots = 100
, SET user:Simon:lingots = 105
i UPDATE Store s INNER JOIN UserProfile u ON s.UserID = u.UserID SET s.Lingots = 105 WHERE u.Username = Simon
. Teraz masz 105 w swojej bazie danych i w Redis, i możesz dostać się user:Simon:lingots
bez zapytania do bazy danych.
Drugi przypadek to aktualizacja informacji zależnych. Załóżmy, że generujesz fragmenty strony i buforujesz ich wyniki. Nagłówek pokazuje doświadczenie, poziom i ilość pieniędzy gracza; strona profilu gracza ma blok, który pokazuje jego statystyki; i tak dalej. Gracz zdobywa trochę doświadczenia. Cóż, teraz masz kilka templates:Header:Simon
, templates:StatsBox:Simon
, templates:GrowthGraph:Simon
, i tak dalej dziedzinach, w których już buforowane wyjście bazy pół tuzina zapytań prowadzonym przez silnik szablonu. Zwykle podczas wyświetlania tych stron mówisz:
$t = GetStringFromRedis("templates:StatsBox:" + $playerName);
if ($t == null) {
$t = BuildTemplate("StatsBox.tmpl",
GetStatsFromDatabase($playerName));
SetStringInRedis("Templates:StatsBox:" + $playerName, $t);
}
print $t;
Ponieważ właśnie zaktualizowałeś wyniki GetStatsFromDatabase("Simon")
, musisz zrezygnować templates:*:Simon
z pamięci podręcznej klucz-wartość. Podczas próby renderowania któregokolwiek z tych szablonów aplikacja odpali pobieranie danych z bazy danych (PostgreSQL, MongoDB) i wstawia je do szablonu; następnie zapisze wynik w Redis i, miejmy nadzieję, nie będzie zawracał sobie głowy tworzeniem zapytań do bazy danych i renderowaniem szablonów przy następnym wyświetleniu tego bloku danych wyjściowych.
Redis umożliwia także tworzenie kolejek wiadomości subskrybowanych przez wydawcę i tym podobnych. To zupełnie inny temat. Chodzi o to, że Redis to pamięć podręczna klucz-wartość, która różni się od relacyjnej bazy danych lub magazynu dokumentów.
Wniosek
Wybierz narzędzia w zależności od potrzeb. Największą potrzebą jest zazwyczaj model danych, który określa stopień złożoności i podatności na błędy w kodzie. Specjalistyczne aplikacje będą opierać się na wydajności - miejscach, w których piszesz wszystko w mieszance C i asemblera; większość aplikacji po prostu obsłuży uogólnioną skrzynkę i użyje systemu buforowania, takiego jak Redis lub Memcached, który jest o wiele szybszy niż wysokowydajna baza danych SQL lub magazyn dokumentów.