set的含义
- 集合
- 设置(和get相对应)
集合就是把一些有关联的数据放到一起
- 集合中的元素是无序的(和list的有序是对应的-顺序很重要,这里的无序就是顺序不重要);在list中[]1,2,3],[1,3,2],是两个不同的list,如果是集合就是同一个集合
- 集合中的元素是不能重复的(唯一的)
和list类似,集合中的每个元素也都是string类型(可以使用json这样的格式让string也能存储结构化数据)
set的常见命令
sadd
- 将⼀个或者多个元素添加到 set 中。注意,重复的元素⽆法添加到 set 中
- 时间复杂度:O(1) 返回值:本次添加成功的元素个数
- 把集合中的元素称为member,就像hash类型中叫做field类似
- 不能重复,看返回值即可
smembers
- 获取⼀个 set 中的所有元素,注意,元素间的顺序是⽆序的。
- 时间复杂度:O(N) 返回值:所有元素的列表。
sismember
- 集合的操作都是带有S前缀的,判断⼀个元素在不在 set 中。
- 时间复杂度:O(1) 返回值:1 表⽰元素在 set 中。0 表⽰元素不在 set 中或者 key 不存在。
spop
- 从 set 中删除并返回⼀个或者多个元素,本来删除末尾,但是无法辨认,使用spop删除元素,所以随即删除
- 注意,由于 set 内的元素是⽆序的,所以取出哪个元素实际是 未定义⾏为,即可以看作随机的。
- 时间复杂度:O(N), n 是 count 返回值:取出的元素。
删除的顺序和插入的顺序无关,是随机的过程
如果我再次构造一个1 2 3 4这样的集合,此时还是通过4次spop进行删除,删除顺序是否还是1234呢?
由此可知,spop是一个随机的删除过程,并且在官方文档上也承认是真正随机的删除
srandmember
随机从key中获取count个随机元素
其实开发者开源码中,针对spop实现的时候,就采取了“生成随机数”的方式
smove
将⼀个元素从源 set 取出并放⼊⽬标 set 中:把member从source上删除,再插入到destination上
时间复杂度:O(1) 返回值:1 表⽰移动成功,0 表⽰失败
如果在key中添加1,此时再进行移动,会怎样?
key中元素减少,key2元素不变;还是会按照插入删除的顺序进行操作
如果要移动的元素不存在呢?
返回0表示失败
srem
将指定的元素从 set 中删除:可以一次删除一个member,也可以删除多个
时间复杂度:O(N), N 是要删除的元素个数. 返回值:本次操作删除的元素个数。
集合间操作
- 交集(inter):最终结果同时出现在两个集合中
- 并集(union):把多个集合中的数据都集中放在一起,如果元素有重复,也最终只保留一份
- 差集(diff):A和B做差集,就是找出哪些元素,在A中存在,同时在B中不存在
sinter
- 获取给定 set 的交集中的元素:此处每个key都对应一个集合
- 时间复杂度:O(N * M), N 是最⼩的集合元素个数. M 是最⼤的集合元素个数
- 返回值:交集的元素。
sinterstore
- 获取给定 set 的交集中的元素并保存到⽬标 set 中。
- 时间复杂度:O(N * M), N 是最⼩的集合元素个数
- M 是最⼤的集合元素个数. 返回值:交集的元素个数。
- 要想直到交集中的元素,只需要按照访问集合的方式进行访问即可
sunion
- 获取给定 set 的并集中的元素。
- 时间复杂度:O(N), N为给定的所有集合的总的元素个数
- 返回值:并集的元素。
sunionstore
- 获取给定 set 的并集中的元素并保存到⽬标 set 中。
- 时间复杂度:O(N), N 给定的所有集合的总的元素个数
- 返回值:并集的元素个数。
sdiff
- 获取给定 set 的差集中的元素
- 时间复杂度:O(N), N 给定的所有集合的总的元素个数
- 返回值:差集的元素
sdiffstore
- 获取给定 set 的差集中的元素并保存到⽬标 set 中
- 时间复杂度:O(N), N 给定的所有集合的总的元素个数
- 返回值:差集的元素个数
set命令小结
序号 | 命令及描述 |
---|---|
1 | SADD key member1 [member2] 向集合添加一个或多个成员 |
2 | SCARD key 获取集合的成员数 |
3 | SDIFF key1 [key2] 返回第一个集合与其他集合之间的差异。 |
4 | SDIFFSTORE destination key1 [key2] 返回给定所有集合的差集并存储在 destination 中 |
5 | SINTER key1 [key2] 返回给定所有集合的交集 |
6 | SINTERSTORE destination key1 [key2] 返回给定所有集合的交集并存储在 destination 中 |
7 | SISMEMBER key member 判断 member 元素是否是集合 key 的成员 |
8 | SMEMBERS key 返回集合中的所有成员 |
9 | SMOVE source destination member 将 member 元素从 source 集合移动到 destination 集合 |
10 | SPOP key 移除并返回集合中的一个随机元素 |
11 | SRANDMEMBER key [count] 返回集合中一个或多个随机数 |
12 | SREM key member1 [member2] 移除集合中一个或多个成员 |
13 | SUNION key1 [key2] 返回所有给定集合的并集 |
14 | SUNIONSTORE destination key1 [key2] 所有给定集合的并集存储在 destination 集合中 |
15 | SSCAN key cursor [MATCH pattern] [COUNT count] 迭代集合中的元素 |
set内部编码
intset(整数集合)
为了节省空间,做出的特定的优化,当元素均为整数,并且元素个数不是很多的时候,内存数据库,更节省空间
hashtable(哈希表)
set的应用场景
使用set来保存用户的”标签“
- 用户画像:分析出你这个人的一些特征(性别,年龄,居住地,爱好),分析清楚之后,再投其所好,所谓的标签就是用户的个人特征-简短的字符串
- 此时就可以把标签保存到redis中的set中了,用户画像,这种事情其实是挺复杂的事情
- set方便计算交集,很容易的找到两个用户之间的公共标签,基于这样的标签,衍生出一些”用户关系“
使用set来计算用户之间的共同好友
基于”集合求交集“,例如QQ两个用户都加了很多好友,可以得出用户之间的共同好友,基于上述还可以做一些好友推荐
使用set统计UV,使用去重
一个互联网产品,如何衡量用户量,用户规模?
- PV-page view 用户每次访问该服务器,每次访问都会产生一个pv
- UV-user view 每个用户,访问服务器,都会产生一个uv,但是同一个用户多次访问,不会使uv增加,uv需要按照用户进行去重,上述的去重过程,就可以使用set来实现