在我写的应用程序中,用户可以执行各种社交操作。我将这些操作的结果保存在 Redis哈希中。
每个哈希的命名方案使用连接的user_ids
和对应的action_ids
。例如。 hash:11:99
可以是存储user_id
11和action_id
99结果的哈希值。在此方案下,检索任何用户执行的任何操作的结果都是O(1)进程(如果两者都是{已知{1}}和user_id
。
但接下来,我还需要查找用户在过去30分钟内执行的所有操作的所有结果(精确action_id
未知)。为此,我将action_id与时间戳一起存储在为每个用户指定的有序集合中。例如。对于action_ids
,sorted_set:1
可以包含action_ids
和timestamps
1。从这里开始,有一个多步骤流程可以让用户在之前的30个内执行所有操作分钟:
1)在用户的排序集中,使用user_id
查找与最近30分钟相关的ZREMRANGEBYSCORE
。时间复杂度O(log(N)+ M)
2)使用检索到的action_ids
,构造必须访问的哈希名称(即action_ids
)。
3)迭代每个哈希并检索所需的结果。时间复杂度O(n)
我的问题是:如何以比上述更好的性能满足上述要求?我可以重新想象使用哪种Redis数据类型。
答案 0 :(得分:1)
某些用例需要数据减少。
如果您需要在这些有序集合中存储部分数据而不仅仅是操作标识符,因为这将最终在比普通查找更短的时间内检索所需信息,Redis赢得了#39;是谁会告诉你不要这样做。 就这么做!
当我说部分数据时,我的意思是我猜你以其他一些序列化格式存储JSON序列化对象或数据。也许源对象有12个属性,但是当您需要某个用户在过去30分钟内完成的最新操作时,您只需要访问这12个属性中的4个。所以去吧!存储仅具有4个属性的序列化对象以及id
,以便能够在应用程序层中获取完整对象(如果需要)。
此外,冗余可能意味着您可以创建4个排序集,根据用例存储具有不同部分数据的最新操作的排名。一个案例需要3个属性,其他需要2个属性,但它们与第一个案例不同,依此类推......
只要认为Redis就是以非常有效的方式索引数据,以便轻而易举地访问数据。
AFAIK,关系数据库索引也是这样工作的。您可以使用许多列构建许多索引,并针对同一数据表创建所有可能的组合。使用Redis,您可以获得相同的行为和目标,因为您决定如何建模这些索引!