当前位置: 首页 > news >正文

Redis:set类型和zset类型

🌈 个人主页:Zfox_
🔥 系列专栏:Redis

🔥 Set集合

集合类型也是保存多个字符串类型的元素的,但和列表类型不同的是,集合中1)元素之间是⽆序的2)元素不允许重复,如图2-24所⽰。⼀个集合中最多可以存储 个元素。Redis除了⽀持集合内的增删查改操作,同时还⽀持多个集合取交集、并集、差集,合理地使⽤好集合类型,能在实际开发中解决很多问题。

图2-24集合类型

在这里插入图片描述

🔥 普通命令

🦋 SADD

将⼀个或者多个元素添加到set中。注意,重复的元素⽆法添加到set中。

语法:

SADD key member [member ...]

命令有效版本:1.0.0之后
时间复杂度:O(1)
返回值:本次添加成功的元素个数。
⽰例:

redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SADD myset "World"
(integer) 0
redis> SMEMBERS myset
1) "Hello"
2) "World"

🦋 SMEMBERS

获取⼀个set中的所有元素,注意,元素间的顺序是⽆序的。
语法:

SMEMBERS key

命令有效版本:1.0.0之后
时间复杂度:O(N)
返回值:所有元素的列表。
⽰例:

redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SMEMBERS myset
1) "Hello"
2) "World"

🦋 SISMEMBER

判断⼀个元素在不在set中。
语法:

SISMEMBER key member

命令有效版本:1.0.0之后
时间复杂度:O(1)
返回值:1表⽰元素在set中。0表⽰元素不在set中或者key不存在。
⽰例:

redis> SADD myset "one"
(integer) 1
redis> SISMEMBER myset "one"
(integer) 1
redis> SISMEMBER myset "two"
(integer) 0

🦋 SCARD

获取⼀个set的基数(cardinality),即set中的元素个数。
语法:

SCARD key

命令有效版本:1.0.0之后
时间复杂度:O(1)
返回值:set内的元素个数。
⽰例:

redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SCARD myset
(integer) 2

🦋 SPOP

从set中删除并返回⼀个或者多个元素。注意,由于set内的元素是⽆序的,所以取出哪个元素实际是未定义⾏为,即可以看作随机的。

语法:

 SPOP key [count]

命令有效版本:1.0.0之后
时间复杂度:O(N),n是count
返回值:取出的元素。
⽰例:

redis> SADD myset "one"
(integer) 1
redis> SADD myset "two"
(integer) 1
redis> SADD myset "three"
(integer) 1
redis> SPOP myset
"one"
redis> SMEMBERS myset
1) "three"
2) "two"
redis> SADD myset "four"
(integer) 1
redis> SADD myset "five"
(integer) 1
redis> SPOP myset 3
1) "three"
2) "four"
3) "two"
redis> SMEMBERS myset
1) "five"

🦋 SMOVE

将⼀个元素从源set取出并放⼊⽬标set中。
语法:

SMOVE source destination member

命令有效版本:1.0.0之后
时间复杂度:O(1)
返回值:1表⽰移动成功,0表⽰失败。
⽰例:

redis> SADD myset "one"
(integer) 1
redis> SADD myset "two"
(integer) 1
redis> SADD myotherset "three"
(integer) 1
redis> SMOVE myset myotherset "two"
(integer) 1
redis> SMEMBERS myset
1) "one"
redis> SMEMBERS myotherset
1) "three"
2) "two"

🦋 SREM

将指定的元素从set中删除。
语法:

SREM key member [member ...]

命令有效版本:1.0.0之后
时间复杂度:O(N),N是要删除的元素个数.
返回值:本次操作删除的元素个数。
⽰例:

redis> SADD myset "one"
(integer) 1
redis> SADD myset "two"
(integer) 1
redis> SADD myset "three"
(integer) 1
redis> SREM myset "one"
(integer) 1
redis> SREM myset "four"
(integer) 0
redis> SMEMBERS myset
1) "three"
2) "two"

集合间操作

交集(inter)、并集(union)、差集(diff)的概念如图2-25所⽰。

图2-25集合求交集、并集、差集

在这里插入图片描述

🦋 SINTER

获取给定set的交集中的元素。
语法:

SINTER key [key ...]

命令有效版本:1.0.0之后
时间复杂度:O(N*M),N是最⼩的集合元素个数.M是最⼤的集合元素个数.
返回值:交集的元素。
⽰例:

redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SINTER key1 key2
1) "c"

🦋 SINTERSTORE

获取给定set的交集中的元素并保存到⽬标set中。
语法:

SINTERSTORE destination key [key ...]

命令有效版本:1.0.0之后
时间复杂度:O(N*M),N是最⼩的集合元素个数.M是最⼤的集合元素个数.
返回值:交集的元素个数。
⽰例:

redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SINTERSTORE key key1 key2
(integer) 1
redis> SMEMBERS key
1) "c"

🦋 SUNION

获取给定set的并集中的元素。
语法:

SUNION key [key ...]

命令有效版本:1.0.0之后
时间复杂度:O(N),N给定的所有集合的总的元素个数.
返回值:并集的元素。
⽰例:

redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SUNION key1 key2
1) "a"
2) "c"
3) "e"
4) "b"
5) "d"

🦋 SUNIONSTORE

获取给定set的并集中的元素并保存到⽬标set中。
语法:

SUNIONSTORE destination key [key ...]

命令有效版本:1.0.0之后
时间复杂度:O(N),N给定的所有集合的总的元素个数.
返回值:并集的元素个数。
⽰例:

redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SUNIONSTORE key key1 key2
(integer) 5
redis> SMEMBERS key
1) "a"
2) "c"
3) "e"
4) "b"
5) "d"

🦋 SDIFF

获取给定set的差集中的元素。
语法:

SDIFF key [key ...]

命令有效版本:1.0.0之后
时间复杂度:O(N),N给定的所有集合的总的元素个数.
返回值:差集的元素。
⽰例:

redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SDIFF key1 key2
1) "a"
2) "b"

🦋 SDIFFSTORE

获取给定set的差集中的元素并保存到⽬标set中。
语法:

SDIFFSTORE destination key [key ...]

命令有效版本:1.0.0之后
时间复杂度:O(N),N给定的所有集合的总的元素个数.
返回值:差集的元素个数。
⽰例:

redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SDIFFSTORE key key1 key2
(integer) 2
redis> SMEMBERS key
1) "a"
2) "b"

🔥 命令⼩结

表2-6总结了集合类型的常⻅命令,开发⼈员可以根据⾃⾝需求进⾏选择。

表2-6集合类型命令

在这里插入图片描述

🔥 内部编码

集合类型的内部编码有两种:

  • intset(整数集合):当集合中的元素都是整数并且元素的个数⼩于set-max-intset-entries配置(默认512个)时,Redis会选⽤intset来作为集合的内部实现,从⽽减少内存的使⽤。
  • hashtable(哈希表):当集合类型⽆法满⾜intset的条件时,Redis会使⽤hashtable作为集合的内部实现。
  1. 当元素个数较少并且都为整数时,内部编码为intset:
127.0.0.1:6379> sadd setkey 1 2 3 4
(integer) 4
127.0.0.1:6379> object encoding setkey
"intset"
  1. 当元素个数超过512个,内部编码为hashtable:
127.0.0.1:6379> sadd setkey 1 2 3 4
(integer) 513
127.0.0.1:6379> object encoding setkey
"hashtable"
  1. 当存在元素不是整数时,内部编码为hashtable:
127.0.0.1:6379> sadd setkey a
(integer) 1
127.0.0.1:6379> object encoding setkey
"hashtable"

🔥 使⽤场景

集合类型⽐较典型的使⽤场景是标签(tag)。例如A⽤户对娱乐、体育板块⽐较感兴趣,B⽤户对历史、新闻⽐较感兴趣,这些兴趣点可以被抽象为标签。有了这些数据就可以得到喜欢同⼀个标签的⼈,以及⽤户的共同喜好的标签,这些数据对于增强⽤户体验和⽤户黏度都⾮常有帮助。例如⼀个电⼦商务⽹站会对不同标签的⽤⼾做不同的产品推荐。

下⾯的演⽰通过集合类型来实现标签的若⼲功能。

  1. 给⽤户添加标签
sadd user:1:tags tag1 tag2 tag5
sadd user:2:tags tag2 tag3 tag5
...
sadd user:k:tags tag1 tag2 tag4
  1. 给标签添加⽤户
sadd tag1:users user:1 user:3
sadd tag2:users user:1 user:2 user:3
...
sadd tagk:users user:1 user:4 user:9 user:28
  1. 删除⽤户下的标签
srem user:1:tags tag1 tag5
...
  1. 删除标签下的⽤户
