一. 集合对象概述
这里的集合是 string 类型的无序集合, 在集合对象中集合成员是唯一的, 这就意味着集合中不能出现重复的数据. 集合是通过哈希表实现的, 集合中最大的成员数为 232-1 (4294967295, 每个集合可存储 40 多亿个成员). 集合对象的编码可以是 intset 或者 hashtable.
1.1 intset 编码
intset 编码的集合对象使用整数集合作为底层实现, 集合对象包含的所有元素都被保存在整数集合里面. 例如下面使用整数集合:
- 127.0.0.1:6379> sadd numbers 1 3 5
- (integer) 3
- 127.0.0.1:6379> object encoding numbers
- "intset"
1.2 hashtable 编码
另一个编码是 hashtable, 集合对象使用字典作为底层实现, 字典的每个键都是一个字符串对象, 每个字符串对象包含了一个集合元素, 而字典的值则全部被设置为 null.
- 127.0.0.1:6379> sadd furits "apple" "banana"
- (integer) 2
- 127.0.0.1:6379> object encoding furits
- "hashtable"
两个底层结构如下图所示, 作为字典结构, 键都是一个字符串对象, 值都为 NULL.
1.3 编码转换
当集合对象可以同时满足以下两个条件时, 对象使用 intset 编码:(1) 集合对象保存的所有元素都是整数值;(2) 集合对象保存的元素数量不超过 512 个. 当不能满足这两个条件的集合对象使用的是 hashtable 编码. 对于第二个条件的上限值可以通过配置文件中的 set-max-intset-entries 选项来修改.
- 127.0.0.1:6379> config get set-max-intset-entries
- 1) "set-max-intset-entries"
- 2) "512"
二. 集合命令实现
-- Sadd 命令将一个或多个成员元素加入到集合中, 已经存在于集合的成员元素将被忽略.
- 127.0.0.1:6379> sadd myset "hello" "foo"
- (integer) 2
-- Scard 命令返回集合中元素的数量
- 127.0.0.1:6379> scard myset
- (integer) 2
-- Sdiff 命令返回给定集合之间的差集, 返回包含差集成员的列表. 下面是返回 myset1 对比 myset2, 返回 myset1 的差集.
- 127.0.0.1:6379> sadd myset1 "hello" "foo" "bar"
- (integer) 3
- 127.0.0.1:6379> sadd myset2 "hello" "world"
- (integer) 2
- 127.0.0.1:6379> sdiff myset1 myset2
- 1) "foo"
- 2) "bar"
-- Sdiffstore 命令将差集存储在指定的集合中, 如果指定的集合 (destination) key 已存在, 则会被覆盖, 下面集合 key 为 destset 不存在, 创建该新集合并且新集合值为二个集合的差集.
- .
- 127.0.0.1:6379> sdiffstore destset myset1 myset2
- (integer) 2
- 127.0.0.1:6379> smembers destset
- 1) "foo"
- 2) "bar"
-- Sinter 命令返回给定所有给定集合的交集, 与 Sdiff 相反. 下面返回 myset1 和 myset2 二个集合共同有的值.
- 127.0.0.1:6379> sinter myset1 myset2
- 1) "hello"
-- Sinterstore 命令将给定集合之间的交集存储在指定的集合中. 如果指定的集合已经存在, 则将其覆盖, 与 Sdiffstore 相反. 下面集合 key 为 destset2 不存在, 创建该新集合并且新集合值为二个集合的交集.
- 127.0.0.1:6379> sinterstore destest2 myset1 myset2
- (integer) 1
- 127.0.0.1:6379> smembers destest2
- 1) "hello"
-- Sismember 命令判断成员元素是否是集合的成员. 如果成员元素是集合的成员, 返回 1.
- 127.0.0.1:6379> sismember myset1 "hello"
- (integer) 1
-- Smembers 命令返回集合中的所有的成员. 不存在的集合 key 被视为空集合.
- 127.0.0.1:6379> smembers myset1
- 1) "hello"
- 2) "bar"
- 3) "foo"
-- Smove 命令将指定成员 member 元素从 source 集合移动到 destination 集合, SMOVE 是原子性操作.
- 127.0.0.1:6379> smembers myset1
- 1) "hello"
- 2) "bar"
- 3) "foo"
- 127.0.0.1:6379> smembers myset2
- 1) "hello"
- 2) "world"
127.0.0.1:6379> smove myset1 myset2 "bar" -- 将 myset1 的元素移到 myset2 中
(integer) 1
127.0.0.1:6379> smembers myset1 -- myset1 中少了 "bar" 元素
- ) "hello"
- ) "foo"
127.0.0.1:6379> smembers myset2 --myset2 中多了 "bar" 元素
- ) "hello"
- ) "world"
- ) "bar"
--Spop 命令用于随机移除指定 count 元素数量, 并返回集合中的移出的元素.
- 127.0.0.1:6379> smembers myset1
- 1) "three"
- 2) "one"
- 3) "hello"
- 4) "two"
127.0.0.1:6379> spop myset1 3 -- 随机移除 3 个
- ) "hello"
- ) "two"
- ) "three"
127.0.0.1:6379> smembers myset1 -- 只剩下一个元素
1) "one"
--Srem 命令用于移除集合中的一个或多个成员元素, 不存在的成员元素会被忽略.
- 127.0.0.1:6379> smembers myset1
- 1) "three"
- 2) "one"
- 3) "two"
127.0.0.1:6379> srem myset1 "one" -- 移除指定元素
(integer) 1
127.0.0.1:6379> smembers myset1 -- 只剩下二个元素
- ) "three"
- ) "two"
--Sunion 命令返回给定集合的并集, 相当于 sql 中的 join 合并去重.
- 127.0.0.1:6379> smembers myset2
- 1) "one"
- 2) "two"
- 127.0.0.1:6379> smembers myset1
- 1) "three"
- 2) "two"
127.0.0.1:6379> sunion myset2 myset1 -- 返回合并后的元素
- ) "three"
- ) "one"
- ) "two"
-- Sunionstore 命令将给定集合的并集, 存储在指定的集合 destination 中.
- 127.0.0.1:6379> sunionstore myset myset2 myset1
- (integer) 3
127.0.0.1:6379> smembers myset -- 并集后, 存储到了 myset 集合中
- ) "three"
- ) "one"
- ) "two
-- Sscan 命令用于迭代集合键中的元素
- 127.0.0.1:6379> smembers myset
- 1) "three"
- 2) "one"
- 3) "two"
- 127.0.0.1:6379> sscan myset 0 match t*
- 1) "0"
- 2) 1) "three"
- 2) "two"
来源: https://www.cnblogs.com/MrHSR/p/9981706.html