Spíše než předělávat spoustu další dokumentace, která je tam venku ve volné přírodě, uvedu jich pár pro nějaké základní informace o Redis Client Redis + ServiceStack:
- Na co myslet při navrhování aplikace NoSQL Redis
- Návrh databáze NoSQL pomocí Redis
- Obecný přehled Redis a .NET
- Verze bez schématu a migrace dat pomocí klienta C# Redis
Neexistuje žádná magie – Redis je prázdné plátno
Nejprve chci poukázat na to, že použití Redis jako úložiště dat poskytuje pouze prázdné plátno a samo o sobě nemá žádný koncept souvisejících entit. tj. poskytuje pouze přístup k distribuovaným datovým strukturám comp-sci. Jak se vztahy uloží, je v konečném důsledku na ovladači klienta (tj. ServiceStack C# Redis Client) nebo vývojáři aplikace pomocí operací primitivních datových struktur Redis. Vzhledem k tomu, že všechny hlavní datové struktury jsou implementovány v Redis, máte v zásadě úplnou svobodu v tom, jak chcete strukturovat a ukládat svá data.
Přemýšlejte, jak byste strukturovali vztahy v kódu
Takže nejlepší způsob, jak přemýšlet o tom, jak ukládat věci v Redis, je úplně ignorovat, jak jsou data uložena v tabulce RDBMS a přemýšlet o tom, jak jsou uložena ve vašem kódu, tj. pomocí vestavěných tříd kolekce C# v paměti - které Redis zrcadlí v chování s jejich datovými strukturami na straně serveru.
Přestože nemá koncept souvisejících entit, vestavěná Sada společnosti Redis a SortedSet datové struktury poskytují ideální způsob ukládání indexů. Např. Sada společnosti Redis kolekce ukládá maximálně 1 výskyt prvku. To znamená, že k ní můžete bezpečně přidávat položky/klíče/id a je vám jedno, zda položka již existuje, protože konečný výsledek bude stejný, kdybyste ji zavolali 1 nebo 100krát – tj. je idempotentní a nakonec zůstane uložen pouze 1 prvek. sada. Běžným případem použití při ukládání objektového grafu (kořen agregátu) je tedy uložení ID podřízených entit (aka cizí klíče) do sady pokaždé, když uložíte model.
Vizualizace vašich dat
Pro dobrou vizualizaci toho, jak jsou entity uloženy v Redis, doporučuji nainstalovat uživatelské uživatelské rozhraní Redis Admin, které dobře funguje s klientem C# Redis Client ServiceStack, protože používá níže uvedenou konvenci pojmenovávání klíčů, která poskytuje pěkný hierarchický pohled a seskupuje vaše zadané entity dohromady (navzdory všem klíčům existující ve stejném globálním klíčovém prostoru).
Chcete-li zobrazit a upravit entitu, klikněte na Upravit odkaz pro zobrazení a úpravu interní reprezentace JSON vybrané entity. Doufejme, že se budete moci lépe rozhodovat o tom, jak navrhovat své modely, jakmile uvidíte, jak jsou uloženy.
Jak jsou uloženy POCO / entity
C# Redis Client funguje se všemi POCO, které mají jeden primární klíč – což je ve výchozím nastavení očekáváno Id
(ačkoli tuto konvenci lze přepsat pomocí ModelConfig). V podstatě se POCO uloží do Redis jako serializovaný JSON s oběma typeof(Poco).Name
a Id
slouží k vytvoření jedinečného klíče pro tuto instanci. Např.:
urn:Poco:{Id} => '{"Id":1,"Foo":"Bar"}'
POCO v klientovi C# jsou konvenčně serializovány pomocí rychlého Serializeru Json ServiceStack, kde jsou serializovány pouze vlastnosti s veřejnými gettery (a veřejnými nastavovači, aby bylo možné získat zpět serializaci).
Výchozí hodnoty lze přepsat pomocí [DataMember]
attrs, ale nedoporučuje se, protože to oškliví vaše POCO.
Entity jsou blobovány
Takže s vědomím, že POCO v Redis jsou jen blobované, chcete na svých POCO uchovávat pouze neagregovaná kořenová data jako veřejné vlastnosti (pokud záměrně nechcete ukládat redundantní data). Dobrou konvencí je použít metody k načtení souvisejících dat (protože se nebudou serializovat), ale také sdělí aplikaci, které metody provádějí vzdálená volání pro čtení dat.
Takže otázka, zda Feed by měl být uložen u uživatele je, nebo nejde o neagregovaná kořenová data, tj. zda chcete nebo nechcete přistupovat ke zdrojům uživatelů mimo kontext uživatele? Pokud ne, opusťte List<Feed> Feeds
vlastnost na User
typ.
Údržba vlastních indexů
Pokud však chcete ponechat všechny zdroje přístupné nezávisle, tj. pomocí redisFeeds.GetById(1)
pak jej budete chtít uložit mimo uživatele a udržovat index spojující tyto 2 entity.
Jak jste si všimli, existuje mnoho způsobů, jak ukládat vztahy mezi entitami, a způsob, jakým to uděláte, je do značné míry otázkou preferencí. Pro podřízenou entitu v nadřazeném>podřízeném vztah, který byste vždy chtěli uložit ParentId s podřízenou entitou. Pro Rodič můžete buď zvolit uložení sbírky ChildIds s modelem a poté proveďte jediné načtení pro všechny podřízené entity, aby se model rehydratoval.
Dalším způsobem je udržovat index mimo nadřazený dto v jeho vlastní Sadě pro každou nadřazenou instanci. Některé dobré příklady toho jsou ve zdrojovém kódu C# ukázky Redis StackOverflow, kde je vztah Users > Questions
a Users > Answers
je uložen v:
idx:user>q:{UserId} => [{QuestionId1},{QuestionId2},etc]
idx:user>a:{UserId} => [{AnswerId1},{AnswerId2},etc]
Ačkoli C# RedisClient obsahuje podporu pro výchozí konvenci rodiče/dítě prostřednictvím svých TParent.StoreRelatedEntities(), TParent.GetRelatedEntities<TChild>()
a TParent.DeleteRelatedEntities()
Rozhraní API, kde je za scénou udržován index, který vypadá takto:
ref:Question/Answer:{QuestionId} => [{answerIds},..]
Ve skutečnosti jsou to jen některé z vašich možných možností, kde existuje mnoho různých způsobů, jak dosáhnout stejného cíle a ve kterých máte také svobodu hodit svůj vlastní.
Měli byste si osvojit svobodu NoSQL bez schémat a volného psaní a neměli byste se obávat, že se budete snažit dodržovat pevnou, předem definovanou strukturu, kterou možná znáte při používání RDBMS.
Závěrem lze říci, že neexistuje žádný skutečný správný způsob k ukládání dat v Redis, např. Klient C# Redis dělá určité předpoklady, aby poskytoval vysokoúrovňové API kolem POCO a blombuje POCO v binárně bezpečných hodnotách řetězců Redis – ačkoli existují jiní klienti, raději ukládají vlastnosti entit do Redis hash (slovníky) místo toho. . Obojí bude fungovat.