栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

ServiceStack.Net Redis:存储相关对象与相关对象ID

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ServiceStack.Net Redis:存储相关对象与相关对象ID

与其重新散布大量的其他文档,我不如列出一些有关Redis + ServiceStack的Redis Client的背景信息:

  • 设计NoSQL Redis应用程序时的注意事项
  • 使用Redis设计NoSQL数据库
  • Redis和.NET的概述
  • 使用C#Redis Client进行无模式版本控制和数据迁移

没有魔法-Redis是一块空白画布

首先,我想指出的是,将Redis用作数据存储仅提供了一个空白画布,并且本身没有任何相关实体的概念。即,它仅提供对分布式comp-
sci数据结构的访问。通过使用Redis的原始数据结构操作,如何存储关系最终取决于客户端驱动程序(即ServiceStack C#Redis
Client)或应用程序开发人员。由于所有主要数据结构都是在Redis中实现的,因此您基本上可以完全自由地构造和存储数据。

想想如何在代码中构建关系

因此,考虑如何在Redis中存储内容的最好方法是完全不考虑数据在RDBMS表中的存储方式,而考虑数据在代码中的存储方式,即在内存中使用内置的C#集合类-
Redis通过其服务器端数据结构来反映行为。

尽管没有相关实体的概念,Redis的内置 SetSortedSet 数据结构还是存储索引的理想方法。例如,Redis的 Set
集合最多只能存储1个元素。这意味着您可以安全地向其中添加项目/键/标识,而不必关心该项目是否已经存在,因为如果您将其调用1或100次,最终结果将是相同的-
即它是幂等的,最终仅将1个元素保留在其中集合。因此,在存储对象图(聚合根)时,一个常见的用例是每次保存模型时将子实体ID(又称为外键)存储到Set中。

可视化您的数据

为了更好地可视化实体在Redis中的存储方式,我建议安装与ServiceStack的C#Redis Client配合使用的Redis Admin
UI,因为它使用下面的键命名约定提供了一个很好的层次结构视图,将键入的实体分组在一起(尽管所有键)存在于同一全局键空间中)。

要查看和编辑实体,请单击“ 编辑”
链接以查看和修改所选实体的内部JSON表示形式。希望一旦看到模型的存储方式,您将能够对如何设计模型做出更好的决策。

POCO /实体的存储方式

C#Redis客户端可与具有单个主键的任何POCO一起使用-
默认情况下应为主键

Id
(尽管此约定可通过ModelConfig覆盖)。本质上,POCO作为序列化JSON存储在Redis中,同时使用
typeof(Poco).Name
Id
来为该实例形成唯一密钥。例如:

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

C#客户端中的POCO通常使用ServiceStack的快速Json序列化器进行序列化,在序列化器中,仅对具有公共获取器的属性进行序列化(并通过公共获取器反序列化)。

默认值可以用

[DataMember]
attrs 覆盖,但不建议使用,因为它会使您的POCO变得丑陋。

实体被爆

因此,知道Redis中的POCO只是泛滥了,您只想将非聚合的根数据保留在POCO上作为公共属性(除非您有意存储冗余数据)。一个好的约定是使用方法来获取相关数据(因为它不会被序列化),但还告诉您的应用哪些方法进行了远程调用以读取数据。

因此,关于 Feed 是否应与 用户
一起存储的问题是,它是否是非聚合的根数据,即您是否要在用户上下文之外访问用户feed?如果否,则将

List<Feed>Feeds
属性保留在
User
类型上。

维护自定义索引

但是,如果您想保持所有提要独立访问,即使用,

redisFeeds.GetById(1)
则需要将其存储在用户外部并维护一个链接这两个实体的索引。

正如您已经注意到的,有很多方法可以存储实体之间的关系,并且如何存储很大程度上取决于偏好。对于 parent >
child
关系中的子实体,您总是希望将 ParentId 与该子实体一起存储。对于父级,您可以选择与模型一起存储 ChildId
的集合,然后对所有子实体进行一次提取以重新 补充 模型。

另一种方法是为每个父实例在其自己的 Set
中的父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进行了一些假设,以提供围绕POCO的高级API,并且在Redis的二进制安全字符串值中使POCO斑点化-
尽管还有其他方法客户将更喜欢将实体属性存储在Redis哈希(字典)中。两者都会起作用。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/411929.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号