Redis 基础命令--进阶篇

今天又扫了一章《Redis入门指南》第4章 进阶,被 sort 指令卡了好久,所以我会重点讲解 sort 指令。

第一个知识点--事务

这个在关系型数据库里经常听见--一组命令的集合,其中的命令要不全部执行,要不全部不执行,在 redis 里面也有这样的操作命令。

基本语法:

multi

redis commands

exec

在 multi 与 exec 之间的命令直到用户输入 exec 之前是不会执行的,所以没有办法判断你的输入逻辑上是否有错误,只能判断语法上是否有错。如下面这个例子:

multi
set string value
hset string field value
exec
第一个 set 将 string 存储成字符串类型,接下来又将 string 存储成散列类型,但是由于 set string field value 这条命令本身的语法没有出错,所以不会出现错误提醒。

再来补充一个命令 

watch key
这个命令可以监视一个 key,也就是在执行 watch key 之后,如果 key 改变的话,接下来针对该 key 的全部事务全部不会执行,例:

set key 1
watch key 
set key 2
multi 
set key 3
exec
最后的结果为 2,因为在 watch key 之后又执行了 set key 2,改变了 key 的值,所以接下来的事务没有执行,即 set key 3 这条命令没有执行。有点像关系型数据库中的锁,但是锁能保证在被锁期间不会被除自己之外的进程修改,这里的 watch 却只能监视该数据是否做出修改,无法阻止。

可以使用 unwatch 解除监视。

第二个知识点--过期时间

可以设置一个 key 的存活时间(TTL time to live),现在这里介绍几个英文单词,因为我英文不怎么好,省的下次又要去查字典

expire  文件、协议(因到期而)失效

persist 继续存在

msec   毫秒

基本语法:

expire key seconds

pexpire key msec

ttl key // 查看还有多久时间才过期

persist key // 将该 key 转变成永久存储模式

注意点

1、如果在这是了一个 key 的过期时间之后再对该 key 执行 set 和 get 操作的话,那么跟执行 persist key 的作用是一样的,该 key 都会变成永久存储模式

2、如果在为一个 key 设置过 expire key seconds 之后再执行一遍 expire key seconds 则会重新开始计时

3、ttl key 的返回值是有含义的,正常情况就不说了,当返回 -1 时表示该 key 没有设置过过期时间,-2 表示该 key 不存在,0 的话,你能掐的那么准吗?偷笑

第三个知识点--排序

先补充一下通配符的介绍,下面要用到:

?	匹配任意一个字符
*	匹配任意数量字符
[]  匹配在 [] 中的任意一个字符
\	转义

在关系型数据库中我们常用 order by 来进行排序,在 redis 中使用 sort by,为了理解,我先列了这么一条公式:

sort 集合、有序集合、列表 by 散列*->field get 散列*->field [limit offset count] [desc] [alpha]

这是我个人感觉排序的用法,因为我在 windows 系统上安装的 redis 不是 redis 官方支持的 redis,是 windows 自己移植过来的,书上的代码我执行是会报错的,不知道是我自己理解错误还是怎么会是,我尝试了很久,总结出了上面的那条公式,为便于理解,我举下面这个例子:

使用集合存储一个班学生的 id 号,这里我们简化一下只有3名同学,id 分别为1、2、3

sadd id 1 2 3
之后我们采用散列表的形式来存储学生的个人信息,包括数学课成绩、体育课成绩。

hset student:1 name yang math 80 pe 50
hset student:2 name hao math 90 pe 95
hset student:3 name wang math 80 pe 80 
这里 student: 后面的数字表示学生的 id

接着我想按照数学成绩来对这3名同学进行排列,应该怎么写 redis 的命令呢?

sort id by student:*->math get student:*->name desc
这句话本质上做了什么呢?

其实他只是对 id 中的1、2、3进行了一个排序,排序的规则是按照 student:* 筛选出来的散列表的 math 字段进行排列的,最后再返回 student:* 散列表的 name 字段的值,顺便使用 desc 进行从大到小的排序,默认的排序是从小到大的。那么 math 成绩一样的 yang 和 wang呢?则按照 student:* 中的 * 来排序。所以最后的结果是:

hao 

