目录
一、介绍
Redis Set对外提供的功能与List类似,是一个列表的功能,特殊之处在于Set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,就可以选择Set。并且Set提供了判断某个成员是否在一个Set集合内的重要接口,这个也是List没有提供的。
Redis的Set是String类型的无序集合,它底层是一个dict字典,hash表实现。Java中HashSet的内部实现是使用的HashMap,其value为null,所有的value都指向同一个对象,Redis的Set结构也是一样,所以添加、删除、查找的复杂度都是O(1)。
一个算法,随着数据的增加,执行时间的长短,如果是O(1),数据增加,查找数据的时间则不变。
总结下来即Redis中的Set是一个hash表,与Java中的HashSet类似,可以看作是一个value为null的HashMap,具有以下特征:
- 无序
- 元素不可重复
- 查找快
- 支持交集、并集和差集等功能
二、Set常用命令
更详细的Redis命令操作指南,请查看Redis官网,有关命令的入口地址如下:
最好的学习方式就是阅读官方文档及源代码
2.1. sadd
sadd <key><value1><value2>...
将一个或多个member元素加入到集合key中,已经存在的member元素将被忽略
2.2. smembers
smembers <key>取出该集合的所有值
2.3. sismember
sismember <key><value>判断集合<key>是否含有该<value>值,有1/没有0
2.4. scard
scard <key>返回该集合的元素个数
2.5. srem
srem <key><value1><value2>...删除集合中的某个元素
2.6. spop
spop <key>随机从该集合中取出一个值
2.7. srandmember
srandmember <key><n>随机从该集合中取出n个值,不会从集合中删除
2.8. smove
smove <source><destination>value 把集合中一个值移到另一个集合
2.9. sinter
sinter <key1><key2>返回两个集合的交集元素
2.10. sunion
sunion <key1><key2>返回两个集合的并集元素
2.11. sdiff
sdiff <key1><key2>返回对比两个集合,返回key1集合里有key2集合里没有的元素
三、应用场景
3.1. 微信抽奖小程序
使用Redis实现该功能非常之简单
1. 点击参与抽奖加入集合
sadd 活动key {userid}
2. 查看参与抽奖的所有用户
smembers 活动key
3. 统计参与抽奖的用户总数
scard 活动key
4. 抽取n名中奖者
srandmember 活动key [n] / spop key [count]
spop可以实现抽取一个后,集合中就会少一个,以此达到每次抽奖人员不一样,能进一步实现一二三等奖。
3.2. 微信微博点赞、收藏、标签
1. 点赞
sadd like:{消息ID} {用户ID}
2. 取消点赞
srem like:{消息ID} {用户ID}
3. 检查用户是否点过赞
sismember like:{消息ID} {用户ID}
4. 获取点赞的用户列表
smembers like:{消息ID}
5. 获取点赞用户数
scard like:{消息ID}
微信朋友圈涉及只能看到共同好友点赞的,需要使用集合操作sinter
3.3. 微信/微博关注模型
1. 胡歌关注的人:
hugeSet -> {tangyan, maobuyi, liuyifei,hejiong,liqin}
2. 毛不易关注的人:
maobuyiSet -> {hejiong,zhouzhennan,xuezhiqian,maoxiaotong,liqin}
3. 我关注的人
mySet -> {huge, maoxiaotong,liqin,mengyitong,xinyuanjieyi}
4. 我和毛不易共同关注:
sinter maobuyiSet mySet --> {maoxiaotong,liqin}
5. 我关注的人也关注他(毛不易)
sismember hugeSet maobuyi
6. 我可能认识的人
sdiff maobuyiSet mySet -> {hejiong,zhouzhennan,xuezhiqian}