【问题标题】:How to Model Complex Objects in Redis如何在 Redis 中为复杂对象建模
【发布时间】:2020-04-05 18:54:45
【问题描述】:

我希望将 Redis 用作复杂数据的缓存。考虑这个例子,我想存储和检索 AssetType 数据。一个 AssetType 可以有多个 AspectType。所以,AspectType 本身就是另一个实体。这些将具有多对多的关系。

当我想将 AssetType 存储在缓存中时,我希望将 AspectType 存储在新的缓存中并以某种方式携带引用。因此,每个 AssetType 中都没有存储 AspectType 的副本。 基本上,结构应该是:

Cache1: AssetType
key: at1, value: {at1, sameple description, [referenceTo-asp1, referenceTo-asp2]}
key: at2, value: {at2, sameple description, [referenceTo-asp2, referenceTo-asp3]}

Cache2: AspectType
key: asp1, value: {asp1, sample description}
key: asp2, value: {asp2, sample description}
key: asp3, value: {asp3, sample description}

当我使用 JPA 通过数据库进行操作时,这非常容易。但是,在 Redis 中是否有任何有效的方法来做到这一点?

【问题讨论】:

  • 难道不能宁愿使用像 H2 这样的内存数据库吗?然后你就可以使用你的工作 JPA 解决方案了。
  • (这不是一个直接的答案,因为它不在 Java 中......而且由于问题与 Java 无关,我相信您希望得到答案)如果您知道如何用 C 或 C++ 编写代码然后你可以创建一个简单的 Redis 模块(它看起来像一个简单的 30-60 分钟任务),它有一个包含所有 AspectType 的全局字典,然后在一个键中它将存储 AssetTypes 和指向 AspectTypes 的指针。您还可以修改 Redis 源以使用全局字符串字典(我认为他们试图做这样的事情,但最终决定不这样做),但同样,这需要您用 C 编写...

标签: java database spring-boot caching redis


【解决方案1】:

在 Redis 中有许多有效的方法可以做到这一点。不过,您需要做出一些设计决策。

首先,您可以为每个 AssetType 设置一个哈希类型的键,或者为所有 AssetType 设置一个哈希。

每个 AssetType 的键

HSET AssetType:at1 name at1 desc "sample description" aspects "asp1,asp2,asp3"
HSET AssetType:at2 name at2 desc "sample description" aspects "asp1,asp2"

您始终可以使用 SCAN 0 MATCH AssetType:* 循环访问您的 AssetType。

所有 AssetType 的一个哈希,序列化每个 AssetType,比如 JSON:

HSET AssetTypes at1 "{'name':'at1','desc':'sample description','aspects':['asp1','asp2','asp3']}"
HSET AssetTypes at2 "{'name':'at2','desc':'sample description','aspects':['asp1','asp2']}"

同样的决定也适用于 AspectTypes。这里的主要权衡是如果您可能想一次检索/更新一个项目的给定字段,或者您总是检索/更新整个项目。

然后,您使用引用的 AspectType id 来检索详细信息。

另一个设计决定是您是否将引用与主要项目一起存储,或者您将引用存储在单独的键中。例如,您可以使用集合来存储对方面的引用:

HSET AssetType:at1 name at1 desc "sample description"
SADD AspectsPerAsset:at1 asp1 asp2 asp3

集在这里很有帮助,因为它们只维护唯一的成员,从而简化了您的 CRUD 操作。

例如,这允许您获取两个或多个 AssetType 的共同方面:

SINTER AspectsPerAsset:at1 AspectsPerAsset:at2 AspectsPerAsset:at3

请注意,到目前为止,我们已经完成了一对多的关系。这是article on many-to-many。在这种情况下,您还需要根据 Aspect 维护对 AssetTypes 的引用:

HSET AssetType:at2 name at2 desc "sample description"
SADD AspectsPerAsset:at2 asp1 asp2
SADD AssetsPerAspect:asp1 at2
SADD AssetsPerAspect:asp2 at2

这使您可以获取给定 AspectType 的所有 AssetType,与 SINTER 共享几个方面的 AssetType,或者说具有一个或多个给定 AspectType 集合的 AssetType:

SUNION AssetsPerAspect:asp1 AssetsPerAspect:asp2 at2

我试图为您说明一些模式。根据您的用例的具体情况,可能还有其他更好的方法。

【讨论】:

    猜你喜欢
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 2014-03-26
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多