set 就是把一些有联系的数据放到一起
1)集合中的元素是无序的(与元素排列顺序无关)
2)集合中的元素是唯一的(集合中的元素 - member)
和 list 类似,set 中的每个元素也是 string 类型的
可以使用 json 的格式让 string 也能存储 结构化 的数据
常见命令
sadd
将一个 \ 多个元素添加到 set 中(重复元素不能添加)
sadd key member [member ...]
返回本次成功添加的元素个数 O(1)
smembers
获取一个 set 中所有的元素(元素间的顺序是无序的)
smember key
返回所有元素的列表 O(N)
sismember
判断一个元素是否在 set 中
sismember key member
1 表示在 set 中,0 表示不在 set 中或者 key 不存在 O(1)
scard
获取一个 set 的基数(cardinality),即 set 中元素的个数
scard key
返回 set 中的元素个数 O(1)
spop
从 set 末尾删除并返回一个 \ 多个元素(由于 set 内部是无序的,所以可以视为随机删除)
spop key [count]
返回取出的元素 O(count)
在 Redis 源码中,针对 spop 实现时采用了“生成随机数”的方式
smove
将一个元素从 set 中取出并放到目标 set 中
smove source destination member
返回 1 表示成功,反之返回 0 O(1)
如果给 key1 再添加一个 “1”,然后把 “1” 移动到 key2 中
此时不会报错,由于 set 中元素是唯一的,所以不会出现两个 “1”
srem
将指定元素从 set 中删除
srem key member [member ...]
返回本次删除的元素个数 O(count)
sinter sinterstore
获取给定 set 的交集中的元素
获取到的 set 的交集中的元素并保存到目标 set 中
sinter key [key ...]
返回交集的元素 O(N * M) N 最小的集合的元素个数 M 最大的集合的元素个数
sinterstore destination key [key ...]
返回交集的元素个数 O(N * M) N 最小的集合的元素个数 M 最大的集合的元素个数
sunion sunionstore
获取给定 set 的并集中的元素
获取给定 set 的并集中的元素并保存到目标 set 中
sunion key [key ...]
返回并集的元素 O(N) N 给定的所有的集合的总的元素个数
sunionstore destination key [key ...]
返回并集的元素个数 O(N) N 给定的所有的集合的总的元素个数
sdiff sdiffstore
返回给定 set 的差集中的元素
返回给定 set 的差集中的元素并保存到目标 set 中
sdiff key [key ...]
返回差集的元素个数 O(N) N 给定的所有的集合的总的元素个数
sdiff destination key [key ...]
返回差集的元素 O(N) N 给定的所有的集合的总的元素个数
编码方式
1)intset(整数集合)
为节省空间,做出的特定优化
当元素均为整数,并且元素的个数不是很多时作为集合的内部实现
2)hashtable(哈希表)
C++
std::set 背后的数据结构是 红黑树
Java
Set 本身就是一个接口,这个接口的实现可以是 TreeSet ,也可以是 HashSet
应用场景
1)保存用户“标签”(tag)
用户的兴趣点可以被统计,抽象为一个一个的“标签”,根据标签进行个性化的推荐,匹配等
标签 就是一段简短的字符串,可以存储在 Redis 的 set 中 ——> 用户画像
2)统计 UV
互联网产品衡量用户量 \ 用户规模:
1.PV page view 用户每次访问该服务器,都会产生一个 pv
2.UV user view 每个用户访问服务器,都会产生一个 uv(同一用户多次访问,uv不增加)
uv 需要按照用户进行去重 —— set 内的元素是唯一的