Redis-API理解和使用-集合(set)

集合(set) 类型也是用来保存多个的字符串元素, 但和列表类型不一样的是, 集合中不允许有重复元素, 并且集合中的元素是无序的, 不能通过
索引下标获取元素。
Redis除了支持集合内的增删改查, 同时还支持多个集合取交集、 并集、 差集, 合理地使用好集合类型, 能在实际开发中解决很多实际问题。

1 命令

1.集合内操作
(1) 添加元素
sadd key element [element ...]

127.0.0.1:6379> exists myset
(integer) 0
127.0.0.1:6379> sadd myset a b c
(integer) 3
127.0.0.1:6379> sadd myset a b
(integer) 0

(2) 删除元素
srem key element [element ...]
返回结果为成功删除元素个数, 例如:

127.0.0.1:6379> srem myset a b
(integer) 2
127.0.0.1:6379> srem myset hello
(integer) 0

(3) 计算元素个数
scard key
scard的时间复杂度为O(1) , 它不会遍历集合所有元素, 而是直接用
Redis内部的变量, 例如:

127.0.0.1:6379> scard myset
(integer) 1

(4) 判断元素是否在集合中
sismember key element
如果给定元素element在集合内返回1, 反之返回0, 例如:

127.0.0.1:6379> sismember myset c
(integer) 1

(5) 随机从集合返回指定个数元素
srandmember key [count]

127.0.0.1:6379> srandmember myset 2
1) "a"
2) "c"
127.0.0.1:6379> srandmember myset
"d"

(6) 从集合随机弹出元素
spop key

127.0.0.1:6379> spop myset
"c"
127.0.0.1:6379> smembers myset
1) "d"
2) "b"
3) "a"

需要注意的是Redis从3.2版本开始, spop也支持[count]参数。
srandmember和spop都是随机从集合选出元素, 两者不同的是spop命令执行后, 元素会从集合中删除, 而srandmember不会。
(7) 获取所有元素
smembers key
下面代码获取集合myset所有元素, 并且返回结果是无序的:

127.0.0.1:6379> smembers myset
1) "d"
2) "b"
3) "a"

smembers和lrange、 hgetall都属于比较重的命令, 如果元素过多存在阻塞Redis的可能性, 这时候可以使用sscan来完成。
2.集合间操作
现在有两个集合, 它们分别是user: 1: follow和user: 2: follow:

127.0.0.1:6379> sadd user:1:follow it music his sports
(integer) 4
127.0.0.1:6379> sadd user:2:follow it news ent sports
(integer) 4

(1) 求多个集合的交集
sinter key [key ...]

127.0.0.1:6379> sinter user:1:follow user:2:follow
1) "sports"
2) "it"

(2) 求多个集合的并集
suinon key [key ...]

127.0.0.1:6379> sunion user:1:follow user:2:follow
1) "sports"
2) "it"
3) "his"
4) "news"
5) "music"
6) "ent"

(3) 求多个集合的差集
sdiff key [key ...]

127.0.0.1:6379> sdiff user:1:follow user:2:follow
1) "music"
2) "his"

(4) 将交集、 并集、 差集的结果保存
sinterstore destination key [key ...]
suionstore destination key [key ...]
sdiffstore destination key [key ...]

127.0.0.1:6379> sinterstore user:1_2:inter user:1:follow user:2:follow
(integer) 2
127.0.0.1:6379> type user:1_2:inter
set
127.0.0.1:6379> smembers user:1_2:inter
1) "it"
2) "sports"

2 内部编码

集合类型的内部编码有两种:
·intset(整数集合) : 当集合中的元素都是整数且元素个数小于set-maxintset-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"

2.1) 当元素个数超过512个, 内部编码变为hashtable:

127.0.0.1:6379> sadd setkey 1 2 3 4 5 6 ... 512 513
(integer) 509
127.0.0.1:6379> scard setkey
(integer) 513
127.0.0.1:6379> object encoding listkey
"hashtable"

2.2) 当某个元素不为整数时, 内部编码也会变为hashtable:

127.0.0.1:6379> sadd setkey a
(integer) 1
127.0.0.1:6379> object encoding setkey
"hashtable"

3 使用场景

集合类型比较典型的使用场景是标签(tag) 。 例如一个用户可能对娱乐、 体育比较感兴趣, 另一个用户可能对历史、 新闻比较感兴趣, 这些兴趣
点就是标签。 有了这些数据就可以得到喜欢同一个标签的人, 以及用户的共同喜好的标签, 这些数据对于用户体验以及增强用户黏度比较重要。
下面使用集合类型实现标签功能的若干功能。
(1) 给用户添加标签

sadd user:1:tags tag1 tag2 tag5
sadd user:2:tags tag2 tag3 tag5
...
sadd user:k:tags tag1 tag2 tag4
...

(2) 给标签添加用户

sadd tag1:users user:1 user:3
sadd tag2:users user:1 user:2 user:3
...
sadd tagk:users user:1 user:2
...

(3) 删除用户下的标签

srem user:1:tags tag1 tag5
...

(4) 删除标签下的用户

srem tag1:users user:1
srem tag5:users user:1
...

开发提示
前面只是给出了使用Redis集合类型实现标签的基本思路, 实际上一个标签系统远比这个要复杂得多, 不过集合类型的应用场景通常为以下几种:
·sadd=Tagging(标签)
·spop/srandmember=Random item(生成随机数, 比如抽奖)
·sadd+sinter=Social Graph(社交需求)
 

备注:文章参考《Redis开发与运维》,作者:付磊,张益军

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值