2023.12.27 关于 Redis 数据类型 List 常用命令

目录

List 类型基本概念

List 类型特点

List 操作命令

LPUSH

LPUSHX

RPUSH

RPUSHX

LRANGE

LPOP

RPOP

LINDEX

LINSERT

LREM

LTRIM

LSET

阻塞版本的命令

阻塞版本 和 非阻塞版本的区别

BLPOP & BRPOP


List 类型基本概念

  • Redis 中的列表(list)相当于 数组 或者 顺序表

  • 列表 (list)约定最左侧的元素下标为 0,且支持使用 负数下标

注意:

  • list 内部的编码方式,并非是一个简单的数组,而是类似于 "双端队列"(deque)
  • 这种设计使得 list 两侧均能进行高效的插入删除,且时间复杂度均为 O(1)

List 类型特点

1、列表中的元素都是有序的

  • 有序的含义 要根据上下文进行区分
  • 有的时候谈到有序指的是 升序 或 降序,有的时候谈到有序指的是 顺序很关键
  • 此处列表中的元素都是有序的,指的是 列表中的顺序很关键
  • 即把列表元素位置颠倒、顺序调换,此时得到的 新 list 和 旧 list 是不等价的

注意:

  • 同一个词该如何理解,需要结合上下文、结合具体场景

实例理解

  • 栈/堆(数据结构、操作系统、JVM)
  • 同步(同步和互斥 、 同步和异步)

2、列表中的元素允许重复

  • Redis 中 hash 类型,其 field 不能重复

小总结:

  • Redis 的典型应用场景就是作为消息队列,最早的时候就是通过 list 类型来实现的
  • 但后来 Redis 又提供了 stream 类型来专门针对消息队列

List 操作命令

LPUSH

  • 将 一个 或 多个 元素从左放入到 list 中,相当于头插
  • lpush ——> left push

语法:

lpush key element [element ...]

时间复杂度:

  • O(1)

返回值:

  • 插入后 list 的长度

实例理解

  • 该列表中 元素 4 在最前面,因为 lpush 相当于 头插

注意:

  • 如果当前 key 已存在,且 key 对应的 value 类型不为 list,则 lpush 命令将报错

LPUSHX

  • 当 key 存在时,将一个或多个元素从左侧放入 到 list 中,相当于头插
  • 当 key 不存在时,则直接返回 0 
  • lpushx ——> left push exists

语法:

lpushx key element [element ...]

时间复杂度:

  • O(1)

返回值:

  • 插入后 list 的长度

实例理解


RPUSH

  • 将 一个 或 多个 元素从右侧放入到 list 中,相当于尾插
  • rpush ——> right push

语法:

rpush key element [element ...]

时间复杂度:

  • O(1)

返回值:

  • 插入后 list 的长度

实例理解

  • 该列表中 元素 1 在最前面,因为 rpush 相当于 尾插

RPUSHX

  • 当 key 存在时,将一个或多个元素从右侧放入 到 list 中,相当于尾插
  • 当 key 不存在时,则直接返回 0
  • rpushx ——> right push exists

语法:

rpush key element [element ...]

实例理解


LRANGE

  • 用于查看 list 中指定范围的元素

 语法:

lrange key start stop
  • 此处描述的区间为 闭区间,且下标支持负数

时间复杂度:

  • O(N)

实例理解

注意点一:

  • 此处的序号是专门给结果集使用的序号 和 list 下标无关

  • 可以看到,当我们进行 hash 操作时,也会得到这种带有序号的结果集
  • 此处的序号仅仅是标识下标返回元素的顺序 和 下标无关
  • hash 类型就没有下标的概念

注意点二:

  • 当使用 lrange 命令返回指定范围的元素时
  • 如果提供的下标超出了列表下标范围,这时 lrange 命令会如何处理呢?

答案:

  • 如果给定区间非法,如超出下标
  • lrange 命令将尽可能的获取到给定区间的元素,不会报错!


LPOP

  •  从 list 左侧取出元素,相当于 头删

语法:

lpop key

时间复杂度:

  • O(1)

返回值:

  • 取出的元素或者 nil

实例理解


RPOP

  • 从 list 右侧取出元素,相当于 尾删

语法:

rpop key

时间复杂度:

  • O(1)

返回值:

  • 取出的元素或者 nil

实例理解

注意:

  • 在当前 redis 5 版本中,LPOP 和 RPOP 命令是没有 count 参数的
  • 但 redis 6.2 版本之后,新增了 count 参数,描述了一次要删 count 个元素

