set
保存多个字符串元素,但不允许有重复的元素,并且集合set是无序的,不能通过索引下标获取元素
set除了基本的增删改查,还支持多个集合的取交集、并集、差集等操作,下面来看一下命令help @set
sadd
SADD key member [member ...]
summary: Add one or more members to a set
since: 1.0.0
添加元素
127.0.0.1:6379[1]> del k1
(integer) 1
127.0.0.1:6379[1]> sadd k1 a b c
(integer) 3
127.0.0.1:6379[1]> sadd k1 b c
(integer) 0
smembers
SMEMBERS key
summary: Get all the members in a set
since: 1.0.0
获取所有元素,并且结果是无序的
127.0.0.1:6379[1]> smembers k1
1) "a"
2) "c"
3) "b"
srem
SREM key member [member ...]
summary: Remove one or more members from a set
since: 1.0.0
删除元素
127.0.0.1:6379[1]> srem k1 b
(integer) 1
127.0.0.1:6379[1]> srem k1 cccc
(integer) 0
127.0.0.1:6379[1]> smembers k1
1) "a"
2) "c"
scard
SCARD key
summary: Get the number of members in a set
since: 1.0.0
计算元素个数,scard的时间复杂度O(1),它不会遍历集合所有的元素,而是直接用Redis内存提供的变量
127.0.0.1:6379[1]> scard k1
(integer) 2
sismember
SISMEMBER key member
summary: Determine if a given value is a member of a set
since: 1.0.0
判断元素是否在集合中,有返回1,无返回0
127.0.0.1:6379[1]> sismember k1 a
(integer) 1
127.0.0.1:6379[1]> sismember k1 aaa
(integer) 0
srandmember
SRANDMEMBER key [count]
summary: Get one or multiple random members from a set
since: 1.0.0
随机从集合返回指定个数元素,元素不会从集合中删除
count的取值:
-
正数:取出一个去重的结果集(不能超过已有集)
-
负数:取出一个带重复的结果集,一定返回满足你要的数量
-
如果:0,不返回
127.0.0.1:6379[1]> sadd k1 a b c d e
(integer) 3
127.0.0.1:6379[1]> srandmember k1 3
1) "c"
2) "a"
3) "d"
127.0.0.1:6379[1]> srandmember k1 -3
1) "d"
2) "a"
3) "d"
spop
SPOP key [count]
summary: Remove and return one or multiple random members from a set
since: 1.0.0
从集合中随机弹出元素,元素会从集合中删除
127.0.0.1:6379[1]> spop k1
"a"
127.0.0.1:6379[1]> smembers k1
1) "e"
2) "c"
3) "b"
4) "d"
sinter、sinterstore
SINTER key [key ...]
summary: Intersect multiple sets
since: 1.0.0
SINTERSTORE destination key [key ...]
summary: Intersect multiple sets and store the resulting set in a key
since: 1.0.0
sinter求多个集合的交集,sinterstore将交集的结果保存
127.0.0.1:6379[1]> del k1 k2
(integer) 1
127.0.0.1:6379[1]> sadd k1 a b c d
(integer) 4
127.0.0.1:6379[1]> sadd k2 c d e
(integer) 3
127.0.0.1:6379[1]> sinter k1 k2
1) "c"
2) "d"
127.0.0.1:6379[1]> sinterstore desinter k1 k2
(integer) 2
127.0.0.1:6379[1]> smembers desinter
1) "c"
2) "d"
sunion、sunionstore
SUNION key [key ...]
summary: Add multiple sets
since: 1.0.0
SUNIONSTORE destination key [key ...]
summary: Add multiple sets and store the resulting set in a key
since: 1.0.0
sunion求多个集合的并集,sunionstore将并集结果保存
127.0.0.1:6379[1]> sunion k1 k2
1) "d"
2) "e"
3) "c"
4) "a"
5) "b"
127.0.0.1:6379[1]> sunionstore desunion k1 k2
(integer) 5
127.0.0.1:6379[1]> smembers desunion
1) "d"
2) "e"
3) "c"
4) "a"
5) "b"
sdiff、sdiffstore
SDIFF key [key ...]
summary: Subtract multiple sets
since: 1.0.0
SDIFFSTORE destination key [key ...]
summary: Subtract multiple sets and store the resulting set in a key
since: 1.0.0
sdiff求多个集合的差集,sdiffstore将差集结果保存
127.0.0.1:6379[1]> sdiff k1 k2
1) "a"
2) "b"
127.0.0.1:6379[1]> sdiffstore desdiff k1 k2
(integer) 2
127.0.0.1:6379[1]> smembers desdiff
1) "a"
2) "b"
smove
SMOVE source destination member
summary: Move a member from one set to another
since: 1.0.0
将指定成员 member 元素从 source 集合移动到 destination 集合
127.0.0.1:6379[1]> smembers k1
1) "a"
2) "c"
3) "b"
4) "d"
127.0.0.1:6379[1]> smembers k2
1) "e"
2) "c"
3) "d"
127.0.0.1:6379[1]> smove k1 k2 a
(integer) 1
127.0.0.1:6379[1]> smembers k1
1) "c"
2) "b"
3) "d"
127.0.0.1:6379[1]> smembers k2
1) "e"
2) "a"
3) "c"
4) "d"
sscan
SSCAN key cursor [MATCH pattern] [COUNT count]
summary: Incrementally iterate Set elements
since: 2.8.0
用于迭代集合中键的元素。cursor - 游标,pattern - 匹配的模式,count - 指定从数据集里返回多少元素,默认值为 10 。
127.0.0.1:6379[1]> sadd k4 apple banana orange
(integer) 3
127.0.0.1:6379[1]> sscan k4 0 match a*
1) "0"
2) 1) "apple"
127.0.0.1:6379[1]> sscan k4 1 match a*
1) "0"
2) (empty list or set)
内部编码
- intset(整数集合):当集合中的元素都是整数且元素个数小于
set-max-intset-entries
配置(默认512个)时,Redis使用intset作为集合的内部实现,从而减少内存的使用。 - hashtable(哈希表):当集合类型无法满足intset的条件时,Redis使用hashtable作为集合的内部实现
127.0.0.1:6379[1]> object encoding k1
"hashtable"
127.0.0.1:6379[1]> sadd intkey 1 2 3 4
(integer) 4
127.0.0.1:6379[1]> object encoding intkey
"intset"
127.0.0.1:6379[1]> sadd intkey 1 2 3 4 5 ... 512 513
(integer) 4
127.0.0.1:6379[1]> object encoding intkey
"hashtable"
应用
- 标签 sadd
给用户添加标签
sadd user:1:tags tag1 tag2 tag3
sadd user:2:tags tag1 tag4 tag5
给标签添加用户
sadd tag1:users user:1 user:2
sadd tag2:users user:2
删除用户下的标签
srem user:1:tags tag3
删除标签下的用户
srem tag1:users user2
计算用户共同感兴趣的标签
sinter user:1:tags user:2:tags
-
抽奖
-
spop
例如每个人只能中一个奖,中奖后不能在参与其他奖项,需要在集合中删除
-
srandmember
每个人可以重复中奖
-
sorted_set
有序集合保留集合不能重复的特性,又可以排序,为每一个元素设置一个分数(score)作为排序的依据。
list,set,sorted_set的异同点
数据结构 | 是否允许重复元素 | 是否有序 | 有序实现方式 | 应用场景 |
---|---|---|---|---|
list | 是 | 是 | 索引下标 | 时间轴、消息队列 |
set | 否 | 否 | 无 | 标签、抽奖、社交等 |
sorted_set | 否 | 是 | 分值 | 排行榜系统、社交等 |
下面看一下sorted_set的相关命令 help @sorted_set
zadd
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
summary: Add one or more members to a sorted set, or update its score if it already exists
since: 1.2.0
添加成员
- nx:member必须不存在,才可以设置成功,用于添加
- xx:member必须存在,才可以设置成功,用于更新
- ch:返回此次操作后,有序集合元素和分数发生变化的个数
- incr:对score做增加,相当于zincrby
sorted_set相比set提供了排序字段,但是也产生了代价,zadd的时间复杂度为O(long(n)),sadd的事件复杂度为O(1)。
127.0.0.1:6379[1]> zadd k1 100 demeter
(integer) 1
zcard
ZCARD key
summary: Get the number of members in a sorted set
since: 1.2.0
计算成员个数
127.0.0.1:6379[1]> zcard k1
(integer) 1
127.0.0.1:6379[1]> zadd k1 120 tom
(integer) 1
127.0.0.1:6379[1]> zcard k1
(integer) 2
zscore
ZSCORE key member
summary: Get the score associated with the given member in a sorted set
since: 1.2.0
计算某个成员的分数
127.0.0.1:6379[1]> zscore k1 tom
"120"
zrank
ZRANK key member
summary: Determine the index of a member in a sorted set
since: 2.0.0
计算成员的排名,zrank是从分数从低到高返回排名
127.0.0.1:6379[1]> zrank k1 tom
(integer) 1
127.0.0.1:6379[1]> zrank k1 demeter
(integer) 0
zrevrank
ZREVRANK key member
summary: Determine the index of a member in a sorted set, with scores ordered from high to low
since: 2.0.0
计算成员的排名,zrevrank是从分数从高到低返回排名
127.0.0.1:6379[1]> zrevrank k1 tom
(integer) 0
127.0.0.1:6379[1]> zrevrank k1 demeter
(integer) 1
zrem
ZREM key member [member ...]
summary: Remove one or more members from a sorted set
since: 1.2.0
删除成员
127.0.0.1:6379[1]> zrem k1 tom
(integer) 1
zincrby
ZINCRBY key increment member
summary: Increment the score of a member in a sorted set
since: 1.2.0
增加成员的分数
127.0.0.1:6379[1]> zincrby k1 40 demeter
"140"
127.0.0.1:6379[1]> zscore k1 demeter
"140"
zrange
ZRANGE key start stop [WITHSCORES]
summary: Return a range of members in a sorted set, by index
since: 1.2.0
返回指定排名范围的成员,zrange按照分值排序从低到高返回,加上withscores,同时会返回成员的分数
127.0.0.1:6379[1]> zadd k1 120 tom
(integer) 1
127.0.0.1:6379[1]> zadd k1 90 jack
(integer) 1
127.0.0.1:6379[1]> zadd k1 200 maek
(integer) 1
127.0.0.1:6379[1]> zadd k1 170 chery
(integer) 1
127.0.0.1:6379[1]> zrange k1 0 -1 withscores
1) "jack"
2) "90"
3) "tom"
4) "120"
5) "demeter"
6) "140"
7) "chery"
8) "170"
9) "maek"
10) "200"
127.0.0.1:6379[1]> zrange k1 1 3 withscores
1) "tom"
2) "120"
3) "demeter"
4) "140"
5) "chery"
6) "170"
zrevrange
ZREVRANGE key start stop [WITHSCORES]
summary: Return a range of members in a sorted set, by index, with scores ordered from high to low
since: 1.2.0
返回指定排名范围的成员,zrange按照分值排序从高到低返回
127.0.0.1:6379[1]> zrevrange k1 0 -1 withscores
1) "maek"
2) "200"
3) "chery"
4) "170"
5) "demeter"
6) "140"
7) "tom"
8) "120"
9) "jack"
10) "90"
127.0.0.1:6379[1]> zrevrange k1 1 3 withscores
1) "chery"
2) "170"
3) "demeter"
4) "140"
5) "tom"
6) "120"
zrangebyscore
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
summary: Return a range of members in a sorted set, by score
since: 1.0.5
返回指定分数范围的成员,zrangebyscore按照从低到高返回,加上withscores,同时会返回成员的分数。[LIMIT offset count]选项可以限制输出的起始位置和个数。
同时min和max还支持开区间(小括号)和闭区间(中括号),-inf和+inf分别代表无限小和无限大
127.0.0.1:6379[1]> zrangebyscore k1 150 200 withscores
1) "chery"
2) "170"
3) "maek"
4) "200"
127.0.0.1:6379[1]> zrangebyscore k1 (100 +inf withscores
1) "tom"
2) "120"
3) "demeter"
4) "140"
5) "chery"
6) "170"
7) "maek"
8) "200
zrevrangebyscore
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
summary: Return a range of members in a sorted set, by score, with scores ordered from high to low
ince: 2.2.0
与zrangebyscore相反,按照分值从高到低返回
127.0.0.1:6379[1]> zrevrangebyscore k1 200 100 withscores
1) "maek"
2) "200"
3) "chery"
4) "170"
5) "demeter"
6) "140"
7) "tom"
8) "120"
zcount
ZCOUNT key min max
summary: Count the members in a sorted set with scores within the given values
since: 2.0.0
返回指定分数范围成员个数
127.0.0.1:6379[1]> zcount k1 100 200
(integer) 4
zremrangebyrank
ZREMRANGEBYRANK key start stop
summary: Remove all members in a sorted set within the given indexes
since: 2.0.0
删除指定排名内的升序元素
127.0.0.1:6379[1]> zremrangebyrank k1 0 1
(integer) 2
zremrangebyscore
ZREMRANGEBYSCORE key min max
summary: Remove all members in a sorted set within the given scores
since: 1.2.0
删除指定分数范围的成员
127.0.0.1:6379[1]> zrange k1 0 -1 withscores
1) "demeter"
2) "140"
3) "chery"
4) "170"
5) "maek"
6) "200"
127.0.0.1:6379[1]> zremrangebyscore k1 200 +inf
(integer) 1
127.0.0.1:6379[1]> zrange k1 0 -1 withscores
1) "demeter"
2) "140"
3) "chery"
4) "170"
zinterstore
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
summary: Intersect multiple sorted sets and store the resulting sorted set in a new key
since: 2.0.0
取交集
- destination:交际计算结果保存到这个键
- numkeys:需要做交集计算键的个数
- key [key …]:需要做交集的键
- [WEIGHTS weight]:每个键的权重,在做交集计算时,每个键中的每个member会将自己分数乘以这个权重,每个键的权重默认是1
- [AGGREGATE SUM|MIN|MAX]:计算成员交集后,分数可以按照sum、min、max做汇总,默认值是sum
127.0.0.1:6379[1]> zadd k2 12 a1 23 a2 31 a3 144 a4 230 a5
(integer) 5
127.0.0.1:6379[1]> zadd k3 18 a1 45 a3 54 a5 140 a7 123 a9
(integer) 5
127.0.0.1:6379[1]> ZINTERSTORE zinter 2 k2 k3
(integer) 3
127.0.0.1:6379[1]> zrange zinter 0 -1 withscores
1) "a1"
2) "30"
3) "a3"
4) "76"
5) "a5"
6) "284"
zunionstore
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
summary: Add multiple sorted sets and store the resulting sorted set in a new key
since: 2.0.0
取并集,参数与交集的参数一致
127.0.0.1:6379[1]> zunionstore zunion 2 k2 k3
(integer) 7
127.0.0.1:6379[1]> zrange zunion 0 -1 withscores
1) "a2"
2) "23"
3) "a1"
4) "30"
5) "a3"
6) "76"
7) "a9"
8) "123"
9) "a7"
10) "140"
11) "a4"
12) "144"
13) "a5"
14) "284"
内部编码
-
ziplist:当有序集合的元素个数小于
zset-max-ziplist-entries
配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value
配置时(默认64字节),Redis会选用ziplist来作为有序集合的内部实现来减少内存的使用 -
skiplist(跳跃表):当有序集合无法满足ziplist的条件时,使用skiplist作为有序集合的内部实现,因为此时ziplist的读写效率会下降
当元素个数较少且每个元素较小时,内部编码为ziplist
127.0.0.1:6379[1]> object encoding k2
"ziplist"
当元素个数超过128个,内部编码变为skiplist
127.0.0.1:6379[1]> zadd k4 1 a1 2 a2 3 a3 4 a4 ... 129 a129
127.0.0.1:6379[1]> object encoding k4
"skiplist"
当某个元素大于64字节时,内部编码变为skiplist
127.0.0.1:6379[1]> zadd k5 1 abababab................................................................................
127.0.0.1:6379[1]> object encoding k5
"skiplist"
应用
- 排行榜,例如博客用户的点赞数
-
添加用户的点赞数
tom在2020-12-15获得十个赞,在之后有获取一个赞
127.0.0.1:6379[1]> zadd user:ranking:2020_12_15 10 tom (integer) 1 127.0.0.1:6379[1]> zincrby user:ranking:2020_12_15 1 tom "11"
-
取消用户赞数
如果用户存在作弊,需要将用户删除
127.0.0.1:6379[1]> zrem user:ranking:2020_12_15 tom
-
展示获取赞数最多的十个用户
127.0.0.1:6379[1]> zrevrange user:ranking:2020_12_15 0 9 1) "tom"
-
展示用户信息以及用户表
用户信息可以存在hash类型中
127.0.0.1:6379[1]> hgetall user:info:tom 127.0.0.1:6379[1]> zrank user:ranking:2020_12_15 tom (integer) 0 127.0.0.1:6379[1]> zscore user:ranking:2020_12_15 tom "11"