一. Set 类型
1.1 简介
[1] Redis的 Set 是 String 类型的无序集合,集合成员是唯一的,这就意味着集合不会出现重复的数据
[2] Redis中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。集合中最大的成员数为 2^32 -1(每个集合可以存储40多亿个成员),类似于Java中的 Hashtable 集合
[3] redis的集合对象 set 的底层存储结构特别稀奇,底层使用了 intset 和 hashtable 两种数据结构存储的,intset 我们可以理解为数组, hashtable 就是普通的哈希表(key为 set 的值,value 为 null)
[4] intset 内部其实是一个数组(int8_t conentents[] 数组),而且存储时候是有序的,因为在查找数据的时候通过二分查找来实现的。
1.2 命令
[1] 赋值语法:
sadd key member1 [member2] # 向集合添加一个或多个成员
例如: sadd s1 a b c # 向集合s1添加 a,b,c 这三个成员
[2] 取值语法
scard key #获取集合的成员数
例如: scard s1 # 返回 s1 集合中的成员数
smembers key #返回集合中所有成员
例如:smembers s1 #返回s1集合中所有成员
sismember key member # 判断member 元素是否是集合 key 的成员(开发中:验证是否存在判断)
srandomember key [count] # 返回集合中一个或多个随机数
[3] 删除语法:
srem key member1 [member2] # 移除集合中一个或多个成员
spop key [count] # 移除并返回集合的一个随机元素
smove source destination member # 将member 元素从source集合移动到destination
例如: smove s1 s2 a # 将s1中的成员a移动到s2中
[4] 差集语法:
sdiff key1 [key2] # 返回给定所有集合的差集 (左侧)
例如: sdiff s1 s2 # 返回的结果为 s1 - s2 (差集)
sdiffstore destination key1 [key2] #返回给定所有集合差集并存储在destination中
例如: sdiffstore s3 s1 s2 # 把s1 - s2 的结果存在s3中
[5] 交集语法:
sinter key1 [key2] #返回给定所有集合的交集(共有数据)
例如: sinter s1 s2 #返回s1 n s2 的结果
sinterstore destination key1 [key2] #返回给定所有集合的交集并存储在destination中
例如: sinterstore s3 s1 s2 #把s1 n s2的结果存入s3中
[6]并集语法:
sunion key1 [key2] #返回所有给定集合的并集
sunionstore destination key1 [key2] # 所有给定集合的并集存储在destination集合中
1.3 应用场景
常应用于:对两个集合的数据[计算] 进行交集,并集,差集运算
[1].以非常方便的实现如共同关注,共同喜好,二度好友等功能。对上面所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存储到一个新的集合中
[2].利用唯一性,可以在统计访问网站所有独立IP
二. 有序集合(sorted set) ZSet
1.1 简介
[1] Redis有序集合,和集合一样也是string 类型元素的集合,且不允许重复的成员
[2] 不同的是每个元素都会关联一个double 类型的分数。redis 正是通过分数来为集合中的成员从小到大排序
[3]有序集合的成员是唯一的,但分数(score)却可以重复
[4] 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。集合中对打的成员数为 2^32 -1 (每个集合可存储40多亿个成员)
[5]Redis的ZSet是有序,且不重复
(很多时候,我们都将redis中的有序集合叫做zset,这是因为在zset中,有序集合相关的操作都是以z开头的)
1.2 命令
[1] 赋值语法:
zadd key score1 member1 [scorce2 member2] # 向有序集合添加一个或多个成员,或者更新已存在成员的分数
例如: zadd z1 75 Java #向有序集合z1中添加成员Java,并给它赋一个关联的分数75
[2] 取值语法:
zcard key #获取有序集合的成员数
zount key min max #计算在有序集合中指定区间分数的成员数
例如: zcount z1 60 80 # 计算出有序集合中分数在60到80之间的成员个数
zrank key member #返回有序集合中指定成员索引
例如: zrank z1 Java #返回有序集合z1中Java的相关索引(即排名)
zrange key start stop [WITHSCORES] #返回有序集合中指定区间的成员,通过索引,分数从低到高
zrevrange key start stop[WITHSOURCES] #返回有序集中指定区间内的成员,通过索引,分数从高到低
例如: zrevrange z1 0 -1 # 按分数从高到低对有序集合z1进行排序并返回(0到-1表示一整个集合)
[3] 删除语法:
del key # 移除集合
zrem key member [member.....] # 移除有序集合中的一个或多个成员
例如:zrem z1 Java # 移除有序集合z1中的Java成员
zremrangebyrank key start stop # 移除有序集合中给定的排名区间的所有成员(第一名是0)(低到高排序)
例如: zremrangebyrank z1 0 2 #移除有序集合z1中排名前三的成员
zremrangebyscore key start stop #移除有序集合中给定分数区间的所有成员
例如: zremrangebyscore z1 60 80 #移除有序集合z1中分数为60到80之间的成员
1.3 应用场景
常应用于:排行榜
[1].比如 twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。
[2].比如一个存储全班同学成绩的 Sorted Set,其集合 value 可以是同学的学号,而 score 就可以使其考试得分,这样数据插入集合的时候,就已经进行了天然的排序
[3].还可以用Sorted Set 来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择score得倒序来获取任务。让重要的任务优先执行。