Redis各种键的使用场景,不清楚的都来看一下
Our-task介绍
本篇博客是我的github上项目our-task:一个完整的清单管理系统的配套教程文档,大家感兴趣的话,可以去看看
字符串
字符串是Redis中最基础的数据类型,其他几种数据结构都是从该基础上构建的。
缓存
典型的场景就是:Redis作为缓存层,Mysql作为存储层,当请求过来的时候,先根据键名从Redis中查找,找到该键就直接取出该键的值,如果没有找到键的话,就从Mysql中查询,并把查询的结果回写到Redis中去,同时设置键过期时间。这样的话,绝大部分请求,都是从Redis中读取的。
以our-task为例,数据库user表里有一个id为1,username为“小风”的记录,那么该键就可以为:our-task:user:1:username,对应的值为:小风,此时该键的命名方式为——库名:表名:id:属性名
当然,这样命名的话,键的长度会比较长,同时也会占用更大的内存,所以需要我们在能够描述清楚键的含义的情况下,尽量减少键名的长度
限速
就像手机获取验证码一样,我们会发现每次我们获取验证码之后,需要再过一分钟才能重新获取验证码,这是为了保护我们的短信接口不被频繁地访问。
具体的做法为:
isExists = redis.set(key, 1, "EX" 60, "NX")
if(isExists != null || redis.incr(key) <= 5){
//通过
}
// "EX" 60 表示设置该键的过期时间为60秒
// "NX"表示该键只有在该键不存在的时候,才能创建成功
// redis.incr(key)表示每次把该键的值增加1
也就是说,这段代码是表示:该键每分钟被调用不超过5次
共享Session
分布式服务会使用共享均衡,将用户的访问分配到不同的服务器上,但是如果用户的Session存放在各自的服务器上的话,用户就会在刷新的时候需要重新登录了,所以可以使用Redis来会Session进行集中管理,每次用户需要获取Session的时候,都直接从Redis中获取。
哈希
Redis本身就是一个键值对的数据库了,一个键对应一个值,哈希类型就是说:该值本身又是一个哈希结构。
存储数据库表
在关系型数据库中,我们的表是这样存储的
id | name | age | sex |
---|---|---|---|
1 | 小明 | 15 | 女 |
2 | 小风 | 22 | 男 |
使用Redis的哈希来存储,我们的表就可以这样来存取
键为:user:1,对应的值为下面的这个表格
id | 1 |
---|---|
name | 小明 |
age | 15 |
city | 女 |
获取用户id为1对应的name,则可以这样写:hget user:1 name
将id为1对应的name修改为:小张,则可以这样写:
hset user:1 name 小张
列表
Redis的列表用来存储多个有序的字符串,这里的有序指的是元素是依次放入的,比如从右边插入,该元素就会跑到列表的最后一个位置。每个字符串又被称为元素,列表中的元素可以重复,可以对这些元素进行两端插入和弹出、获取指定范围的元素列表等操作,也可以通过下标来获取值,如传入0,则可以获取第一个元素,传入-1获取最后一个元素等
消息队列
由于列表可以在两端进行插入和弹出,所以可以当做一个消息队列。生产者在一端把生产的元素插入进去,消费者在另外一端进行数据消费。
栈
使用lpush和lpop,在一端进行插入,在这一端同时进行弹出,就可以实现栈的结构了
队列
和消息队列类似,在一端进行插入,在另一端进行弹出即可实现
集合
集合也是用来保持多个元素的,但和列表的区别就在于,集合是不允许存在重复元素的,另外,集合里面的元素是无序的,故不能通过下标来索引。Redis除了支持集合内元素的增删改查,还支持让集合之间取并集、交集等操作。
标签
标签是集合比较典型的使用场景。以our-task为例,一个清单的名字为:写代码,我可以把它放入“工作”这个标签下,也可以把它放在“学习”这个标签下
那么我们的键名可以是—— task:1:label,表示清单id为1的所有标签的集合,值为label的id即可。使用Redis提供的集合操作,我们进行增删改查都会很方便。
抽奖
针对抽奖的流程,我们都知道当抽取一个数x之后,x就再也不能被抽到,也就是被移除了,我们使用集合来实现的话,就可以先生成一些数放在集合里面。然后使用以下方法来实现抽奖。
spop:移除并返回集合中的一个元素
srandmember:返回集合中一个或多个随机数(不移除元素)
有序集合
有序集合也是一种集合,它可以排序,但是和列表使用下标来排序不同,有序集合会设置一个分数作为排序的依据,类似下表
score | member(学号) |
---|---|
1 | 34343 |
50 | 34323 |
100 | 54443 |
虽然元素不能重复,但是这个分数是可以重复的,就和班级里面的考试分数一样,分数可以重复,但是每个人的学号不能重复
排行榜系统
比如某个用户上传了一个视频,这个视频是有点赞数的
每一次点赞,我们可以给该用户的这个视频加3分
如果用户作弊的话,我们可以直接把改用户删除,或者把改用户的视频,从有序集合里面删除
我们也可以通过有序集合的方法:zrevrange(返回有序集中指定区间内的成员,通过索引,分数从高到低),获取排名前十的视频
等等这些操作,都是可以通过有序集合提供的方法来实现的
字符串和哈希总结
列表和哈希,看起来都能够存储数据库表里面的记录,但是我们需要把这些特点搞清楚,才能在开发中灵活运用
- 字符串类型:每个属性是一个键
- 优点:简单直观,每个属性都可以进行更新删除操作
- 缺点:占用太多的键,从而内存比较大,属性和属性之间没有关联性,一般不考虑在生产环境使用
- 哈希类型:每个属性是一对field-value,但是是用一个key来保存的
- 优点:简单直观,合理使用可以减少内存空间
- 缺点:注意存储的长度,否则哈希会在ziplist和hashtable两种内部编码之间转换,hashtable消耗更多的内存