Redis
 sql >> Baza danych >  >> NoSQL >> Redis

ServiceStack.Net Redis:przechowywanie powiązanych obiektów w porównaniu z powiązanymi identyfikatorami obiektów

Zamiast ponownie haszować wiele innych dokumentów, które są dostępne na wolności, wymienię kilka, aby uzyskać podstawowe informacje dotyczące klienta Redis i usługi ServiceStack:

  • O czym należy myśleć podczas projektowania aplikacji NoSQL Redis
  • Projektowanie bazy danych NoSQL przy użyciu Redis
  • Ogólny przegląd Redis i .NET
  • Wersjonowanie bez schematu i migracje danych z klientem C# Redis

Nie ma magii – Redis to puste płótno

Najpierw chcę zaznaczyć, że używanie Redis jako magazynu danych zapewnia po prostu puste płótno i samo w sobie nie ma żadnej koncepcji powiązanych jednostek. tzn. po prostu zapewnia dostęp do rozproszonych struktur danych comp-sci. Sposób przechowywania relacji zależy ostatecznie od sterownika klienta (tj. ServiceStack C# Redis Client) lub dewelopera aplikacji przy użyciu operacji na prymitywnej strukturze danych Redis. Ponieważ wszystkie główne struktury danych są zaimplementowane w Redis, zasadniczo masz pełną swobodę w zakresie struktury i przechowywania danych.

Pomyśl, jak ustrukturyzowałbyś relacje w kodzie

Więc najlepszym sposobem na zastanowienie się, jak przechowywać rzeczy w Redis, jest całkowite zignorowanie tego, jak dane są przechowywane w tabeli RDBMS i zastanowienie się, jak są przechowywane w swoim kodzie, tj. za pomocą wbudowanych klas kolekcji C# w pamięci - które Redis odzwierciedla zachowanie ze swoimi strukturami danych po stronie serwera.

Pomimo braku koncepcji powiązanych podmiotów, wbudowany zestaw w Redis i Posortowany zestaw struktury danych zapewniają idealny sposób przechowywania indeksów. Np. Zestaw Redisa kolekcja przechowuje tylko maksymalnie 1 wystąpienie elementu. Oznacza to, że możesz bezpiecznie dodawać do niego elementy/klucze/identyfikatory i nie obchodzić go, czy element już istnieje, ponieważ wynik końcowy będzie taki sam, gdybyś go wywołał 1 lub 100 razy - tj. Jest idempotentny i ostatecznie tylko 1 element pozostaje przechowywany w zestaw. Tak więc częstym przypadkiem użycia jest przechowywanie grafu obiektów (zagregowanego katalogu głównego) to przechowywanie identyfikatorów jednostek podrzędnych (znanych również jako klucze obce) w zestawie za każdym razem, gdy zapisujesz model.

Wizualizacja danych

Aby uzyskać dobrą wizualizację sposobu przechowywania jednostek w Redis, zalecam zainstalowanie interfejsu administratora Redis, który działa dobrze z klientem C# Redis usługi ServiceStack, ponieważ używa poniższej konwencji nazewnictwa kluczy, aby zapewnić ładny widok hierarchiczny, grupując wpisane jednostki razem (pomimo wszystkich kluczy istniejących w tej samej globalnej przestrzeni kluczy).

Aby wyświetlić i edytować jednostkę, kliknij Edytuj link, aby zobaczyć i zmodyfikować wewnętrzną reprezentację JSON wybranej jednostki. Mamy nadzieję, że kiedy zobaczysz, jak są przechowywane, będziesz w stanie podejmować lepsze decyzje dotyczące projektowania modeli.

Jak przechowywane są POCO/Entity

Klient C# Redis współpracuje z dowolnymi POCO, które mają jeden klucz podstawowy — domyślnie oczekuje się, że będzie to Id (chociaż ta konwencja jest możliwa do zastąpienia w przypadku ModelConfig). Zasadniczo POCO są przechowywane w Redis jako serializowany JSON z typeof(Poco).Name i Id używany do tworzenia unikalnego klucza dla tej instancji. Np.:

urn:Poco:{Id} => '{"Id":1,"Foo":"Bar"}'

POCO w kliencie C# są konwencjonalnie serializowane przy użyciu szybkiego serializatora Json ServiceStack, w którym serializowane są tylko właściwości z publicznymi metodami pobierającymi (i publiczne ustawiające w celu przywrócenia z powrotem serializacji).

Domyślne ustawienia można nadpisać za pomocą [DataMember] attrs, ale nie jest to zalecane, ponieważ oczernia twoje POCO.

Elementy są blobowane

Więc wiedząc, że POCO w Redis są po prostu blobowane, chcesz tylko zachować niezagregowane dane główne na swoich POCO jako właściwości publiczne (chyba że celowo chcesz przechowywać nadmiarowe dane). Dobrą konwencją jest używanie metod do pobierania powiązanych danych (ponieważ nie zostaną one zserializowane), ale także informuje aplikację, które metody wykonują zdalne wywołania w celu odczytania danych.

Więc pytanie, czy Kanał powinny być przechowywane z użytkownikiem czy są to niezagregowane dane root, tj. czy chcesz uzyskać dostęp do kanałów użytkowników poza kontekstem użytkownika? Jeśli nie, pozostaw List<Feed> Feeds właściwość User typ.

Utrzymanie indeksów niestandardowych

Jeśli jednak chcesz, aby wszystkie kanały były dostępne niezależnie, np. za pomocą redisFeeds.GetById(1) wtedy będziesz chciał przechowywać go poza użytkownikiem i utrzymywać indeks łączący te 2 podmioty.

Jak zauważyłeś, istnieje wiele sposobów przechowywania relacji między podmiotami, a sposób, w jaki to robisz, jest w dużej mierze kwestią preferencji. Dla jednostki podrzędnej w rodzicu>dziecku związek, w którym zawsze chciałbyś przechowywać ParentId z podmiotem podrzędnym. W przypadku Rodzica możesz wybrać przechowywanie kolekcji ChildIds z modelem, a następnie wykonaj jednokrotne pobranie dla wszystkich jednostek podrzędnych, aby ponownie nawodnić model.

Innym sposobem jest utrzymanie indeksu poza nadrzędnym dto we własnym Zestawie dla każdej instancji nadrzędnej. Kilka dobrych przykładów tego jest w kodzie źródłowym C# demonstracji Redis StackOverflow, gdzie relacja Users > Questions i Users > Answers jest przechowywany w:

idx:user>q:{UserId} => [{QuestionId1},{QuestionId2},etc]
idx:user>a:{UserId} => [{AnswerId1},{AnswerId2},etc]

Chociaż C# RedisClient obejmuje obsługę domyślnej konwencji nadrzędnej/podrzędnej za pośrednictwem jej TParent.StoreRelatedEntities(), TParent.GetRelatedEntities<TChild>() i TParent.DeleteRelatedEntities() Interfejsy API, w których za kulisami utrzymywany jest indeks, który wygląda następująco:

ref:Question/Answer:{QuestionId} => [{answerIds},..]

W rzeczywistości są to tylko niektóre z możliwych opcji, w których istnieje wiele różnych sposobów osiągnięcia tego samego celu i w których masz również swobodę rozwijania własnych.

Wolności NoSQL bez schematów i luźnego pisania powinny zostać przyjęte i nie powinieneś się martwić próbą podążania za sztywną, predefiniowaną strukturą, którą możesz znać podczas korzystania z RDBMS.

Podsumowując, nie ma prawdziwego właściwego sposobu do przechowywania danych w Redis, m.in. Klient C# Redis przyjmuje pewne założenia, aby zapewnić wysokopoziomowy interfejs API wokół POCO i blobuje POCO w binarnych bezpiecznych wartościach ciągów Redis — chociaż inni klienci wolą zamiast tego przechowywać właściwości jednostek w skrótach Redis (słowniki) . Oba będą działać.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Klawisze sortowania Spring Redis

  2. Jak zapisać i pobrać ciąg z akcentami w redis?

  3. ConnectionMultiplexer.Connect przerywa się podczas łączenia z serwerem redis

  4. Jak ustawić limit czasu odczytu na kliencie redis węzła?

  5. Znajdowanie kluczy, które nie wygasają w Redis