redis数据结构list的基本指令

基本介绍

list相当于列表或者一个顺序表,约定最左侧的下标为0,也就是说下图的abcde的下标依次为01234,也支持负数下标,也就是-5,-4,-3,-2,-1,支持头插头删,尾插尾删,内部的结构并不是一个简单的数组,而是一个双端队列,就可以去高效的对两侧插入删除,所以在开发场景中,可以作为一个栈/队列来使用。

特点

  • list数组的元素是有序的,有序有两个含义,一个是简单的'升序'/'降序',另外一个是指'顺序很关键',也就是说把元素位置颠倒,位置调换,此时得到的新list和之前的list是不一样的。
  • 列表中的元素是有序的,意味着可以通过索引获取某个元素或者某个范围的元素,可以使用lindex和lrange指令。
  • 区分删除和获取的区别:lrem b表示把列表从左开始数的第一个b元素删除掉,lrem和lindex都可以获取到值,但经过lrem后,列表长度变为4,而lindex获取操作并不会导致列表的长度发生变化。
  • 列表的元素是允许重复的。

相关命令

lpush和lrange

lpush :用于在列表中插入元素,一次可以只插入一个元素,也可以插入多个元素,这个插入是依次头插,比如说我们新创建了一个list,往里面插入1234四个数字,那么4是在头部。

如果key已经存在,并且此key对应的value不是list类型,那么lpush命令就会报错。

bash 复制代码
lpush key element1 [element2 ....]

lrange :获取一定范围的元素,此start和end是闭区间,且下标支持负数,如果我们输入的下标超出有效范围了,那么不会报错,而是尽可能获取到可以获取的元素,比如说key1的下标有效范围是0-3,如果我们选择0-100的范围,最后也只会出现0-3下标的值。

上述场景指的是只有一个下标越界的情况,如果两个下标都越界了,那么就会出现报错。

bash 复制代码
lrange key start end

lpushx,rpush和rpushx

lpushx :当key存在的时候,将一个或者多个元素头插到list中,如果不存在直接返回,返回值是插入后的list长度。

bash 复制代码
lpushx key element1[element2...]

rpush和rpushx:之前的lpush和lpushx是头插,而rpush和rpushx是尾插,用法和lpush和lpushx是一样的。

lpop和rpop

lpop和rpop的用法是一样的,时间复杂度为O(1),如果list里面还有元素的话,那么返回值就是取出来的元素,如果list里面没有元素的话,那么返回值就是nil。

bash 复制代码
lpop key
rpop key

lindex,linsert和llen

lindex :这个指令用于获取从左开始,值为pivot位置的元素,这里的index可以为负数,时间复杂度为O(N),返回值为取出的元素或者nil。

如果这个list列表里的基准值有多个,那么只在从左数的第一个元素的前面或者后面插入对应的值,后续的多个值不会发生插入。

如果这个list列表里不存在pivot元素,那么就不会插入,返回值为-1。

bash 复制代码
lindex key index

linsert:这个指令可以在指定的位置插入元素,可以通过before和after指定元素要插入在指定元素之前还是指定元素之后,返回值是得到的新的list的长度。

bash 复制代码
linsert key [before|after] pivot element


llen:获取此列表的长度,如果此列表对应的key存在,就返回列表的长度,如果key不存在则返回0。

bash 复制代码
llen key

lrem

此命令表示在列表中删除元素,count表示要删除的个数,如果count大于0,就是从左往右去找,如果count小于0,就从右往左找,如果count等于0,表示删除所有的element元素。

element表示要删除的值。

bash 复制代码
lrem key count element

ltrim和lset

ltrim:用于删除,把指定范围内的元素保留,把其他的元素全部删除,此区间是一个闭区间。

bash 复制代码
ltrim key start end


lset:用于根据下标修改元素,如果选择的下标超过范围,会提示下标越界。

bash 复制代码
lset key index element

blpop和brpop

在生产者消费者模型里,有两种情况会产生阻塞,一种是队列为空,出队列的操作会产生阻塞,另外一种是队列为满,入队列的操作会产生阻塞,,redis中的list相当于阻塞队列几乎一样,不一样的是,redis中的list只考虑队列为空的情况,不考虑队列为满的情况,这个线程安全是通过单线程实现的,而不是多线程。

如果list中存在元素,那么blpop,brpop的作用和lpop,rpop是一样的,如果list为空,那么blpop和brpop会阻塞到list不为空为止,但我们不能无休止的等,所以这两个命令是可以设置阻塞时间的。

在阻塞期间redis可以执行其他命令,但要求执行该命令的客户端表现为阻塞状态。

如果命令中设置了多个键,就会从左往右依次遍历键,一旦有一个键的列表中可以弹出元素,命令就会立即返回。

如果多个客户端同时多一个键执行pop,最先执行命令的客户端会得到弹出的元素。

bash 复制代码
blpop/brpop key1 [key2...] timeout #timeout单位是秒

内部编码

以前的list类型内部编码方式主要有两种,一种是ziplist(把数据按照更紧凑的压缩形式存储),另外一种是linkedlist方式,这两种现在几乎都不使用了,现在的编码方式是quicklist,是前两者的结合,整体还是一个链表,但每一个链表节点都是一个压缩列表。

所以redis现在的配置项就改为list-max-ziplist-size了,如果没有修改过原先配置的话,就可以使用cd /etc/redis下的配置目录,查看这个配置项,这个配置项表示一个压缩列表的大小大于nkb的时候,就要分出另外一个节点进行保存。

应用场景

  • 作为一个对象的属性进行使用:在MySQL中一个表可能有多个属性,而在redis中,可以用一个list来存放一个对象的属性,多个对象的关联关系也可以存储,但查询关联关系的功能是没有MySQL强大的。
  • 作为消息队列:作为生产者消费者模型,可以通过redis列表来完成此过程。
  • 分页展示文章列表:每个用户都有属于自己的文章列表,列表里元素都是有序的,并且支持按照索引范围获取元素。
相关推荐
zephyr052 小时前
C++ STL unordered_set 与 unordered_map 完全指南
开发语言·数据结构·c++
難釋懷2 小时前
Redis桌面客户端
数据库·redis·缓存
填满你的记忆2 小时前
【从零开始——Redis 进化日志|Day5】分布式锁演进史:从 SETNX 到 Redisson 的完美蜕变
java·数据库·redis·分布式·缓存
hanqunfeng2 小时前
(四十)SpringBoot 集成 Redis
spring boot·redis·后端
難釋懷2 小时前
Jedis快速入门
redis·缓存
漫随流水2 小时前
leetcode算法(112.路径总和)
数据结构·算法·leetcode·二叉树
小北方城市网2 小时前
SpringBoot 集成 MinIO 实战(对象存储):实现高效文件管理
java·spring boot·redis·分布式·后端·python·缓存
企鹅侠客3 小时前
第24章—数据结构篇:skiplist原理与实现解析
数据结构·skiplist
Chan163 小时前
【 微服务SpringCloud | 模块拆分 】
java·数据结构·spring boot·微服务·云原生·架构·intellij-idea