小总结:

  • list 是一个双端队列,即两头插入、删除元素均十分高效,时间复杂度为 O(1)
  • 搭配使用 rpush 和 lpop 就相当于 队列
  • 搭配使用 rpush 和 rpop 就相当于 栈

LINDEX

  • 用于获取从左数第 index 位置的元素

语法:

lindex key index

时间复杂度:

  • O(N)
  • 此处 N 指的是 list 中的元素个数

返回值:

  • 如果下标非法,返回 nil 

实例理解


LINSERT

  • 用于在特定位置插入元素

语法:

linsert key <before | after> pivot element

时间复杂度:

  • O(N)
  • 此处的N表示列表的长度

返回值:

  • 插入后 新 list 的长度

实例理解

注意:

  • 万一要插入的列表中 基准值存在多个怎么办?

回答:

  • linsert 在进行插入时,会根据基准值先找到其对应的位置
  • 寻找顺序为从左往右,找到第一个符合基准值的位置打止


LREM

  • 用来删除指定元素

语法:

lrem key count element
  • count 代表要删除的个数,element 代表要删除的值

时间复杂度:

  • O(N+M)
  • N 为列表的长度,M 为要删除元素的个数,此处 M 一般不会很大,可视为O(N)

返回值:

  • 被移除的元素数量

实例理解

  •  如果 count > 0 相当于在列表中从左往右找 删除 count 个 element

  • 如果 count < 0 相当于在列表中从右往左找 删除 count 个 element

  • 如果 count = 0 相当于 删除列表中 所有的 element


LTRIM

  • 用于保留列表中 指定范围的元素,移除范围外的元素

 语法:

ltrim key start stop
  • 保留 [start ,stop] 区间的元素,即区间外面两边的元素就直接被删除了

时间复杂度:

  • O(N)
  • N 为要删除元素的个数

返回值:

  • 命令执行成功则返回 OK

实例理解


LSET

  • 用于根据下标修改对应元素

语法:

lset key index element

时间复杂度:

  • O(N)

返回值:

  • 命令执行成功则返回 OK

实例理解

注意:

  • 相较于 lindex 命令,其能很好的处理下标越界问题,如果下标越界则直接返回 nil
  • 但 lset 命令对于下标越界,其会直接报错
  • 而不会像 JavaScript 语言,动态地扩展列表 并在给定下标位置插入元素

阻塞版本的命令

  • 阻塞:当前的线程 不走了,代码不继续执行了,会在满足一定的条件之后,被唤醒
  • blpop、brpop 这俩个命令是 lpop、rpop 俩个命令的阻塞版本


阻塞版本 和 非阻塞版本的区别

1、如果 list 中存在 元素,blpop、brpop 命令和 lpop、rpop 命令作用完全相同,但如果 list 中为空, blpop 和 brpop 便会产生阻塞,一直阻塞到队列不为空为止

  • brpop 和 blpop 会根据设置的超时时间 timeout 进行阻塞等待,即 执行该命令的 redis 客户端将会阻塞,但在这期间 redis 服务器可以执行其他redis 客户端发来的命令

注意:

  • 使用 brpop、blpop 命令时,需显式地设置阻塞时间
  • 虽然此处的 brpop 和 blpop 看起来好像耗时很久,但 redis 服务器不会产生因此而产生任何负面影响

2、blpop、brpop 命令可设置多个键,将根据设置的键从左向右进行遍历,一旦有一个键对应的列表中可以弹出元素,命令立即返回

3、如果多个客户端同时对一个键执行 pop 命令,则最先执行命令的客户端将得到弹出元素

注意:

  • 无论 pop 命令是否为阻塞命令,均满足第三条特性

实例理解

  • 此处理解 blpop、brpop 命令和 lpop、rpop 命令 的区别

a、当列表不为空时:

  • lpop user:1:messages 得到 x 元素
  • blpop user:1:messages 得到 x 元素
  • 二者行为一致

b、当列表不为空时,且五秒内无新元素加入

  • lpop user:1:messages 立即得到 nil
  • blpop user:1:messages 5 执行命令 5 秒后得到 nil
  • 二者行为不一致

c、当列表不为空时,且五秒内有新元素加入

  • lpop user:1:messages 立即得到 nil
  • blpop user:1:messages 5 执行命令,直到新元素加入,得到新元素
  • 二者行为不一致

BLPOP & BRPOP

  • LPOP & RPOP 的阻塞版本
  • 前缀 b ——> block (阻塞)

注意:

  • redis 中的 list 也相当于 阻塞队列一样
  • 线程安全是通过单线程模型支持的
  • 阻塞,则只支持 队列为空 的情况,不考虑 队列满

 语法:

blpop key [key ...] timeoutbrpop key [key ...] timeout

