Redis
 sql >> база данни >  >> NoSQL >> Redis

ServiceStack.Net Redis:Съхранение на свързани обекти срещу идентификатори на свързани обекти

Вместо да прехешвам много друга документация, която е там в дивата природа, ще изброя няколко за основна информация около Redis Client на Redis + ServiceStack:

  • За какво да мислите, когато проектирате приложение NoSQL Redis
  • Проектиране на NoSQL база данни с помощта на Redis
  • Общ преглед на Redis и .NET
  • Безсхемни версии и миграции на данни с C# Redis клиент

Няма магия - Redis е празно платно

Първо искам да отбележа, че използването на Redis като хранилище за данни просто осигурява празно платно и няма никаква концепция за свързани обекти. т.е. той просто осигурява достъп до разпределени структури от Comp-Sci данни. Как се съхраняват връзките в крайна сметка зависи от драйвера на клиента (т.е. ServiceStack C# Redis Client) или от разработчика на приложение, като се използват операциите на примитивната структура на данните на Redis. Тъй като всички основни структури от данни са внедрени в Redis, вие по принцип имате пълна свобода за това как искате да структурирате и съхранявате данните си.

Помислете как бихте структурирали връзките в кода

Така че най-добрият начин да помислите как да съхранявате неща в Redis, е напълно да пренебрегнете как данните се съхраняват в RDBMS таблица и да помислите как се съхраняват във вашия код, т.е. да използвате вградените C# класове за колекция в паметта - които Redis отразява в поведението си със своите структури от данни от страна на сървъра.

Въпреки че няма концепция за свързани обекти, вграденият набор на Redis и SortedSet структурите от данни осигуряват идеалния начин за съхранение на индекси. напр. Комплект на Redis колекцията съхранява само максимум 1 поява на елемент. Това означава, че можете безопасно да добавяте елементи/ключове/идентификатори към него и да не ви пука дали елементът вече съществува, тъй като крайният резултат ще бъде същият, ако го извикате 1 или 100 пъти - т.е. той е идемпотентен и в крайна сметка само 1 елемент остава съхранен в комплектът. Така че често срещаният случай на употреба е, когато съхраняването на графика на обект (агрегиран корен) е да съхранявате идентификаторите на дъщерни обекти (известни още като външни ключове) в набор всеки път, когато запазвате модела.

Визуализация на вашите данни

За добра визуализация на това как обектите се съхраняват в Redis, препоръчвам да инсталирате Redis Admin UI, който работи добре с C# Redis Client на ServiceStack, тъй като използва конвенцията за именуване на ключове по-долу, за да осигури приятен йерархичен изглед, групиращ въведените от вас обекти заедно (въпреки всички ключове съществуващи в същото глобално ключово пространство).

За да видите и редактирате обект, щракнете върху Редактиране връзка, за да видите и промените вътрешното JSON представяне на избрания обект. Надяваме се, че ще можете да вземете по-добри решения за това как да проектирате своите модели, след като можете да видите как се съхраняват.

Как се съхраняват POCO/обектите

C# Redis Client работи с всички POCO, които имат един първичен ключ - който по подразбиране се очаква да бъде Id (въпреки че тази конвенция може да бъде отменена с ModelConfig). По същество POCO се съхраняват в Redis като сериализиран JSON с двата typeof(Poco).Name и Id се използва за формиране на уникален ключ за този екземпляр. Напр.:

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

POCO в C# Client са конвенционално сериализирани с помощта на бързия Json Serializer на ServiceStack, където се сериализират само свойства с публични гейтери (и публични сетери за обратно десериализиране).

Настройките по подразбиране могат да се отменят с [DataMember] attrs, но не се препоръчва, тъй като унищожава вашите POCO.

Обектите са blobbed

Така че, знаейки, че POCO в Redis са просто blobbed, вие искате само да запазите неагрегирани root данни на вашите POCO като публични свойства (освен ако не искате нарочно да съхранявате излишни данни). Добра конвенция е да се използват методи за извличане на свързаните данни (тъй като няма да се сериализират), но също така казва на приложението ви кои методи извършват отдалечени повиквания за четене на данни.

Така че въпросът за това дали Feed трябва да се съхранява при Потребителя дали това са неагрегирани основни данни, т.е. дали искате да получите достъп до потребителските емисии извън контекста на потребителя? Ако не, оставете List<Feed> Feeds свойство на User тип.

Поддържане на персонализирани индекси

Ако обаче искате да запазите всички емисии достъпни независимо, т.е. с redisFeeds.GetById(1) тогава ще искате да го съхраните извън потребителя и да поддържате индекс, свързващ 2-те субекта.

Както забелязахте, има много начини за съхраняване на връзки между обекти и как го правите до голяма степен е въпрос на предпочитание. За дъщерния обект вродител>дете връзка, която винаги бихте искали да съхранявате ParentId с дъщерната единица. За родителя можете да изберете да съхранявате колекция от ChildIds с модела и след това направете еднократно извличане за всички дъщерни обекти, за да хидратирате отново модела.

Друг начин е да поддържате индекса извън родителския dto в неговия собствен набор за всеки родителски екземпляр. Някои добри примери за това са в изходния код на C# на демонстрацията на Redis StackOverflow, където връзката на Users > Questions и Users > Answers се съхранява в:

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

Въпреки че C# RedisClient включва поддръжка за конвенция за родител/дете по подразбиране чрез своите TParent.StoreRelatedEntities(), TParent.GetRelatedEntities<TChild>() и TParent.DeleteRelatedEntities() API, където се поддържа индекс зад сцената, който изглежда така:

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

Всъщност това са само някои от възможните ви опции, при които има много различни начини за постигане на една и съща цел и в които също имате свободата да приложите своите.

Трябва да се приемат свободите на NoSQL без схема и свободно въвеждане и не трябва да се притеснявате да се опитвате да следвате твърда, предварително дефинирана структура, с която може да сте запознати, когато използвате RDBMS.

В заключение, няма истинскиправилен път за съхраняване на данни в Redis, напр. C# Redis Client прави някои предположения, за да предостави API на високо ниво около POCO и blobs на POCO в бинарно-безопасните стойности на низове на Redis - въпреки че има други клиенти, които предпочитат да съхраняват свойства на обекти в Redis хешове (речници) вместо това . И двете ще работят.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Как да задам парола за Redis?

  2. Redis connect ECONNREFUSED 127.0.0.1:6379

  3. Джедаите Променят ли семантиката на Redis?

  4. има ли начин да получа IP на клиента в redis?

  5. Получавам дублиращи се съобщения в моето клъстерирано приложение node.js/socket.io/redis pub/sub