srem tag1:users user:1
srem tag5:users user:1
...
  1. 计算⽤户的共同兴趣标签
sinter user:1:tags user:2:tags

🔥 Zset有序集合

有序集合相对于字符串、列表、哈希、集合来说会有⼀些陌⽣。它保留了集合不能有重复成员的特点,但与集合不同的是,有序集合中的每个元素都有⼀个唯⼀的浮点类型的分数(score)与之关联,着使得有序集合中的元素是可以维护有序性的,但这个有序不是⽤下标作为排序依据⽽是⽤这个分数。如图2-26所⽰,该有序集合显⽰了三国中的武将的武⼒。

图2-26有序集合

在这里插入图片描述
有序集合提供了获取指定分数和元素范围查找、计算成员排名等功能,合理地利⽤有序集合,可以帮助我们在实际开发中解决很多问题。

有序集合中的元素是不能重复的,但分数允许重复。类⽐于⼀次考试之后,每个⼈⼀定有⼀个唯⼀的分数,但分数允许相同。

表2-7列表、集合、有序集合三者的异同点。

在这里插入图片描述

🔥 普通命令

🦋 ZADD

添加或者更新指定的元素以及关联的分数到zset中,分数应该符合double类型,+inf/-inf作为正负极限也是合法的。

ZADD的相关选项:

  • XX:仅仅⽤于更新已经存在的元素,不会添加新元素。
  • NX:仅⽤于添加新元素,不会更新已经存在的元素。
  • LT:这个选项的意思是 less than 和 greater than 的意思,这两个意思表示的是现在如果要进行更新分数,那么如果当前的分数比之前的分数小,就更新成功,否则就不更新,反之同理
  • CH:默认情况下,ZADD返回的是本次添加的元素个数,但指定这个选项之后,就会还包含本次更新的元素的个数。
  • INCR:此时命令类似ZINCRBY的效果,将元素的分数加上指定的分数。此时只能指定⼀个元素和分数。

语法:

ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member ...]

命令有效版本:1.2.0之后
时间复杂度:O(log(N))

对于 zset 来说,时间复杂度就不一样了,在 set 中的各项操作基本都是 O(1) 的时间复杂度,而在 zset 中却被放到了 O(logn),这是因为毕竟是有序结构,要找到合适的位置才能放,所以这里是 logn,那为什么不是 O(n) 呢?其实更多的是借助了跳表这样的数据结构,可以快速定位到对应的位置,进行元素的插入工作

返回值:本次添加成功的元素个数。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 1 "uno"
(integer) 1
redis> ZADD myzset 2 "two" 3 "three"
(integer) 2
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "uno"
4) "1"
5) "two"
6) "2"
7) "three"
8) "3"
redis> ZADD myzset 10 one 20 two 30 three
(integer) 0
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "uno"
2) "1"
3) "one"
4) "10"
5) "two"
6) "20"
7) "three"
8) "30"
redis> ZADD myzset CH 100 one 200 two 300 three
(integer) 3
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "uno"
2) "1"
3) "one"
4) "100"
5) "two"
6) "200"
7) "three"
8) "300"
redis> ZADD myzset XX 1 one 2 two 3 three 4 four 5 five
(integer) 0
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "uno"
4) "1"
5) "two"
6) "2"
7) "three"
8) "3"
redis> ZADD myzset NX 100 one 200 two 300 three 400 four 500 five
(integer) 2
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "uno"
4) "1"
5) "two"
6) "2"
7) "three"
8) "3"
9) "four"
10) "400"
11) "five"
12) "500"
redis> ZADD myzset INCR 10 one
"11"
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "uno"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
7) "one"
8) "11"
9) "four"
10) "400"
11) "five"
12) "500"
redis> ZADD myzset -inf "negative infinity" +inf "positive infinity"
(integer) 2
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "negative infinity"
2) "-inf"
3) "uno"
4) "1"
5) "two"
6) "2"
7) "three"
8) "3"
9) "one"
10) "11"
11) "four"
12) "400"
13) "five"
14) "500"
15) "positive infinity"
16) "inf"

🦋 ZCARD

获取⼀个zset的基数(cardinality),即zset中的元素个数。
语法:

ZCARD key

命令有效版本:1.2.0之后
时间复杂度:O(1)
返回值:zset内的元素个数。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZCARD myzset
(integer) 2

🦋 ZCOUNT