重点理解:

  • 此处我们可以指定 一个 key 或 多个 key每个 key 都需对应为 list 类型
  • 如果这些 key 对应的 list 有任何一个非空,blpop & rlpop 命令便会按照指定 key 的顺序进行遍历
  • 直到有一个 key 对应的 list 非空,就将该 list 头或尾 的元素给获取到,并立即返回该元素给客户端
  • 如果这些 key 对应的 list 均为空,此时就会根据设置的 timeout 超时时间,进行阻塞等待,等待其他客户端往这些 key 对应的 list 中插入元素
  • 进而获取到对应 key 的 list,返回该 list 的 头 或 尾 元素给客户端

注意:

  • 此处的 超时时间 timeout,单位为 秒
  • Redis 6 版本之后,允许超时时间设置成 小数,但 Redis 5 版本中超时时间,得为整数

时间复杂度:

  • O(1)

实例理解

1)针对一个 非空的列表进行操作

  • 返回的结果相当于一个 二元组
  • 该返回结果 告诉我们当前元素来自于哪个 key 的同时也告诉了我们弹出的元素值是什么

2)针对一个空的列表进行操作

3)针对多个 key 进行操作


小总结:

  • Redis 可使用 blpop & brpop 命令 作为消息队列
  • 虽然这俩命令可以在一定程度上满足 消息队列 的需求
  • 但整体来说,对于一些复杂的消息处理场景中,这俩命令还是有一定的局限性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2660728.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

第十一章 Stream消息驱动

Stream消息驱动 gitee:springcloud_study: springcloud&#xff1a;服务集群、注册中心、配置中心&#xff08;热更新&#xff09;、服务网关&#xff08;校验、路由、负载均衡&#xff09;、分布式缓存、分布式搜索、消息队列&#xff08;异步通信&#xff09;、数据库集群、…

Apache Commons JCS缓存解决方案

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff01;今天&#xff0c;咱们来聊聊Apache Commons JCS&#xff0c;一个Java界里的缓存大杀器。缓存技术&#xff0c;对于提高应用性能来说&#xff0c;就像是给它加了一剂兴奋剂&#xff0c;能让数据访问变得快如闪电。…

Qt(二):使用udp发送与接收图片

使用Qt来通过UDP协议发送和接收图片可以分为几个步骤。以下是一个基本的指南&#xff1a; 发送图片准备图片数据&#xff1a;首先&#xff0c;你需要将图片转换为可以在网络上传输的数据格式。通常&#xff0c;这涉及到将图片转换为字节数组。设置UDP套接字&#xff1a;在Qt中…

OpenCV-Python(21):OPenCV查找及绘制轮廓

1.认识轮廓 1.1 目标 理解什么是轮廓学习掌握找轮廓、绘制轮廓等学习使用cv2.findContours()、cv2.drawContours()函数的用法 1.2 什么是轮廓 在OpenCV中&#xff0c;轮廓是图像中连续的边界线的曲线&#xff0c;具有相同的颜色或者灰度&#xff0c;用于表示物体的形状。轮廓…

linux用户态与内核态通过字符设备交互

linux用户态与内核态通过字符设备交互 简述 Linux设备分为三类&#xff0c;字符设备、块设备、网络接口设备。字符设备只能一个字节一个字节读取&#xff0c;常见外设基本都是字符设备。块设备一般用于存储设备&#xff0c;一块一块的读取。网络设备&#xff0c;Linux将对网络…

web自动化(4)——POM设计重构

1. 什么是POM Page Object Model 是ui自动化测试中常见的封装方式。 原理&#xff1a;将页面封装为PO对象&#xff0c;然后通过面向对象的方式实现UI自动化 2. 封装原则 PO无需包含全部UI元素PO应当验证元素PO不应该包含断言PO不应该暴露元素 3. 怎么进行POM封装 面向对象…

Centos7:Jenkins+gitlab+node项目启动(2)

Centos7&#xff1a;Jenkinsgitlabnode项目启动(1) Centos7&#xff1a;Jenkinsgitlabnode项目启动(1)-CSDN博客 Centos7&#xff1a;Jenkinsgitlabnode项目启动(2) Centos7&#xff1a;Jenkinsgitlabnode项目启动(2)-CSDN博客 Centos7&#xff1a;Jenkinsgitlabnode项目启…

自动化网络故障修复管理

什么是故障管理 故障管理是网络管理的组成部分&#xff0c;涉及检测、隔离和解决问题。如果实施得当&#xff0c;网络故障管理可以使连接、应用程序和服务保持在最佳水平&#xff0c;提供容错能力并最大限度地减少停机时间。专门为此目的设计的平台或工具称为故障管理系统。 …

