Redis ⑦-set | Zset

set类型基本介绍
set 为集合,该集合为无序集合,可以存储多个不同的数据类型,包括字符串、整数、浮点数等。
集合中的元素是唯一的,不可重复。
set类型常用命令
SADD
SADD key member [member...]
- 集合中的值称为
member - 将一个或多个
member元素加入到集合key当中,已经存在于集合的member元素将被忽略。 - 返回成功添加的元素的数量。
SMEMEBRS
SMEMBERS key
- 返回集合
key中的所有成员。
SISMEMEBERS
SISMEMBER key member
- 判断
member是否是集合key的成员。 - 返回 1 表示
member是集合key的成员,返回 0 表示member不是集合key的成员。
SCARD
SCARD key
- 返回集合
key的基数(元素的数量)。
SPOP
SPOP key [count]
- 由于 set 中的元素是无序的,所以删除元素是随机的。
- 随机移除并返回集合
key中的一个元素,如果不写count参数,则随机移除并返回一个元素。否则随机移除并返回count个元素。
SRANDMEMBER
SRANDMEMBER key [count]
- 随机返回集合
key中的一个元素,如果不写count参数,则随机返回一个元素。否则随机返回count个元素。
SMOVE
SMOVE source destination member
- 将集合
source中的member元素移动到集合destination中。 - 如果
member元素不存在于source集合中,则不进行任何操作,返回 0。 - 如果
member元素已经存在于destination集合中,则不进行任何操作,返回 0。 - 如果
member元素成功地从source集合中移除并添加到destination集合中,则返回 1。
SREM
SREM key member [member...]
- 移除集合
key中的一个或多个member元素。 - 如果
member元素不存在于集合中,则忽略该元素。 - 返回被成功移除的元素的数量。
SINTER
SINTER key [key...]
- 交集:
A ∩ B = { x ∈ A ∣ x ∈ B } A \cap B = \{x \in A \mid x \in B\} A∩B={x∈A∣x∈B} - 返回给定所有集合的交集。
- 时间复杂度为 O(M * N),M 为所有给定集合中最小集合的元素数量,N 为所有给定集合中最大集合的元素数量。
SINTERSTORE
SINTERSTORE destination key [key...]
- 将所有给定集合的交集存储在集合
destination中。 - 如果
destination集合已经存在,则先移除该集合中的所有元素。 - 返回存储在
destination集合中的元素数量。
SUNION
SUNION key [key...]
- 并集:
A ∪ B = { x ∣ x ∈ A ∨ x ∈ B } A\cup B = \{x\mid x\in A \vee x\in B\} A∪B={x∣x∈A∨x∈B} - 返回给定所有集合的并集。
- 时间复杂度为 O(N),N 就是总的元素数量。
SUNIONSTORE
SUNIONSTORE destination key [key...]
- 将所有给定集合的并集存储在集合
destination中。 - 如果
destination集合已经存在,则先移除该集合中的所有元素。 - 返回存储在
destination集合中的元素数量。
SDIFF
SDIFF key [key...]
- 差集:
A − B = { x ∈ A ∣ x ∉ B } B − A = { x ∈ B ∣ x ∉ A } A - B = \{x \in A \mid x \notin B\} \\ B - A = \{x \in B \mid x \notin A\} A−B={x∈A∣x∈/B}B−A={x∈B∣x∈/A} - 返回给定所有集合的差集。
- 时间复杂度为 O(N),N 就是总的元素数量。
SDIFFSTORE
SDIFFSTORE destination key [key...]
- 将所有给定集合的差集存储在集合
destination中。 - 如果
destination集合已经存在,则先移除该集合中的所有元素。 - 返回存储在
destination集合中的元素数量。
set编码方式
- set 类型有两种编码方式:
intset和hashtable。 intset:当集合中元素都是整数并且元素数量较少时,Redis 会使用intset编码方式。hashtable:当集合中元素数量较多或者值不全为整数时,Redis 会使用hashtable编码方式。
set应用场景
- 保存用户一些 “标签”,也就是用户画像,如兴趣爱好、收藏的文章、喜欢的电影等。
- 利用 set 的交集功能,可以找到两个用户共同喜欢的电影、共同的好友等。
- 使用 set 统计
UV、PV等指标。UV就是user view的简写,即用户访问某个页面的次数。PV就是page view的简写,即某个页面的访问次数。
Zset类型基本介绍
Zset 为有序集合,该集合为有序集合,可以存储多个不同的数据类型,包括字符串、整数、浮点数等。
与 set,Zset 中的元素是按照顺序存放的,其通过存储 二元组<memeber, score>,随即按照 score 对元素进行升序排序(默认为升序)。
如果出现相同的 score,则按照 member 的字典序进行排序。
Zset 中的 member 必须是唯一的,不可重复,但是 score 可以重复。
Zset类型常用命令
ZADD
ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member...]
ZADD命令用于向有序集合key中添加元素。score是一个浮点数,用于对元素member进行排序。- 时间复杂度为
O(log(N)),其中 N 为有序集合元素的个数。 - 返回值为成功添加的元素的数量。只是新增元素的数量,如果是更新对应的
score值,则不会添加到计数中。 NX:只在元素的 score 值不存在时,才执行添加操作,否则添加失败。XX:只在元素的 score 值存在时,才执行添加操作,否则添加失败。GT:表示当更新的member的值已经存在并且设置的 新score大于已经存在的score时,才执行更新操作。如果member不存在,也不影响添加新的memeber。LT:当更新的member的值已经存在并且设置的 新score小于已经存在的score时,才执行更新操作。如果member不存在,也不影响添加新的memeber。CH:更改返回值的数量,如果设置为CH,则返回添加或更新元素的数量。默认是包括更新元素的数量的。INCR:将member的score加上score,返回值为新的score值。
ZRANGE
ZRANGE key start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count] [WITHSCORES]
- 返回有序集合
key中指定区间内的元素,区间以start和stop指定。默认是以下标(排序好了)进行获取。start和stop默认都是闭区间,若写成(start (stop表示都是开区间。 - 时间复杂度为
O(log(N)+M),其中 N 为有序集合元素的个数,M 为要返回的元素的个数。 REV:表示reverse,即按照降序进行排序,若score相同,则按照字典序进行降序排序。BYSCORE:表示按照score进行排序,start和stop写成对应的分数区间而不是下标区间。BYLEX:表示按照字典序进行排序,start和stop写成字母。其中,字母必须加上[或者(,如:[a [z。写成-和+表示获取所有元素,类似于默认的0和-1。LIMIT:限制返回元素的数量,offset表示偏移量,count表示数量。WITHSCORES:表示返回元素的所有信息,即包括score值。
ZREVRANGE、ZRANGEBYSCORE、ZREVRANGEBYSCORE、ZRANGEBYLEX、ZREVRANGEBYLEX
ZREVRANGE key start stop [WITHSCORES]
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
ZRANGEBYLEX key min max [LIMIT offset count]
ZREVRANGEBYLEX key max min [LIMIT offset count]
- 在 6.2.0 版本之后,这些命令都将被废弃,因为
ZRANGE命令可以实现相同的功能。
ZCARD
ZCARD key
- 返回有序集合
key中元素的数量。 - 时间复杂度为 O(1)。
ZCOUNT
ZCOUNT key min max
- 返回有序集合
key中指定分数区间[min, max]内元素的数量。 - 时间复杂度为 O(log(N))。
- 也可以写成
(min (max表示分数区间都为开区间。inf为无穷大,-inf为负无穷大。
ZPOPMAX
ZPOPMAX key [count]
- 移除并返回有序集合
key中分数最高的元素,如果不写count参数,则随机移除并返回一个元素。否则随机移除并返回count个元素。 - 时间复杂度为
O(log(N)M),其中 N 为有序集合元素的个数,M 为要返回的元素的个数。 - 实际上,该命令的时间复杂度可以优化为 O(log(N)),但是 Redis 并没有实现该优化,可能是因为优化之后提升的效率并不明显。
ZPOPMIN
ZPOPMIN key [count]
- 移除并返回有序集合
key中分数最低的元素,如果不写count参数,则随机移除并返回一个元素。否则随机移除并返回count个元素。 - 时间复杂度为
O(log(N)*M),其中 N 为有序集合元素的个数,M 为要返回的元素的个数。
BZPOPMAX、BZPOPMIN
BZPOPMAX key [key ...] timeout
BZPOPMIN key [key ...] timeout
- 阻塞式的
ZPOPMAX和ZPOPMIN,如果key中为空,则阻塞timeout时间后。在指定的时间内,如果有元素被添加到有序集合key中,则返回该元素。 - 如果没有元素被添加到有序集合
key中,则在指定的时间内一直阻塞,直到有元素被添加到有序集合key中。 - 时间复杂度为
O(log(N)),其中 N 为有序集合元素的个数。
ZRANK
ZRANK key member
- 返回有序集合
key中member元素的排名(从 0 开始),如果member不存在,则返回nil。 - 时间复杂度为
O(log(N))。
ZREVRANK
ZREVRANK key member
- 返回有序集合
key中member元素的排名(从 0 开始),但是反着算,因为reverse了。 - 时间复杂度为
O(log(N))。
ZSCORE
ZSCORE key member
- 返回有序集合
key中member元素的score值,如果member不存在,则返回nil。 - 时间复杂度为
O(log(1))。
ZREM
ZREM key member [member ...]
- 从有序集合
key中移除member元素,如果member不存在,则忽略。 - 返回被移除元素的数量。
- 时间复杂度为
O(M*log(N)),其中 M 参数中元素的个数,N 为有序集合元素的个数。
ZREMRANGEBYSCORE
ZREMRANGEBYSCORE key min max
- 从有序集合
key中移除score值在[min, max]区间内的元素。 - 返回被移除元素的数量。
- 时间复杂度为
O(log(N)+M),其中 N 为有序集合元素的个数,M 为移除的元素的个数。
ZREMRANGEBYLEX
ZREMRANGEBYLEX key min max
- 从有序集合
key中移除member值在[min, max]区间内的元素。 - 返回被移除元素的数量。
- 时间复杂度为
O(log(N)+M),其中 N 为有序集合元素的个数,M 为移除的元素的个数。
ZREMRANGEBYRANK
ZREMRANGEBYRANK key start stop
- 从有序集合
key中移除排名在[start, stop]区间内的元素。 - 返回被移除元素的数量。
- 时间复杂度为
O(log(N)+M),其中 N 为有序集合元素的个数,M 为移除的元素的个数。
ZINCYBY
ZINCRBY key increment member
- 将
member元素的score值增加increment,如果member不存在,则添加member元素并设置score为increment。 - 返回更新后的
member元素的score值。 - 时间复杂度为
O(log(N)),其中 N 为有序集合元素的个数。
ZINTER
ZINTER numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM | MIN | MAX] [WITHSCORES]
- 计算多个有序集合的交集,将计算后的结果返回
numkeys:表示需要计算交集的有序集合的个数。这里作用就有点像HTTP协议中的content-length。WEIGHTS:表示为相应的key设置权重,权重的个数必须与numkeys相等。此处指定的相当于一个系数,会乘以当前的score并返回。AGGREGATE:Zset的交集计算只是按照member进行的,所以会存在相同member但是score不同的情况,此时需要对结果进行聚合。SUM表示对score进行求和,MIN表示取最小的score,MAX表示取最大的score。WITHSCORES:表示返回结果中包含score值。- 时间复杂度为
O(N*K)+O(M*log(M)),其中 N 为所有有序集合中最小的那个,K 为需要计算交集的有序集合的个数,M 为结果集的元素个数。 - 实际上,时间复杂度可以近似看为
O(M*log(M))。
ZINTERSTORE
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight[weight ...]] [AGGREGATE <SUM | MIN | MAX>]
- 将多个有序集合的交集存储到新的有序集合
destination中。 - 如果
destination已存在,则会将其重写。 - 其他的与
ZINTER命令相同。 - 时间复杂度为
O(N*K)+O(M*log(M))。
ZUNION
ZUNION numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM | MIN | MAX] [WITHSCORES]
- 计算多个有序集合的并集,将计算后的结果返回。
- 与
ZINTER命令类似,只是计算的是并集。 - 时间复杂度为
O(N)+O(M*log(M)),其中 N 为所有有序集合元素数量的总和,M 为结果集的元素个数。 - 实际上,时间复杂度也可以近似看为
O(M*log(M))。
ZUNIONSTORE
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight[weight ...]] [AGGREGATE <SUM | MIN | MAX>]
- 将多个有序集合的并集存储到新的有序集合
destination中。 - 如果
destination已存在,则会将其重写。 - 其他的与
ZUNION命令相同。 - 时间复杂度为
O(N)+O(M*log(M))。
ZDIFF
ZDIFF numkeys key [key ...] [WITHSCORES]
- 计算多个有序集合的差集,将计算后的结果返回。
- 时间复杂度为
O(L + (N-K)log(N)),L 为所有有序集合的所有元素总和,N 为第一个有序集合的元素个数,K 为结果集的元素个数。
ZDIFFSTORE
ZDIFFSTORE destination numkeys key [key ...]
- 将多个有序集合的差集存储到新的有序集合
destination中。 - 如果
destination已存在,则会将其重写。 - 时间复杂度为
O(L + (N-K)log(N))。
Zset编码方式
Zset类型有两种编码方式:ziplist和skiplist。ziplist:当Zset中元素数量较少或者某个元素的长度超过一定的限制时,Redis 会使用ziplist编码方式。skiplist:跳表,就是一种复杂链表,查询元素的时间复杂度为O(log(N))。
Zset的应用场景
- 排行榜:比如,一个社交网站的用户排行榜,可以用
Zset实现。 - 热度排行榜通常由多种因素影响,比如浏览量、点赞数、评论数等,可以用 多个
Zset存储,然后用ZUNIONSTORE或者ZINTERSTORE并且指定不同的数值的权重(WEIGHTS),计算出一个综合的热度排行榜。