返回分数在min和max之间的元素个数,默认情况下,min和max都是包含的,可以通过(排除。

语法:

 ZCOUNT key min max

命令有效版本:2.0.0之后
时间复杂度:O(log(N))
返回值:满⾜条件的元素列表个数。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZCOUNT myzset -inf +inf
(integer) 3
redis> ZCOUNT myzset 1 3
(integer) 3
redis> ZCOUNT myzset (1 3
(integer) 2
redis> ZCOUNT myzset (1 (3
(integer) 1

🦋 ZRANGE

返回指定区间⾥的元素,分数按照升序。带上WITHSCORES可以把分数也返回。
语法:

ZRANGE key start stop [WITHSCORES]

此处的[start,stop]为下标构成的区间.从0开始,⽀持负数.
命令有效版本:1.2.0之后
时间复杂度:O(log(N)+M)
返回值:区间内的元素列表。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
redis> ZRANGE myzset 0 -1
1) "one"
2) "two"
3) "three"
redis> ZRANGE myzset 2 3
1) "three"
redis> ZRANGE myzset -2 -1
1) "two"
2) "three"

🦋 ZREVRANGE

返回指定区间⾥的元素,分数按照降序。带上WITHSCORES可以把分数也返回。
备注:这个命令可能在6.2.0之后废弃,并且功能合并到ZRANGE中。
语法:

ZREVRANGE key start stop [WITHSCORES]

命令有效版本:1.2.0之后
时间复杂度:O(log(N)+M)
返回值:区间内的元素列表。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZREVRANGE myzset 0 -1 WITHSCORES
1) "three"
2) "3"
3) "two"
4) "2"
5) "one"
6) "1"
redis> ZREVRANGE myzset 0 -1
1) "three"
2) "two"
3) "one"
redis> ZREVRANGE myzset 2 3
1) "one"
redis> ZREVRANGE myzset -2 -1
1) "two"
2) "one"

🦋 ZRANGEBYSCORE

返回分数在min和max之间的元素,默认情况下,min和max都是包含的,可以通过(排除。
备注:这个命令可能在6.2.0之后废弃,并且功能合并到ZRANGE中。
语法:

ZRANGEBYSCORE key min max [WITHSCORES]

命令有效版本:1.0.5之后
时间复杂度:O(log(N)+M)
返回值:区间内的元素列表。

⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZRANGEBYSCORE myzset -inf +inf
1) "one"
2) "two"
3) "three"
redis> ZRANGEBYSCORE myzset 1 2
1) "one"
2) "two"
redis> ZRANGEBYSCORE myzset (1 2
1) "two"
redis> ZRANGEBYSCORE myzset (1 (2
(empty array)

🦋 ZPOPMAX

删除并返回分数最⾼的count个元素。
语法:

ZPOPMAX key [count]

命令有效版本:5.0.0之后
时间复杂度:O(log(N)*M)
返回值:分数和元素列表。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZPOPMAX myzset
1) "three"
2) "3"

🦋 BZPOPMAX

ZPOPMAX的阻塞版本。
语法:

BZPOPMAX key [key ...] timeout

命令有效版本:5.0.0之后
时间复杂度:O(log(N))
返回值:元素列表。
⽰例:

redis> DEL zset1 zset2
(integer) 0
redis> ZADD zset1 0 a 1 b 2 c
(integer) 3
redis> BZPOPMAX zset1 zset2 0
1) "zset1"
2) "c"
3) "2"

🦋 ZPOPMIN

删除并返回分数最低的count个元素。
语法:

ZPOPMIN key [count]

命令有效版本:5.0.0之后
时间复杂度:O(log(N)*M)
返回值:分数和元素列表。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZPOPMIN myzset
1) "one"
2) "1"

🦋 BZPOPMIN

ZPOPMIN的阻塞版本。
语法:

BZPOPMIN key [key ...] timeout

命令有效版本:5.0.0之后
时间复杂度:O(log(N))
返回值:元素列表。
⽰例:

redis> DEL zset1 zset2
(integer) 0
redis> ZADD zset1 0 a 1 b 2 c
(integer) 3
redis> BZPOPMIN zset1 zset2 0
1) "zset1"
2) "a"
3) "0"

🦋 ZRANK

返回指定元素的排名,升序。
语法:

ZRANK key member

命令有效版本:2.0.0之后
时间复杂度:O(log(N))
返回值:排名。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZRANK myzset "three"
(integer) 2
redis> ZRANK myzset "four"
(nil)

🦋 ZREVRANK

返回指定元素的排名,降序。
语法:

ZREVRANK key member

命令有效版本:2.0.0之后
时间复杂度:O(log(N))
返回值:排名。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZREVRANK myzset "one"
(integer) 2
redis> ZREVRANK myzset "four"
(nil)

🦋 ZSCORE

返回指定元素的分数。
语法:

ZSCORE key member

命令有效版本:1.2.0之后
时间复杂度:O(1)
返回值:分数。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZSCORE myzset "one"
"1"

🦋 ZREM

删除指定的元素。
语法:

ZREM key member [member ...]

命令有效版本:1.2.0之后
时间复杂度:O(M*log(N))
返回值:本次操作删除的元素个数。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZREM myzset "two"
(integer) 1
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "three"
4) "3"

🦋 ZREMRANGEBYRANK

按照排序,升序删除指定范围的元素,左闭右闭。
语法:

ZREMRANGEBYRANK key start stop

命令有效版本:2.0.0之后
时间复杂度:O(log(N)+M)
返回值:本次操作删除的元素个数。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZREMRANGEBYRANK myzset 0 1
(integer) 2
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "three"
2) "3"

🦋 ZREMRANGEBYSCORE

按照分数删除指定范围的元素,左闭右闭。
语法:

ZREMRANGEBYSCORE key min max

命令有效版本:1.2.0之后
时间复杂度:O(log(N)+M)
返回值:本次操作删除的元素个数。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZREMRANGEBYSCORE myzset -inf (2
(integer) 1
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "two"
2) "2"
3) "three"
4) "3"

🦋 ZINCRBY

为指定的元素的关联分数添加指定的分数值。
语法:

ZINCRBY key increment member

命令有效版本:1.2.0之后
时间复杂度:O(log(N))
返回值:增加后元素的分数。
⽰例:

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZINCRBY myzset 2 "one"
"3"
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "two"
2) "2"
3) "one"
4) "3"

🔥 集合间操作

图2-27有序集合的交集操作

在这里插入图片描述

🦋 ZINTERSTORE

求出给定有序集合中元素的交集并保存进⽬标有序集合中,在合并过程中以元素为单位进⾏合并,元素对应的分数按照不同的聚合⽅式和权重得到新的分数。

语法:

ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight
[weight ...]] [AGGREGATE <SUM | MIN | MAX>]

命令有效版本:2.0.0之后

时间复杂度:O(NK)+O(Mlog(M))N是输⼊的有序集合中,最⼩的有序集合的元素个数;K是输⼊了⼏个有序集合;M是最终结果的有序集合的元素个数.

返回值:⽬标集合中的元素个数

⽰例:

redis> ZADD zset1 1 "one"
(integer) 1
redis> ZADD zset1 2 "two"
(integer) 1
redis> ZADD zset2 1 "one"
(integer) 1
redis> ZADD zset2 2 "two"
(integer) 1
redis> ZADD zset2 3 "three"
(integer) 1
redis> ZINTERSTORE out 2 zset1 zset2 WEIGHTS 2 3
(integer) 2
redis> ZRANGE out 0 -1 WITHSCORES
1) "one"
2) "5"
3) "two"
4) "10"
图2-28有序集合的并集操作kris 1

在这里插入图片描述

🦋 ZUNIONSTORE

求出给定有序集合中元素的并集并保存进⽬标有序集合中,在合并过程中以元素为单位进⾏合并,元素对应的分数按照不同的聚合⽅式和权重得到新的分数。

语法:

ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight
[weight ...]] [AGGREGATE <SUM | MIN | MAX>]

命令有效版本:2.0.0之后
时间复杂度:O(N)+O(M*log(M))N是输⼊的有序集合总的元素个数;M是最终结果的有序集合的元素个数.

返回值:⽬标集合中的元素个数

⽰例:

redis> ZADD zset1 1 "one"
(integer) 1
redis> ZADD zset1 2 "two"
(integer) 1
redis> ZADD zset2 1 "one"
(integer) 1
redis> ZADD zset2 2 "two"
(integer) 1
redis> ZADD zset2 3 "three"
(integer) 1
redis> ZUNIONSTORE out 2 zset1 zset2 WEIGHTS 2 3
(integer) 3
redis> ZRANGE out 0 -1 WITHSCORES
1) "one"
2) "5"
3) "three"
4) "9"
5) "two"
6) "10"

🔥 命令⼩结

表2-8有序集合命令

在这里插入图片描述

🔥 内部编码

