如何设计与 Redis 的 "Following" 关系
How to design "Following" relations with Redis
我正在尝试实现一个用户 A 关注用户 B 的场景,这样用户 A 的所有关注者也将关注用户 B。
例如:
假设我们有 4 个用户(users:1users:2users:3user:4)
->表示'following'
用户2->用户3,用户4
新动作:
用户 1-> 用户 2
我想将 user:2(又名 user:1)的所有关注者更新为关注用户 3 和用户 4:
预期结果
用户1->用户2,用户3,用户4
用户2->用户3,用户4
我需要所有用户都有这种行为
我开始思考我的解决方案。请让我知道如何实际适应它。
我正在使用键为 [unsername]_followers 的集合。
每次用户有新的关注者时,我都会检索他的关注者列表并逐个迭代代码,并通过向其中添加新用户来修改他们的列表。
问题开始变得有点复杂,因为我还需要更新关注者的关注者
代码:
requirement fact: if a follow b, b must follow a
//creating new users:
HMSET user:110 username rot
hMSET user:111 username jane
HMSET user:112 username kenny
//adding follow relations:
//user 110 started to follow user:111
sadd user:110_following user:111
sadd user:111_following user:110
//user 112 started to follow user:111
sadd user:111_following user:112
sadd user:112_following user:111
//update other "influenced" followers:
127.0.0.1:6379> smembers user:111_following
1) "user:111"
2) "user:110"
3) "user:112"
//need to update 110 (since 110 follows 111 which follow 112)
sadd user:110_following user:112
127.0.0.1:6379> smembers user:110_following
1) "user:111"
2) "user:110"
3) "user:112"
//need to update 112 (since now 110 also follows 112)
sadd user:112_following user:110
你怎么看这种方式?
谢谢,
雷.
毕竟你的做法是可以的。还是有一些问题:
- 不要在集合中存储
user:x
(其中 x
是用户 ID),而只存储 x
.
- 使用
:
分隔符:users:11:followers
.
- 也许您也应该创建一个排序集。我想您想按某种顺序列出关注者。存储在集合和排序集合中,以便能够进行集合操作,如交集和分页 (f.e。
zrange
)。
- 当您将数据存储在多个键中时,您应该使用
multi
命令以原子方式执行此操作。
- 也许您想存储 JSON 个对象,而不是将数据存储在许多散列中。例如:
hset users 1 { "userName": "Matias" }
而不是 hset users:11 username Matias
。由于您将使用 list
、set
和 sorted set
命令执行大部分操作,因此没有理由将每个用户 属性 存储在散列中。
- 而不是在您的应用程序层中检索所有关注者,why don't you use
sunionstore
?这样,如果您将用户 A 的关注者与用户 B 的关注者合并,并将结果存储在用户 B 的关注者中,因为它是一个 集 ,结果集将仅包含唯一的用户 ID。
我正在尝试实现一个用户 A 关注用户 B 的场景,这样用户 A 的所有关注者也将关注用户 B。
例如:
假设我们有 4 个用户(users:1users:2users:3user:4)
->表示'following'
用户2->用户3,用户4
新动作: 用户 1-> 用户 2
我想将 user:2(又名 user:1)的所有关注者更新为关注用户 3 和用户 4:
预期结果
用户1->用户2,用户3,用户4
用户2->用户3,用户4
我需要所有用户都有这种行为
我开始思考我的解决方案。请让我知道如何实际适应它。
我正在使用键为 [unsername]_followers 的集合。 每次用户有新的关注者时,我都会检索他的关注者列表并逐个迭代代码,并通过向其中添加新用户来修改他们的列表。
问题开始变得有点复杂,因为我还需要更新关注者的关注者
代码:
requirement fact: if a follow b, b must follow a
//creating new users:
HMSET user:110 username rot
hMSET user:111 username jane
HMSET user:112 username kenny
//adding follow relations:
//user 110 started to follow user:111
sadd user:110_following user:111
sadd user:111_following user:110
//user 112 started to follow user:111
sadd user:111_following user:112
sadd user:112_following user:111
//update other "influenced" followers:
127.0.0.1:6379> smembers user:111_following
1) "user:111"
2) "user:110"
3) "user:112"
//need to update 110 (since 110 follows 111 which follow 112)
sadd user:110_following user:112
127.0.0.1:6379> smembers user:110_following
1) "user:111"
2) "user:110"
3) "user:112"
//need to update 112 (since now 110 also follows 112)
sadd user:112_following user:110
你怎么看这种方式?
谢谢, 雷.
毕竟你的做法是可以的。还是有一些问题:
- 不要在集合中存储
user:x
(其中x
是用户 ID),而只存储x
. - 使用
:
分隔符:users:11:followers
. - 也许您也应该创建一个排序集。我想您想按某种顺序列出关注者。存储在集合和排序集合中,以便能够进行集合操作,如交集和分页 (f.e。
zrange
)。 - 当您将数据存储在多个键中时,您应该使用
multi
命令以原子方式执行此操作。 - 也许您想存储 JSON 个对象,而不是将数据存储在许多散列中。例如:
hset users 1 { "userName": "Matias" }
而不是hset users:11 username Matias
。由于您将使用list
、set
和sorted set
命令执行大部分操作,因此没有理由将每个用户 属性 存储在散列中。 - 而不是在您的应用程序层中检索所有关注者,why don't you use
sunionstore
?这样,如果您将用户 A 的关注者与用户 B 的关注者合并,并将结果存储在用户 B 的关注者中,因为它是一个 集 ,结果集将仅包含唯一的用户 ID。