Redis05-集合

563 阅读5分钟

Redis的集合

参考

01-redis安装:how2j.cn/k/redis/red…

02-redis学习:<Redis开发与运维>(获取本书PDF见文章末)

定义

它是用来保存多个字符串的元素,元素不可以重复,并且元素是无序的,不能通过索引下标获取元素。Redis除了支持元素的增删改查之外,还支持集合之间的交集、并集和补集。

如下图:集合user:1:follow包含着it、music、his和sports一共4个元素。一个集合最多可以存储2的32次方减1个元素。

命令

常用的命令和时间复杂度

1.集合内
(1)添加元素(sadd)

添加的元素不能重复,否则会返回0。可以看出元素还是无序的。

127.0.0.1:6379> sadd myset a b c
(integer) 3
127.0.0.1:6379> sadd myset a b
(integer) 0
127.0.0.1:6379> smembers myset
1) "c"
2) "a"
3) "b"
(2)删除元素(srem)
127.0.0.1:6379> smembers myset
1) "c"
2) "a"
3) "b"
127.0.0.1:6379> srem myset a b
(integer) 2
127.0.0.1:6379> smembers myset
1) "c"
(3)计算元素个数(scard)
127.0.0.1:6379> smembers myset
1) "c"
127.0.0.1:6379> scard myset
(integer) 1
(4)判断元素是否在集合中(sismember)

元素存在返回1,不存在返回0

127.0.0.1:6379> smembers myset
1) "c"
127.0.0.1:6379> sismember myset c
(integer) 1
127.0.0.1:6379> sismember myset a
(integer) 0
(5)随机从集合中返回指定元个数的元素(srandmember)
127.0.0.1:6379> sadd myset a b d
(integer) 3
127.0.0.1:6379> srandmember myset
"d"
127.0.0.1:6379> srandmember myset
"a"
127.0.0.1:6379> smembers myset
1) "a"
2) "c"
3) "d"
4) "b"
(6)从集合随机弹出元素(spop)
127.0.0.1:6379> spop myset
"d"
127.0.0.1:6379> spop myset
"b"
127.0.0.1:6379> smembers myset
1) "a"
2) "c"

srandmember和spop都是随机从集合选出元素,两者不同的是spop命令执行后,元素会从集合中删除,而srandmember不会。

(7)获取所有元素
127.0.0.1:6379> smembers myset
1) "a"
2) "c"
2.集合间

添加2个集合,分别是user:1:follow和user:2:follow

127.0.0.1:6379> sadd user:1:follow a b c d
(integer) 4
127.0.0.1:6379> sadd user:2:follow a e f d
(integer) 4
(1)交集(sinter)
127.0.0.1:6379> sadd user:1:follow a b c d
(integer) 4
127.0.0.1:6379> sadd user:2:follow a e f d
(integer) 4
127.0.0.1:6379> sinter user:1:follow user:2:follow
1) "a"
2) "d"
(2)并集(sunion)
127.0.0.1:6379> sadd user:1:follow a b c d
(integer) 4
127.0.0.1:6379> sadd user:2:follow a e f d
(integer) 4
127.0.0.1:6379> sunion user:1:follow user:2:follow
1) "c"
2) "a"
3) "e"
4) "d"
5) "b"
6) "f"
(3)补集(差集)(sdiff)
127.0.0.1:6379> sadd user:1:follow a b c d
(integer) 4
127.0.0.1:6379> sadd user:2:follow a e f d
(integer) 4
127.0.0.1:6379> sdiff user:1:follow user:2:follow
1) "c"
2) "b"
(4)将交集、并集、补集的结果保存

集合之间的运算在元素比较多的时候会比较耗时,所以将它们保存起来。

交集

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) "a"
2) "d"

并集

127.0.0.1:6379> sunionstore user:1_2:sunion user:1:follow user:2:follow
(integer) 6
127.0.0.1:6379> type user:1_2:sunion
set
127.0.0.1:6379> smembers user:1_2:sunion
1) "c"
2) "a"
3) "e"
4) "d"
5) "b"
6) "f"

补集

127.0.0.1:6379> sdiffstore user:1_2:sdiff user:1:follow user:2:follow
(integer) 2
127.0.0.1:6379> type user:1_2:sdiff
set
127.0.0.1:6379> smembers user:1_2:sdiff
1) "c"
2) "b"

内部编码

.intset(整数集合)

集合中的元素都是整数,并且元素的个数都小于512个时,redis会采用intset,减少内存的使用。

.hashtable(哈希表)

超过512个元素,redis会选择hashtable。

示例

(1)当元素个数较少,并且都为整数的时候,redis会采用intset
127.0.0.1:6379> sadd mekey 1 2 3 4 5
(integer) 5
127.0.0.1:6379> object encoding mekey
"intset"
(2)当元素大于512个,redis会采用hashtable
127.0.0.1:6379> sadd mekey 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"
(3)当某个元素不为整数的时候,内部编码也会变成hashtable
127.0.0.1:6379> sadd mekey 1 a b d 4 5
(integer) 3
127.0.0.1:6379> object encoding mekey
"hashtable"

使用场景

标签

一个用户对娱乐、新闻感兴趣,另一个用户对历史、科技感兴趣,有了这些数据就可以拿到喜欢同一个类型的用户了,就可以给对应的用户推荐他们感兴趣的内容。

(1)给用户添加标签
127.0.0.1:6379> sadd user:1:tags one two three
(integer) 3
127.0.0.1:6379> sadd user:2:tags one four five
(integer) 3
(2)给标签添加用户
127.0.0.1:6379> sadd one:users user:1 user:3
(integer) 2
127.0.0.1:6379> sadd two:users user:1
(integer) 1

用户和标签的关系应该放在一个事务中执行,防止事务不一致,导致命令执行失败。

(3)删除用户下的标签
127.0.0.1:6379> smembers user:1:tags
1) "two"
2) "one"
3) "three"
127.0.0.1:6379> srem user:1:tags one
(integer) 1
127.0.0.1:6379> smembers user:1:tags
1) "two"
2) "three"
(4)删除标签下的用户
127.0.0.1:6379> smembers one:users
1) "user:1"
2) "user:3"
127.0.0.1:6379> srem one:users user:1
(integer) 1
127.0.0.1:6379> smembers one:users
1) "user:3"
(5)计算用户共同感兴趣的标签
127.0.0.1:6379> smembers user:1:tags
1) "two"
2) "three"
3) "five"
127.0.0.1:6379> smembers user:2:tags
1) "one"
2) "five"
3) "four"
127.0.0.1:6379> sinter user:1:tags user:2:tags
1) "five"

链接:关注公众号Elevenkeep,回复redis即可获得链接。