我希望将Redis用作复杂数据的缓存。考虑这个示例,我想存储和检索AssetType数据。一个AssetType可以具有多个AspectType。因此,AspectType本身是另一个实体。这些将有多对多的关系。
当我要将AssetType存储在缓存中时,我希望AspectType被存储在新的缓存中并以某种方式携带引用。因此,每个AssetType中都没有重复的AspectTypes。
基本上,结构应为:
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中有什么有效的方法吗?
最佳答案
在Redis中有许多有效的方法可以做到这一点。但是,您需要做出一些设计决策。
首先,您可以为每个AssetType拥有一个哈希类型的密钥,或者为所有AssetTypes拥有一个哈希。
每个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:*
遍历AssetTypes。所有资产类型的一个哈希值,序列化每个资产类型,例如使用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操作。
例如,这使您可以获得两个或更多资产类型的共同方面:
SINTER AspectsPerAsset:at1 AspectsPerAsset:at2 AspectsPerAsset:at3
请注意,到目前为止,我们已经建立了一对多关系。这是一个article on many-to-many。在这种情况下,您还将维护对每个方面对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
我试图为您说明一些模式。根据您的用例的具体情况,可能还有其他更好的方法。