列表/集合排序与Redis事务

本文介绍了Redis中集合的排序功能,包括按权重和字母顺序排序,并详细解释了SORT命令的使用,如ALPHA和LIMIT修饰符。同时,文章探讨了Redis事务,与关系型数据库事务的区别,强调Redis事务不支持回滚,但仍然保持原子性。
摘要由CSDN通过智能技术生成

目录

集合排序

按权重进行排序

Redis事务

Redis事务和关系型数据库事务区别


      排序重要性毋庸置疑,基本上大家看的算法书,编程语言书都会讲到各种各样的排序算法,现在基本上都有封装好的排序算法工具包,直接拿来用就可以了,不需要重复造轮子,Java语言对ArrayList就有sort()方法可以直接调用。在Redis中,列表和集合里的元素都是无序的,有序集合虽然有序,但它的排序方式是按照权重来排序,如果我们想按照元素的值来排序,Redis也提供了SORT命令为集合进行排序,这篇日志就来总结下排序SORT命令。

 

集合排序

       由于Redis无序集合里存储的对象都是唯一且无序的,当我们用SADD命令创建一个无序集合后,可以通过SORT命令对集合进行升序或者降序排序:

      SORT命令可以返回一个集合或者列表经过升序or降序排序后的结果,要注意的是SORT命令不会对原列表/集合进行改变,排序后你用LRANGE查看列表或SMEMBERS命令查看集合会发现里面元素还是无序的。SORT默认是升序排序,想要降序添加修饰符DESC即可。

      我们的集合中不一定是存放数值元素的,如果存放的是字符串,例如播放歌单里存放的歌曲名,是字符串形式,可以用SORT命令进行排序吗?当然可以,看我们平时用的音乐播放APP里对歌曲名排序方式是字母顺序,即从A到Z:

      在一个集合MusicList中放入若干首歌曲名,都是字符串的形式,如果我们想对其按照字母顺序排序,需要在SORT命令后加上修饰符ALPHA,如上图所示,SORT “MusicList” ALPHA DESC命令会以降序的方式返回排序后的集合。排序时我们还可以指定返回排序的元素数量,使用的修饰符是LIMIT,例如我们指向返回歌单中前五首歌,可以在SORT后面加上LIMIT 0 5,这里要注意的是,数字0和5分别表示的是排序元素的起始位置和返回的元素个数,也就是说0 5表示从起始偏移量为0的元素开始,排序返回5个元素,而不是排序返回偏移量0到5的元素。如上图的第三条指令所示,如果我们指定LIMIT 5 1,表示的是从起始偏移量为5的元素,即“Somebody”开始,返回元素为1个,即只有Somebody本身。

 

按权重进行排序

       除了按键值(value)进行排序外,SORT命令还可以直接对键key的数据进行排序,例如我们的歌曲数据由三部分组成,song_id,歌曲名song_name和播放了song_times,存储方式为列表存储song_id,两个字符串分别存储歌曲名和播放量,此时如果我们想按照键歌曲播放量来排序,或者按照键歌曲名字母顺序来排序,可以用SORT命令加上BY修饰符实现:

      把歌曲信息按格式录入后,命令SORT “song_id” BY “song_times_*”命令的作用是先取出每一个song_id,即1,2,3,然后匹配到song_times_1、song_times_2、song_times_3的值作为排序的权重,它们的值分别是39,12和22,所以默认升序排序得到的歌曲播放量排名id为2,3和1。如果我们想根据id对歌名进行排序,排序结果中将歌名一一列出,可以用到GET修饰符,它可以取出key对应的值value,如上图所示,SORT “song_id” GET “song_name_*”命令根据id排序后,id为1,2,3的歌曲名分别对应“Intention”,“Mistletoe”和“Yummy”,如果我们不想输出id,而是想获取歌名,通过GET修饰符便可实现。当然也可以直接写成想第三条指令那样,更加明了,匹配歌曲id,BY修饰符根据播放量进行排序,输出结果通过GET获取歌名,得到的序列就是根据播放量升序并显示歌名的歌单。

 

Redis事务

       在学习关系型数据库时相信大家都接触到事务,事务就是一系列的原子性操作,原子性就是这一组操作要么全部执行成功,要么失败全部不执行,除了原子性之外还有一致性,隔离性和持久性等。Redis作为键值数据库,同样有“事务”这个概念,但是和关系型数据库有点区别,先来看一下Redis事务。

      Redis中实现事务的命令有四个,WATCH、MULTI、EXEC和DISCARD,开始事务命令为MULTI,提交事务命令为EXEC,取消事务命令为DISCARD。当一个Redis事务通过MULTI开始时,并不会被立刻执行,而是先被放入一个队列中等待(先进先出),当遇到EXEC提交事务命令后,才会将队列中的事务拿出来执行。

      使用MULTI命令标识一个事务块的开始,然后下面编写的命令都会按顺序一一入队列,最后通过EXEC命令提交事务,执行完毕后用GET命令获取刚刚设置的字符串,可以看到事务执行成功。如果我们在事务块最后使用DISCARD命令,即取消事务的执行,那么事务块中所有的命令都不会被执行,事务的原子性嘛,要么全部执行,要么全部不执行,使用GET命令获取被取消的事务块设置的字符串也可以看到,song_1没有被修改,song_5键对应的值为空。

 

Redis事务和关系型数据库事务区别

       那么Redis事务和关系型数据库事务有什么区别呢?Redis事务是否也是一组原子性操作?它们的关键区别在于关系型数据库事务支持回滚,Redis事务不支持,或者说,只支持一半。为什么说是支持一般?因为前面说了,Redis事务在执行前需要入队,假设事务中某条命令出现错误,如命令语法错误,此类错误在事务执行前就会被发现,结果是整个事务中的命令都不会执行;第二种情况是命令没有错误,事务顺利执行,但在执行过程中出现错误,如对一个字符串数据进行加减操作,此时Redis会怎么处理?来看一下:

      如上图,第一种情况是在事务执行前就发现了错误,事务块中第三条命令“GETT“是错误命令,可以看到Redis直接报错,之后即使使用EXEC命令提交,也不会执行事务块。第二种情况是事务块命令语法上没有错误,执行过程中会出现错误,因为我们对一个非Integer类型的数据进行减一操作,EXEC命令提交后,发现,虽然第二条命令执行失败,但是第一条和第三条却能顺利执行,第三条命令不会因为第二条命令执行失败而跟着停止,也就是说,Redis事务在某种情况下,即使命令执行错误,也不会回滚,错误命令下面的命令会接着执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值