目标检测损失函数:IoU、GIoU、DIoU、CIoU、EIoU、alpha IoU、SIoU、WIoU原理及Pytorch实现

前言 损失函数是用来评价模型的预测值和真实值一致程度&#xff0c;损失函数越小&#xff0c;通常模型的性能越好。不同的模型用的损失函数一般也不一样。损失函数主要是用在模型的训练阶段&#xff0c;如果我们想让预测值无限接近于真实值&#xff0c;就需要将损失值降到最低…

vue3(十)-基础入门之Swiper轮播与自定义指令

一、Swiper html : 注意&#xff1a; class“swiper-wrapper”、class“swiper-slide” 等类名不能写错 <body><!-- 导入下载好的包或通过 CDN 导入vue、swiper.js、swiper.css --><!-- <script src"https://unpkg.com/vue3/dist/vue.global.js"&…

RK3568平台开发系列讲解(Linux系统篇)PWM系统编程

🚀返回专栏总目录 文章目录 一、什么是PWM二、PWM相关节点三、PWM应用编程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍 PWM 的系统编程。 一、什么是PWM PWM,即脉冲宽度调制(Pulse Width Modulation)

【PowerMockito:编写单元测试过程中采用when打桩失效的问题】

问题描述 正如上图所示&#xff0c;采用when打桩了&#xff0c;但是&#xff0c;实际执行的时候还是返回null。 解决方案 打桩时直接用any() 但是这样可能出现一个mybatisplus的异常&#xff0c;所以在测试类中需要加入以下代码片段&#xff1a; Beforepublic void setUp() …

Awesome Chrome Form UI - 框架设计与基础实现

Money is not evil by itself. Its just paper with perceived value to obtain other things we value in other ways. If not money what is evil you may ask? Evil is the unquenchable, obsessive and moral bending desire for more. Evil is the bottomless,soulless …

解决VSCode中C/C++ Project Generator插件创建的项目只能运行单个程序的问题

初六&#xff0c;履霜&#xff0c;坚冰至。 释意&#xff1a;初六&#xff0c;当你踩着微霜之时&#xff0c;严寒与坚冰也就即将到来。 目录 一、前言 二、问题描述 三、解决方案 1、思路总结 2、思考过程 3、解决方案&#xff08;直接用&#xff0c;报错找我(&#xff8…

超声功率放大器怎么用

超声功率放大器是一种用于放大超声信号的设备&#xff0c;广泛应用于医疗领域、工业领域和科学研究中。它能够将超声信号的能量增加到足够大的水平&#xff0c;以便进行高强度超声疗法、材料加工和实验研究等应用。下面将详细介绍超声功率放大器的使用方法和其工作原理。 首先&…

数据结构——红黑树 and B-树

红黑树 根据平衡条件第4、5两点 最短路径&#xff0c;都是黑色 最长路径&#xff0c;红黑相间 最长是最短的两倍 B-树

《深入理解Java虚拟机(第三版)》读书笔记:Java内存区域与内存溢出异常、垃圾收集器与内存分配策略

下文是阅读《深入理解Java虚拟机&#xff08;第3版&#xff09;》这本书的读书笔记&#xff0c;如有侵权&#xff0c;请联系删除。 文章目录 第2章 Java内存区域与内存溢出异常2.2 运行时数据区域2.3 HotSpot虚拟机对象探秘 第3章 垃圾收集器与内存分配策略3.2 对象已死&…

安装Node修改Node镜像地址搭建Vue脚手架创建Vue项目

1、安装VSCode和Node 下载VSCode Visual Studio Code - Code Editing. Redefined 下载Node Node.js (nodejs.org) 检验是否安装成功&#xff0c;WinR,输入cmd命令&#xff0c;使用node -v可以查看到其版本号 2、修改镜像地址 安装好node之后&#xff0c;开始修改镜像地址 …

【 YOLOv5】目标检测 YOLOv5 开源代码项目调试与讲解实战(4)-自制数据集及训练(使用makesense标注数据集)

如何制作和训练自己的数据集 看yolov5官网创建数据集1.搜索需要的图片2.创建标签标注数据集地址&#xff1a;放入图片后选择目标检测创建文档&#xff0c;每个标签写在单独的一行上传结果此处可以编辑类别把车框选选择类别即可导出数据 3.新建一个目录放数据写yaml文件 4. 测试…

重装系统以后无法git跟踪

总结&#xff1a;权限问题 故障定位 解决方案&#xff1a; 复制一份新的文件夹。&#xff08;新建的文件创建和写入权限都变了&#xff09; 修改文件为新的用户 执行提示的命令