wang

yang

sort by 的重点在哪里呢?就在 by 后面的参考点的筛选上,如果没有 student:* 的表,即 student:1、student:2、student:3,那么针对 id 进行排序没有任何意义,正是因为 student:* 匹配到了 student:1、student:2、student:3,才赋予了 id 排序的含义。具体的使用场景肯定不止我上面讲的这一种,还是自己去尝试一下比较好,现在只是掌握了基础的语法,到具体的应用还有一段差距的。

还有几个关键字

limit offset count 

作用跟关系数据库中是一样的,限制返回的数量,offset 偏移量,count 返回的数量。

还可以使用关键字 store 存储最后的排列结果。

顺便再加一句 * 要在 -> 前面使用才有用。

第四个知识点--消息通知

这个知识点可以结合上一篇的列表知识来理解,是列表的升级版。

基本语法:

brpop key1 timeout1 key2 timeout2 key3 timeout3

blpop key1 timeout1 key2 timeout2 key3 timeout3


brpop 与 rpop 一样,是从列表类型的 key 中从右边取出第一个数据,不同的是,rpop 当当前列表为空时就会返回 nil (no list),但是 brpop 则会等待 timeout 秒的时间,如果在 timeout 之前有数据存入则会自动取出显示,blpop 也是一样的。当设置多个 timeout 时,以最大的 timeout 作为超时时间,当其中一个有数据输出则停止全部的等待。

例:

在 redis-cli.exe 中输入以下内容:

brpop key1 10 key2 60

在大约20多秒的时候再打开一个 redis-cli.exe 输入以下内容:

rpush key1 100

在最开始打开的 redis-cli.exe 中就会显示以下内容,并且退出 brpop 的等待时间:

key1
100
(20.96s)

可以看到上面设置的 key1 的 timeout 是10,可是10s 后还是有效的,这就说明是以最长过期时间为准的,如果想要永久有效,要不直接不写,或者写0.

最后的结果:


这个有什么用呢?书上的例子是说用来处理以下情况的:

当一个博主发表一篇文章后,都发一封邮件给订阅他博客的人,通知他们订阅的博客更新了,所以数据库会存储这些订阅者的邮箱,但是为了验证该邮箱的有效性,所以在用户输入完一个邮箱之后都会发送一封确认邮件到用户的指定邮箱,用户需要点击邮箱中的链接地址才能完成验证,但是问题就来了,一定是拿列表来存储这些需要验证的邮箱,但是如果采用一般的 rpop 或者 lpop,每次都需要判断一下该队列是否为空,不为空的话就执行 rpop,那么意味着我们在控制器端需要一直监视这个队列的情况。但是采用 brpop 之后,如果队列为空的话,就会一直等待,直到添加如数据,并把数据取出,这些都可以交由 redis 内部去执行,而不需要我们额外使用第三方代码实现。

除了上面的内容,还有一个发布/订阅的模式:

基本语法2:

publish channel message

subscribe channel1 channel2 channel3


publish     发布

subscribe 订阅

一个线程调用 subscribe channel1 channel2 channel3
一个线程调用 publish channel message
如果 subscribe 的 channel1、channel2、channel3 与 publish 的 channel 一致就会接收到 message,否则就没有
可以尝试以下下面的代码就懂了


注意,subscribe 可以一次性订阅多个 channel,但是 publish 每次却只能往一个 channel 中发送数据。

但是这样就会存在问题,当一次订阅多个 channel 时就要每个输入一遍,可以使用通配符来解决这个问题
psubscribe pattern 
例:
psubscribe channel1.?* 
这样就可以同时订阅例如 channel1.1、channel1.100、channel1.40等,通配符的含义在字符串类型中讲解过了。

第五个知识点--管道

就是将多条命令存储在一起,从客户端,也就是--redis-cli.exe 中传入到 redis 一起进行处理,再将结果返回,有点像事务,但是不像事务一定要每条命令都i执行完毕,本质上管道就是把多条互不相连的命令一起发送给 redis,然后再统一将处理结果发送回来而已。这个是通过第三方编程语言来实现的,不是 redis 本身的命令。

感觉越到越后面越想说一句,码字好幸苦。快哭了


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值