Redis基于二级索引设计数据结构
Redis design data structure based on secondary indices
假设我必须在缓存中存储以下对象-
{
student_id: "student123",
school_id: "xyz123",
class_id: "class123"
}
如何设计我的 Redis 数据结构,使我可以通过任何 ID 检索对象?
我尝试执行 HSET
命令:HSET student123 school_id xyz123 class_id class123
但这会为特定的 student_id 创建哈希。我还想确保搜索在 O(1) 中。提前致谢!
澄清一下,如果我必须按 school_id 进行搜索,我该怎么做?
您需要使用多个键索引才能在查询中获得 O(1)。
也考虑使用其他数据结构。看看Secondary indexing with Redis, how to have relations many to many in redis and this other article on many to many.
比如,使用 sets,您将 {student123, xyz456, class789} 条目添加为:
SADD student:student123 "xyz456 class789"
SADD school:xyz456 "student123 class789"
SADD class:class789 "xyz456 student123"
你可能会想"this will increase my memory usage a lot"。确实如此。这是内存和处理之间的通常折衷。关系数据库在创建索引时也会这样做。但是 Redis 会给你亚毫秒级的性能,Redis 使用多种技巧来优化内存使用,比如 ziplists, see https://redis.io/topics/memory-optimization.
哪种数据结构的最佳组合取决于您的用例的具体情况。
如果键中的前缀是常量,请考虑删除它们,只要它们在值中的顺序保持一致即可。
SADD student:123 "456 789"
请记住,集和排序集只允许唯一成员。如果您为使用学生 ID 作为分数的学生使用一个排序集:ZADD students 123 "456 789"
,然后在同一所学校添加另一个学生-class 和 ZADD students 235 "456 789"
这实际上更新了 [=14] 的分数=], 它没有添加新值。
假设我必须在缓存中存储以下对象-
{
student_id: "student123",
school_id: "xyz123",
class_id: "class123"
}
如何设计我的 Redis 数据结构,使我可以通过任何 ID 检索对象?
我尝试执行 HSET
命令:HSET student123 school_id xyz123 class_id class123
但这会为特定的 student_id 创建哈希。我还想确保搜索在 O(1) 中。提前致谢!
澄清一下,如果我必须按 school_id 进行搜索,我该怎么做?
您需要使用多个键索引才能在查询中获得 O(1)。
也考虑使用其他数据结构。看看Secondary indexing with Redis, how to have relations many to many in redis and this other article on many to many.
比如,使用 sets,您将 {student123, xyz456, class789} 条目添加为:
SADD student:student123 "xyz456 class789"
SADD school:xyz456 "student123 class789"
SADD class:class789 "xyz456 student123"
你可能会想"this will increase my memory usage a lot"。确实如此。这是内存和处理之间的通常折衷。关系数据库在创建索引时也会这样做。但是 Redis 会给你亚毫秒级的性能,Redis 使用多种技巧来优化内存使用,比如 ziplists, see https://redis.io/topics/memory-optimization.
哪种数据结构的最佳组合取决于您的用例的具体情况。
如果键中的前缀是常量,请考虑删除它们,只要它们在值中的顺序保持一致即可。
SADD student:123 "456 789"
请记住,集和排序集只允许唯一成员。如果您为使用学生 ID 作为分数的学生使用一个排序集:ZADD students 123 "456 789"
,然后在同一所学校添加另一个学生-class 和 ZADD students 235 "456 789"
这实际上更新了 [=14] 的分数=], 它没有添加新值。