*Redis SINTERSTORE 命令 计算交集并存储到新集合

*语法

SINTERSTORE destination key [key ...]
SINTERSTORE destination key [key ...] [LIMIT count]

*说明

计算给定的多个 Set 集合之间的交集(intersection set),并将结果存储到 destination 目标集合中。

如果 destination 已经存在,它会被覆盖(overwrite)。如果 destination 原本存储的不是 Set 类型,它会被强制替换为新的 Set。

数学定义:交集 = 同时存在于所有给定集合中的成员。

如果参与运算的任一 key 不存在,Redis 将其视为空集合,因此交集结果必然为空,destination 将被创建或清空为空集合。

*Redis 7.0 新特性:LIMIT 选项

Redis 7.0 开始,SINTERSTORE 也支持可选的 LIMIT 选项:

  • SINTERSTORE destination key1 ... keyN LIMIT count
  • 在交集计算过程中,当找到 count 个成员后就会停止,仅将最多 count 个成员存储到 destination
  • 这在大规模集合场景中可以减少内存和 CPU 消耗。

重要提示:SINTERSTORE 生成的结果集合中的成员顺序是不确定的(unspecified order)

*返回值

  • Integer:存储到 destination 集合中的成员数量。如果结果为空,则返回 0

*时间复杂度

  • O(N×M),其中 N 是最小集合的成员数量,M 是参与运算的集合数量。
  • 使用 LIMIT 时可提前终止,降低实际消耗。

*版本兼容性

Redis 版本 变更说明
>= 1.0.0 初始支持
>= 7.0.0 支持 LIMIT count 选项

*示例

*示例 1:将交集存储到新集合

SADD set_a "a" "b" "c" "d"
# 返回:(integer) 4

SADD set_b "b" "c" "e" "f"
# 返回:(integer) 4

# 将 A ∩ B 存储到 result
SINTERSTORE result set_a set_b
# 返回:(integer) 2

SMEMBERS result
# 返回:1) "b"  2) "c"(顺序随机)

*示例 2:覆盖已存在的 destination

# 预先创建一个字符串类型的 key
SET mydata "original string"
# 返回:OK

SADD tags:article1 "redis" "database"
# 返回:(integer) 2

SADD tags:article2 "redis" "cache"
# 返回:(integer) 2

# mydata 会被覆盖为 Set 类型
SINTERSTORE mydata tags:article1 tags:article2
# 返回:(integer) 1

TYPE mydata
# 返回:set

SMEMBERS mydata
# 返回:1) "redis"

*示例 3:多个集合的交集存储

SADD skills:alice "python" "redis" "docker"
# 返回:(integer) 3

SADD skills:bob "python" "redis" "kubernetes"
# 返回:(integer) 3

SADD skills:charlie "python" "redis" "docker"
# 返回:(integer) 3

# 三人的共同技能
SINTERSTORE common_skills skills:alice skills:bob skills:charlie
# 返回:(integer) 2

SMEMBERS common_skills
# 返回:1) "python"  2) "redis"(顺序随机)

*示例 4:空交集会清空 destination

SADD set1 "x" "y"
# 返回:(integer) 2

# 预先给 destination 填充数据
SADD dest "old_data"
# 返回:(integer) 1

# set2 不存在,交集为空,dest 被清空
SINTERSTORE dest set1 set2
# 返回:(integer) 0

SCARD dest
# 返回:(integer) 0

*相关命令