3

我目前有一个数据集,类似于:

通道 1 = 用户 1、用户 2、用户 3

频道 2 = 用户 4、用户 5、用户 6

注意-这些不是实际名称,文本不是可预测的序列

我希望对以下内容具有最优化的功能:

1) 将用户添加到频道

2) 从频道中删除用户

3)获取几个选定频道中所有用户的列表,保持对他们所在频道的了解(以防万一——这也可以简单地检查一个频道是否有任何用户,而无需获取他们的实际列表)

4)检测特定用户是否在频道中(如有必要愿意放弃此功能)

我对一次获得多个密钥的方法只有两种方式感到有点担心:

A) 使用常规密钥和 mget key1、key2、key3

  • 在这个解决方案中,每个值都是一个 JSON 字符串,然后可以在客户端对其进行操作和查询以添加/删除/确定值。这本身有几个问题 - 首先,另一个客户端可能会在处理数据时更改数据(即这个解决方案不是原子的),并且如果通道包含特定用户,即使很容易检测也不容易立即检测到检测频道是否有任何用户(这是低优先级,如上所述)

B) 使用 set 和 sunion

  • 我真的很想以某种方式为此解决方案使用集合,上面的解决方案似乎是错误的......但我看不到如何一次查询多个集合并维护有关每个成员来自哪个集合或是否有任何集合的信息union 有 0 个成员(sunion 只给了我所有组合成员的最后一组)

任何可以在最佳时间和原子操作中实现上述第 1-4 点的解决方案?

编辑:在我的特定情况下可能有用的一个想法是将频道名称存储为用户名的一部分,然后使用集合。不过,获得更通用的答案会很棒

4

1 回答 1

3

简短的回答:使用集合 + 流水线 + MULTI/EXEC,或集合 + Lua。

1) 将用户添加到频道

SADD命令

2) 从频道中删除用户

SREM命令

3) 获取多个选定频道中所有用户的列表

有几种方法可以做到这一点。

如果您不需要严格的原子性,则只需通过管道传输多个SMEMBERS命令即可在一次往返中检索所有集合。如果您只是对频道是否有用户感兴趣,您可以将 SMEMBERS 替换为SCARD

如果您需要严格的原子性,您可以流水线包含 SMEMBERS 或 SCARD 命令的 MULTI/EXEC 块。EXEC 命令的输出将包含所有结果。这是我推荐的解决方案。

另一种(原子)方法是使用EVAL命令调用服务器端 Lua 脚本。Lua 脚本执行总是原子的。该脚本可以将多个通道作为输入参数,并构建一个多层批量回复以返回输出。

4)检测特定用户是否在频道中

SISMEMBER命令 - 如果您需要检查多个用户,则将它们流水线化。

于 2013-09-30T17:50:38.053 回答