在我正在编写的应用程序中,用户可以执行各种社交操作。我将这些操作的结果保存在 Redis 哈希 中。
每个散列的命名方案采用串联的 user_ids
和相应的 action_ids
。例如。 hash:11:99
可以是 user_id
11 和 action_id
99 的哈希存储结果。在这种方案下,检索执行的任何操作的结果任何用户都是 O(1) 进程(如果 user_id
和 action_id
已知)。
但接下来,我还需要查找用户在过去 30 分钟内执行的所有操作的所有结果(精确的 action_ids
未知)。为此,我将 action_id 和时间戳一起存储在为每个用户指定的排序集中。例如。 sorted_set:1
可以包含 action_ids
和 timestamps
for user_id
1. 从这里开始,有一个多步骤过程来获取用户在过去 30 分钟内执行的所有操作:
1) 在用户的排序集中,使用 ZREMRANGEBYSCORE
查找与过去 30 分钟相关的 action_ids
。时间复杂度O(log(N)+M)
2) 使用检索到的action_ids
,构造必须访问的哈希名称(即hash:user_id:action_id
)。
3) 遍历每个散列并检索所需的结果。时间复杂度O(n)
我的问题是:我怎样才能以比上面更好的性能满足上面的要求?我愿意重新设想要使用的 Redis 数据类型。
最佳答案
一些用例需要数据冗余。
如果您需要将部分数据存储在这些已排序的集合中,而不仅仅是操作标识符,因为这最终会在比普通查找更短的时间内检索所需的信息,Redis 将不会谁会告诉你不要这样做。 就去做吧!
当我说部分数据时,我的意思是我猜您正在存储 JSON 序列化对象或其他一些序列化格式的数据。也许源对象有 12 个属性,但是当您需要某个用户在过去 30 分钟内完成的最新操作时,您只需要访问这 12 个属性中的 4 个。所以去吧!存储一个仅包含 4 个属性和 id
的序列化对象,以便能够在应用程序层中获取完整对象(如果需要)。
此外,冗余可能意味着您可以创建 4 个排序集,根据用例使用不同的部分数据存储最新操作的排名。一种情况需要 3 个属性,另一种情况需要 2 个属性,但它们与第一种情况不同,依此类推...
只要想一想,Redis 就是以一种非常有效的方式为数据编制索引,以便轻松访问数据。
据我所知,关系数据库索引也是这样工作的。您可以针对同一数据表构建具有多个列和所有可能组合的多个索引。使用 Redis,您可以按照自己的方式获得相同的行为和目标,因为您决定如何对这些索引建模!
关于redis - 使用正确的 Redis 数据类型进行基于时间的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39956798/