Redis之Set类型和SortedSet类型的介绍和案例应用

一. Set类型基础

1. 类型说明

  1个key→多个value,value的值不重复!

  Set一种无序且元素内容不重复的集合,不用做重复性判断了,和我们数学中的集合概念相同,可以对多个集合求交集、并集、差集,key可以理解成集合的名字。

注:set 用哈希表来保持字符串的唯一性,没有先后顺序,是按照自己的一个存储方式来遍历,因为没有保存插入顺序。

2. 常用指令Api说明

3. 常用Api说明

(1).SetAdd:添加数据,可以单独1个key-1个value,也可以1个key-多个value添加

(2).SetLength:求key集合的数量

(3).SetContains:判断key集合中是否包含指定值

(4).SetRandomMember:随机获取指定key集合中的一个值或n个值

(5).SetMembers:获取key中的所有值,数据类型要一致,便于存储

(6).SetRemove:删除key集合中的指定value(1个或多个)

(7).SetPop:随机删除指定key集合中的一个值或n个值,并返回这些值。

(8).SetCombine:求多个元素的交并差

  a.SetOperation.Intersect:交集

  b.SetOperation.Union:并集

  c.SetOperation.Difference:差集

(9).SetCombineAndStore:把多个元素的交并差,放到一个新的元素集合中

二. Set类型案例

1.抽奖

(1) 背景:用户参与抽奖,抽奖大致分两类:

 A:只抽1次,1次抽n个人。

 B:抽多次,比如三等奖抽3名,二等奖抽2名,一等奖抽1名。

(2) 技术分析:

主要利用Set结构元素的不重复性和获取随机数的方法来实现,以“specialPrize”为key,参与用户的id当做value

A:用户点击参与抽奖则执行SetAdd方法。

B:可以获取所有参与用户SetMembers 和 判断某个用户是否参与抽奖了SetContains

C:随机抽一次奖用SetRandomMember或SetRandomMembers,因为不需要删除

      多次抽奖用SetPop,因为抽完要删掉。

(3) 代码分析

2. 微信或微博中消息的点赞(或者某篇文章的收藏)

(1). 背景

  微信朋友圈用户A的某条消息的点赞功能,要实现点赞、取消点赞、获取点赞列表、获取点赞用户数量、判断某用户是否点赞过。

(2). 技术分析

  利用Set结构, 以用户Id-消息id作为key,点赞过该消息的用户id作为value。

  A:点赞 SetAdd方法

  B:取消点赞 SetRemove方法

  C:获取点赞列表 SetMembers方法

  D:获取点赞用户数量 SetLength方法

  E:判断某用户是否点赞过 SetContains方法

  该案例容易理解,此处不写代码了。

3.关注模型

(1).背景

  比如微博关注或者共同好友的问题,以微博关注为例,要实现:同时关注、关注的和、关注A的用户中也关注B的、当A进入B页面,求可能认识的人。

(2). 技术分析

利用Set结构,一个博主对应一个Set结构,博主的id作为key,关注该博主的用户id作为value。

A:关注和取消关注: SetAdd方法 和 SetRemove方法

B:同时关注:求交集

C:关注的和:求并集

D:关注A的用户中也关注B的:遍历A中的用户,利用SetContains判断是否B中也存在

E:当A进入B页面,求可能认识的人:这里指的是关注B中的用户 扣去 里面也关注A的用户,就是A可能认识的人。

  求差集:B-A

(3). 代码分享

 View Code

4. 利用唯一性,可以统计访问网站的所有IP

三. SortedSet类型基础

1. 类型说明

  将Set中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列, 同样元素名称也不能重复, 三个字段:key-member-score, key键,member值,score:权重或者打分值

2. 常用Api

(1).SortedSetAdd:增加,可以一次增加一个member,也可以一次增加多个member

(2).SortedSetIncrement 和 SortedSetDecrement:Score值自增或自减,如果不存在这member值,则执行增加操作,并返回当前Score值。

(3).获取相关

  SortedSetRangeByRank:根据索引获取member值,默认是升序,可以获取指定索引内的member值

  SortedSetRangeByScore:根据score获取member值,默认是升序,可以获取指定score开始和结束的member值,后面的skip和take用于分页

  SortedSetRangeByValue:根据member获取member值,默认是升序,可以获取指定member开始和结束的值,后面的skip和take用于分页

  SortedSetRangeByRankWithScores:获取member和score值,可以只返回 start-stop 这个索引排序内的值(默认升序),后面的skip和take用于分页

  SortedSetScore:获取指定key指定member的score值

  SortedSetLength:获取集合的数量

(4).删除相关

  SortedSetRemove:删除指定key和指定member,member可以是1个或多个

  SortedSetRemoveRangeByRank:删除指定索引开始到结束

  SortedSetRemoveRangeByScore:删除指定分开始到结束 (5分-8分)

  SortedSetRemoveRangeByValue::删除指定起始值和结束值(这里指定是member)

 

四. SortedSet案例

1. 热词搜索

(1). 需求:

  统计某个网站热词搜索,并实时显示前5名的词及其搜索次数。

PS:实时显示无非就是每隔几秒查询一次,大部分情况我们不建议直接去Redis里查排名,可以把前五名的相关数据存储到Redis的String结构中, 设置5分钟过期。

下面的案例不考虑上面的PS情况,不考虑IP限制问题(前面访问量案例做过),仅仅做最简单的热词搜索,刷新显示

(2).技术分析:

  利用Redis中SortedSet(key-member-score)这一数据结构,利用SortedSetIncrement方法的原子性,每搜索一个词,Score值加1(member不存在则执行的是增加操作), 然后再利用SortedSetRangeByRankWithScores方法获取Score值前五的memeber和Score数据

2.宝宝投票

  分析:和上面的热词原理一样,利用SortedSet的1个key对应多个不重复的 member-score,key用来存储一个标记,比如叫做“AllChildren”,代表该标记下存储宝宝的投票情况,member可以存储

宝宝的标记id,score存储该宝宝的投票数量.

同样原理:利用SortedSetIncrement进行自增存储,利用SortedSetRangeByRankWithScores获取排名情况

3.高积分用户排行榜

   类似案例:主播-粉丝刷礼物的排行榜(同时看主播的排行和每个主播下面粉丝的排行), 原理和上面都一样

 

 

 总结: 

  SortedSet和String利用其自增自减(并返回当前值)原子性均可以实现计数器的作用,String是针对单个,Sorted是针对某个类别下的多个或每一个,并且实现排序功能。 Hash类型也能实现某个类别下多个物品的计数,但它不具有排序功能。