有序集合类型的内部编码有两种:

  • ziplist(压缩列表):当有序集合的元素个数⼩于zset-max-ziplist-entries配置(默认128个),同时每个元素的值都⼩于zset-max-ziplist-value配置(默认64字节)时,Redis会⽤ziplist来作为有序集合的内部实现,ziplist可以有效减少内存的使⽤。
  • skiplist(跳表):当ziplist条件不满⾜时,有序集合会使⽤skiplist作为内部实现,因为此时ziplist的操作效率会下降。
  1. 当元素个数较少且每个元素较⼩时,内部编码为ziplist:
127.0.0.1:6379> zadd zsetkey 50 e1 60 e2 30 e3
(integer) 3
127.0.0.1:6379> object encoding zsetkey
"ziplist"
  1. 当元素个数超过128个,内部编码skiplist:
127.0.0.1:6379> zadd zsetkey 50 e1 60 e2 30 e3 ... 省略 ... 82 e129
(integer) 129
127.0.0.1:6379> object encoding zsetkey
"skiplist"
  1. 当某个元素⼤于64字节时,内部编码skiplist:
127.0.0.1:6379> zadd zsetkey 50 "one string bigger than 64 bytes ... 省略 ..."
(integer) 1
127.0.0.1:6379> object encoding zsetkey
"skiplist"

🔥 使⽤场景

有序集合⽐较典型的使⽤场景就是排⾏榜系统。例如常⻅的⽹站上的热榜信息,榜单的维度可能是多⽅⾯的:按照时间、按照阅读量、按照点赞量。本例中我们使⽤点赞数这个维度,维护每天的热榜:

  1. 添加⽤户赞数

例如⽤户james发布了⼀篇⽂章,并获得3个赞,可以使⽤有序集合的zadd和zincrby功能:

zadd user:ranking:2022-03-15 3 james

之后如果再获得赞,可以使⽤zincrby:

zincrby user:ranking:2022-03-15 1 james
  1. 取消⽤户赞数

由于各种原因(例如⽤户注销、⽤户作弊等)需要将⽤户删除,此时需要将⽤户从榜单中删除掉,可以使⽤zrem。例如删除成员tom:

zrem user:ranking:2022-03-15 tom
  1. 展⽰获取赞数最多的10个⽤⼾户

此功能使⽤zrevrange命令实现:

zrevrangebyrank user:ranking:2022-03-15 0 9
  1. 展⽰⽤户信息以及⽤户分数

此功能将⽤户名作为键后缀,将⽤户信息保存在哈希类型中,⾄于⽤户的分数和排名可以使⽤zscore和zrank来实现。

hgetall user:info:tom
zscore user:ranking:2022-03-15 mike
zrank user:ranking:2022-03-15 mike

🔥 共勉

😋 以上就是我对 Redis:set类型和zset类型 的理解, 觉得这篇博客对你有帮助的,可以点赞收藏关注支持一波~ 😉
在这里插入图片描述

相关文章:

  • 汽车制造通信革新:网关模块让EtherCAT成功对接CCLINK
  • gitlab相关操作
  • Redis GEO 底层实现(结合源码分析)
  • Redis的主从复制底层实现
  • 【编译工具】(调试)Chrome DevTools + Postman:调试组合如何让我的开发效率提升400%?
  • Guava常用工具类使用教程
  • 《Redis》持久化
  • Oracle线上故障问题解决
  • SpringMVC异步处理Servlet
  • Flask应用中处理异步事件(后台线程+事件循环)的方法
  • 达梦数据库 单机部署dmhs同步复制(DM8—>DM8)
  • 高频面试之6Hive
  • Redis: List类型
  • Redis免费客户端工具推荐
  • Github月度新锐热门工具 - 202506
  • [HarmonyOSNext鸿蒙开发]11.ArkUI框架:Swiper、Grid布局与代码复用实战指南
  • Spring Boot 集成 Redis 实战教程
  • spring boot源码和lib分开打包
  • AWS CloudFormation实战:构建可复用的ECS服务部署模板
  • AWS TAM行为面试模拟题
  • 快递物流网站建设开发具备哪些功能/想学销售去哪培训
  • 制作一个静态网页/北京度seo排名
  • 交易平台网站制作/推广引流图片
  • 好看的单页面网站模板免费下载/排名网站
  • 阿里云wordpress教程/seo网站推广实例
  • 做的阿里巴巴网站的放哪个科目/牡丹江seo