Redis SINTERCARD 命令详细教程SINTERCARD返回多个集合交集的成员数量而不返回成员本身。它是 Redis 7.0.0 新增的命令专为只关心交集大小的场景设计省去把全部交集成员传输到客户端的开销并支持LIMIT参数在达到阈值后立即停止计算。判断两人是否有共同好友商品是否满足全部筛选条件时用它比 SINTER 更省资源。资料合集https://pan.quark.cn/s/10e98d308913、https://pan.quark.cn/s/f56bc69c5338一、概览与语法SINTERCARD numkeys key [key ...] [LIMIT limit]项目说明数据类型Set支持版本Redis 7.0.0 起numkeys必填参与运算的集合个数必须与实际提供的 Key 数量一致key参与求交的集合 Key数量由 numkeys 指定LIMIT limit可选默认 0 表示不限制大于 0 时达到该数量即停止计算并返回 limit返回值整数交集的成员数量时间复杂度O(N×M) 最坏情况N 为最小集合成员数M 为集合个数带 LIMIT 时可提前终止ACLread、set、slow命令标记readonly官方说明返回指定集合交集的基数。不存在的 Key 被视为空集合可选的 LIMIT 参数指定计算的上限达到上限即返回默认值 0 表示不限制。$TRAE_REFnumkeys是 Redis 7.0 一批可变参数命令如 ZINTERCARD、LMPOP、ZMPOP的统一设计先用一个整数声明后面跟几个 Key再由服务端校验数量。二、基础示例以下命令在测试实例的 redis-cli 中执行。文中结果是预期说明未实际连接 Redis 运行。示例沿用官方文档的数据与结果。DEL tutorial:{sintercard}:key1 tutorial:{sintercard}:key2 SADD tutorial:{sintercard}:key1 a b c d SADD tutorial:{sintercard}:key2 a c d e SINTERCARD 2 tutorial:{sintercard}:key1 tutorial:{sintercard}:key2 SINTERCARD 2 tutorial:{sintercard}:key1 tutorial:{sintercard}:key2 LIMIT 2预期结果两条 SADD 各返回4第一条 SINTERCARD 返回(integer) 3交集为 a、c、d第二条带LIMIT 2返回(integer) 2因为数到第 2 个交集成员就提前终止。三、LIMIT 的语义这是 SINTERCARD 相对 SINTER 最核心的价值也是最容易误解的地方LIMIT 0默认不限制返回完整交集基数。LIMIT nn 0最多数到 n 就停返回值为min(真实交集大小, n)。LIMIT为负数报错不会当作不限制。因此LIMIT n返回n只能说明交集至少有 n 个不能说明恰好有 n 个。业务上常用于是否存在至少 n 个共同点的布尔判断返回 n 即条件成立返回小于 n 即条件不成立。SINTERCARD 2 tutorial:{sintercard}:key1 tutorial:{sintercard}:key2 LIMIT 1 SINTERCARD 2 tutorial:{sintercard}:key1 tutorial:{sintercard}:key2 LIMIT 10预期结果LIMIT 1返回1交集至少 1 个实际是 3 个LIMIT 10返回3阈值大于真实交集返回完整数量。四、numkeys 的校验numkeys必须与实际 Key 数量严格一致否则报错情形结果numkeys 与实际 Key 数一致正常执行numkeys 小于实际 Key 数多余的参数会被当作语法错误处理numkeys 大于实际 Key 数报错提示 Key 数量不足numkeys 为 0 或负数报错必须是正整数numkeys 不是整数报ERR value is not an integer or out of rangeSINTERCARD 2 tutorial:{sintercard}:key1 SINTERCARD 0 tutorial:{sintercard}:key1预期结果第一条声明 2 个 Key 却只给了 1 个报参数数量错误第二条 numkeys 为 0报 numkeys 必须大于 0 的错误。五、不存在的 Key 与空结果场景返回所有 Key 都存在且有交集交集成员数量正整数任一 Key 不存在0不存在的集合视为空集所有 Key 都存在但无公共成员0SINTERCARD 2 tutorial:{sintercard}:key1 tutorial:{sintercard}:nokey预期结果返回0。与 SINTER 一致任一 Key 不存在即交集为空——这与差集 SDIFF 的后续 Key 不存在不影响结果形成鲜明对比。六、边界情况与错误处理场景行为缺少 numkeys报语法错误numkeys 与实际 Key 数不符报参数数量错误LIMIT 为负数报LIMIT cant be negativeLIMIT 不是整数报ERR value is not an integer or out of range任一 Key 类型不是 Set报 WRONGTYPE只传一个 Keynumkeys 1返回该集合的基数SET tutorial:{sintercard}:str text SINTERCARD 2 tutorial:{sintercard}:key1 tutorial:{sintercard}:str SINTERCARD 2 tutorial:{sintercard}:key1 tutorial:{sintercard}:key2 LIMIT -1预期结果第一条因 str 是 String 类型报 WRONGTYPE第二条因 LIMIT 为负报LIMIT cant be negative。七、与相近命令的区别命令返回是否传输成员LIMIT 支持版本SINTERCARD交集数量否是7.0.0SINTER交集成员数组是否1.0.0SINTERSTORE写入目标后返回数量否写服务端否1.0.0SUNION并集成员是否1.0.0SDIFF差集成员是否1.0.0ZINTERCARD有序集合交集数量否是7.0.0选择规则很清楚只关心有多少或是否达到阈值用 SINTERCARD需要成员内容用 SINTER需要成员在服务端长期保留用 SINTERSTORE。SINTERCARD 与 ZINTERCARD 是同一设计的集合版与有序集合版参数结构一致numkeys keys LIMIT但 ZINTERCARD 不支持 WEIGHTS/AGGREGATE。八、客户端示例前提为 redis-py 版本支持 SINTERCARD7.0 及以上服务端。redis-py 提供sintercard(keys, limit0)。importredis rredis.Redis(hostlocalhost,port6379,decode_responsesTrue)k1tutorial:{sintercard}:py1k2tutorial:{sintercard}:py2try:r.delete(k1,k2)r.sadd(k1,a,b,c,d)r.sadd(k2,a,c,d,e)print(r.sintercard([k1,k2]))# 3print(r.sintercard([k1,k2],2))# 2达到 LIMIT 提前终止print(r.sintercard([k1],0))# 4单集合即自身基数print(r.sintercard([k1,no-such]))# 0finally:r.delete(k1,k2)r.close()JavaJedis 5.x示例sintercard(keys...)与sintercard(limit, keys...)返回long。Jedis 会自动计算 numkeys不需要手动传入try(JedisjedisnewJedis(localhost,6379)){Stringk1tutorial:{sintercard}:java1;Stringk2tutorial:{sintercard}:java2;jedis.del(k1,k2);jedis.sadd(k1,a,b,c,d);jedis.sadd(k2,a,c,d,e);System.out.println(jedis.sintercard(k1,k2));// 3System.out.println(jedis.sintercard(2,k1,k2));// 2limit2 提前终止jedis.del(k1,k2);}注意sintercard(2, k1, k2)中的 2 是limit 而不是 numkeys这是 Jedis 与原始命令参数顺序上的差异容易写错。Jedis 较早版本4.x 及之前没有该方法需升级到 5.x 或自行用sendCommand发送原始命令。九、原子性与并发只读且原子SINTERCARD 不修改数据单命令原子返回执行瞬间的计数快照。计数是精确值结果没有误差与 SINTER 返回数组的长度一致未设 LIMIT 时。这与 PFCOUNT 的近似基数不同。LIMIT 与并发带 LIMIT 时返回n只代表至少 n 个集合在并发写入下随时可能变化不要把该结果当作稳定不变的精确值缓存。事务与 Pipeline可在 MULTI/EXEC、Lua 脚本和管道中正常使用。集群限制Redis Cluster 中所有参与运算的 Key 必须落在同一哈希槽否则报 CROSSSLOT。十、性能与使用注意事项省的是带宽而非计算SINTERCARD 与 SINTER 的复杂度同为 O(N×M)差别在于不把成员序列化并传回客户端。交集很大时节省的网络与内存开销非常显著。LIMIT 才是真正的提速手段达到阈值即停止遍历能把判断是否存在共同点从全量扫描降为常数级。判断是否有共同好友时LIMIT 1是标准写法。仍然可能阻塞不带 LIMIT 的大集合求交依旧带slow标记。必要时在副本执行或先做数据分片。不能替代读成员SINTERCARD 只返回数量。后续需要用成员时仍需 SINTER 或 SINTERSTORE。十一、典型业务场景共同好友数量SINTERCARD 2 user:{a}:friends user:{b}:friends直接得到共同好友数不必取回全部集合再求长度。若只需判断有没有共同好友加LIMIT 1。多条件筛选取量商品颜色、尺寸、品牌三个集合求交的基数用于展示当前筛选条件下共 N 件商品避免传输大量 ID。权限覆盖率判断用户角色集合与所需角色集合的交集数量是否达到要求用 LIMIT 做快速判定。推荐去重计数候选集合与已曝光集合的交集数量用于评估推荐重复率。风控同时命中规则数多个规则集合的交集大小作为风险评分输入。
阅读完成 · 觉得有帮助?