【Redis】深入探索 Redis 的数据类型 —— 列表 List

文章目录

  • 一、List 类型介绍
  • 二、List 类型相关命令
    • 2.1 LPUSH 和 RPUSH、LPUSHX 和 RPUSHX
    • 2.2 LPOP 和 RPOP、BLPOP 和 BRPOP
    • 2.3 LRANGE、LINDEX、LINSERT、LLEN
    • 2.4 列表相关命令总结
  • 三、List 类型内部编码
    • 3.1 压缩列表(ziplist)
    • 3.2 链表(linkedlist)
  • 四、List 类型的应用场景
    • 4.1 消息队列
    • 4.2 微博列表


一、List 类型介绍

list 列表类型是用来存储多个有序的字符串,列表中的每个字符串称为元素(element),一个列表最多可以存储 2^32 - 1 个元素。在 Redis 中,可以对列表两端插人(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等。列表是⼀种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发上有很多应用场景。

列表两端插入和弹出操作:

列表的获取、删除等操作:

列表类型的特点:

  • 列表中的元素是有序的,这意味着可以通过索引下标获取某个元素或者某个范围的元素列表;
  • 区分获取和删除的区别,例上图 中的 lrem 1 b 是从列表中把从左数遇到的前 1 个 b 元素删除,这个操作会导致列表的长度从 5 变成 4;但是执行 lindex 4 只会获取元素,但列表长度不会变化。
  • 列表中的元素是允许重复的,例如下图中的列表中是包含了两个 a 元素的。

二、List 类型相关命令

2.1 LPUSH 和 RPUSH、LPUSHX 和 RPUSHX

  1. LPUSHRPUSH

LPUSH 命令的作用是将一个或多个元素从左侧(头插)插入到 list 中;而 RPUSH 命令的作用则是将一个或多个元素从右侧(尾插)插入到 list 中。

语法:

LPUSH key element [element ...]RPUSH key element [element ...]
  1. LPUSHXRPUSHX

LPUSHX 命令的作用是当 key 存在时,将⼀个或者多个元素从左侧放⼊(头插)到 list 中,不存在则直接返回;而 RPUSHX 命令的作用是是当 key 存在时,将⼀个或者多个元素从右侧放⼊(头插)到 list 中,不存在则直接返回。

语法:

LPUSHX key element [element ...]RPUSHX key element [element ...]

2.2 LPOP 和 RPOP、BLPOP 和 BRPOP

  1. LPOPRPOP

LPOP 命令的作用是从左侧删除一个元素(头删),并返回删除的值;而 RPOP 则是从右侧删除(尾删),然后返回删除的值。

语法:

LPOP keyRPOP key
  1. BLPOPBRPOP

BLPOPBRPOP 命令的作用和LPOPRPOP 一样,只是需要指定一个超时时间,如果没有元素可以删除的时候,会进行阻塞,如果在设定的超时时间内向 Redis 中插入元素,则会立即执行;否则超时则之间退出。

语法:

BLPOP key [key ...] timeoutBRPOP key [key ...] timeout

另外,BLPOPBRPOP 可以同时指定多个 key 进行删除。

2.3 LRANGE、LINDEX、LINSERT、LLEN

  1. LRANGE
    LRANGE命令的作用是获取从 start 到 stop 区间的所有元素,区间左闭右闭,并且指定的位置可以是负数,表示倒数第几个。

语法:

LRANGE key start stop
  1. LINDEX

LINDEX 命令的作用是获取从左边开始第 index 位置的元素。

语法:

LINDEX key index
  1. LINSERT

LINSERT 命令的作用是在特定的位置插入元素。

语法:

LINSERT key BEFORE|AFTER pivot element

说明:

  • BEFORE 表示插入到 pivot 元素之前;
  • AFTER 表示插入到 pivot 元素之后。
  1. LLEN

LLEN 命令的作用是 获取 list 长度。

语法:

LLEN key

2.4 列表相关命令总结

以下是关于 Redis List 相关命令的总结,包括命令、作用以及时间复杂度:

命令作用时间复杂度
LPUSH从列表左侧插入一个或多个元素O(N) (N 为插入元素数量)
RPUSH从列表右侧插入一个或多个元素O(N) (N 为插入元素数量)
LPUSHX如果列表存在,从左侧插入一个或多个元素,否则不执行操作O(1)
RPUSHX如果列表存在,从右侧插入一个或多个元素,否则不执行操作O(1)
LPOP从列表左侧删除并返回一个元素O(1)
RPOP从列表右侧删除并返回一个元素O(1)
BLPOP从左侧删除并返回元素,如果列表为空则阻塞,带有超时参数O(1) 或阻塞等待
BRPOP从右侧删除并返回元素,如果列表为空则阻塞,带有超时参数O(1) 或阻塞等待
LRANGE获取指定范围内的元素列表O(Slice Size)
LINDEX获取指定位置的元素O(N) (N 为索引位置)
LINSERT在指定元素前或后插入新元素O(N) (N 为列表长度)
LLEN获取列表的长度O(1)

注意:时间复杂度中的 “N” 表示操作的复杂度与列表的长度或插入元素的数量成线性关系,而不是固定的常数时间。在实际使用中,需要根据数据规模和性能要求选择适当的命令。

三、List 类型内部编码

Redis 中的 List 数据类型在内部可以使用不同的编码方式来存储数据,具体的编码方式取决于列表的大小和元素的大小。下面将介绍两种常见的 List 内部编码方式:

3.1 压缩列表(ziplist)

压缩列表(ziplist)是 Redis 中一种紧凑的、内存优化的列表编码方式,适用于存储较小的列表,或者列表中的元素都是较小的整数或字符串。压缩列表以连续的内存块的形式存储数据,每个节点可以包含一个或多个元素,这使得压缩列表在内存使用效率上有一定优势。

特点:

  • 压缩列表可以保存多个元素在一个节点中,因此在元素较小的情况下,它可以节省内存。
  • 压缩列表支持快速的元素访问,因为可以通过索引直接访问元素。
  • 压缩列表适用于列表较小且元素较小的情况。

3.2 链表(linkedlist)

链表(linkedlist)是 Redis 中另一种列表的内部编码方式,它更适合存储大型列表或者元素大小不一致的列表。链表中的每个节点包含一个元素以及指向前一个节点和后一个节点的指针,这种结构使得链表在插入和删除元素时具有较高的效率。

特点:

  • 链表适用于列表较大或元素较大的情况,因为它不需要连续的内存块,可以更好地处理大型数据。
  • 链表对于插入和删除元素的操作更加高效,因为只需要调整节点的指针而不需要移动大量数据。
  • 链表相对于压缩列表占用更多的内存,因为需要额外的指针来维护节点之间的链接。

总之,Redis 根据列表的大小和元素的大小自动选择使用压缩列表或链表来进行编码,以平衡内存使用和操作效率。在选择数据结构和命令时,需要考虑数据的规模和操作的性能需求。

示例:

1)当元素个数较少且没有大元素时,内部编码为 ziplist:

127.0.0.1:6379> rpush listkey e1 e2 e3
OK
127.0.0.1:6379> object encoding listkey
"ziplist"

2)当元素个数超过 512 时,内部编码为 linkedlist:

127.0.0.1:6379> rpush listkey e1 e2 e3 ... 省略 e512 e513
OK
127.0.0.1:6379> object encoding listkey
"linkedlist"

3)当某个元素的长度超过 64 字节时,内部编码为 linkedlist:

127.0.0.1:6379> rpush listkey "one string is bigger than 64 bytes ... 省略 ..."
OK
127.0.0.1:6379> object encoding listkey
"linkedlist"

四、List 类型的应用场景

4.1 消息队列

Redis 可以使用 lpush + brpop 命令组合实现经典的阻塞式生产者-消费者模型队列,生产者客户端使用 lpush 从列表左侧插入元素,多个消费者客户端使用 brpop命令阻塞式地从队列中 “争抢” 队首元素。通过多个客户端来保证消费的负载均衡和高可用性。

Redis 阻塞消息队列模型:


分频道的消息队列:

Redis 可以同样使用 lpush + brpop 命令,但通过不同的键模拟频道的概念,不同的消费者可以通过 brpop 不同的键值,实现订阅不同频道的理念。

4.2 微博列表

每个用户都有属于自己的微博列表 ,现需要分页展示文章列表。此时可以考虑使用列表类型,因为列表不但是有序的,同时支持按照索引范围获取元素。

1)每篇微博使用哈希结构存储,例如微博中 3 个属性:title、timestamp、content:

hmset mblog:1 title xx timestamp 1476536196 content xxxxx
...
hmset mblog:n title xx timestamp 1476536196 content xxxxx

2)向用户 的微博列表中添加微博,使用 user:<uid>:mblogs 作为微博的键:

lpush user:1:mblogs mblog:1 mblog:3
...
lpush user:k:mblogs mblog:9

3)分页获取用户的微博列表,例如获取用户1 的前 10 篇微博:

keylist = lrange user:1:mblogs 0 9
for key in keylist {hgetall key
}

此外,此方案在实际中可能存在两个问题:

  1. 1 + n 问题。即如果每次分页获取的微博个数较多,需要执行多次 hgetall 操作,此时可以考虑使用 pipeline(流水线)模式批量提交命令,或者微博不采用哈希类型,而是使用序列化的字符串类型,使用 mget 获取。
  2. 分页获取文章时,lrange 在列表两端表现较好,获取列表中间的元素表现较差,此时可以考虑将列表做拆分。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1-5 AUTOSAR数据交换文件ARXML

总目录——AUTOSAR入门详解AUTOSAR入门详解目录汇总&#xff1a;待续中。。。https://xianfan.blog.csdn.net/article/details/132818463 目录 一、Arxml文件 二、各类ARXML文件 一、Arxml文件 arxml文件是AUTOSAR&#xff08;Automotive Open System Architecture&#xff0…

nbcio-boot移植到若依ruoyi-nbcio平台里一formdesigner部分(四)

到目前为止&#xff0c;虽然基础的formdesigner部分已经完成&#xff0c;但流程用formdesigner提交与审批过程中的显示还有问题。 1、后端部分 其中FormConf修改如下&#xff1a; package com.ruoyi.flowable.core;import lombok.Data;import java.util.List; import java.uti…

Python用若干列的数据多条件筛选、去除Excel数据并批量绘制直方图

本文介绍基于Python&#xff0c;读取Excel数据&#xff0c;以一列数据的值为标准&#xff0c;对这一列数据处于指定范围的所有行&#xff0c;再用其他几列数据数值&#xff0c;加以筛选与剔除&#xff1b;同时&#xff0c;对筛选与剔除前、后的数据分别绘制若干直方图&#xff…

微信小程序的疫苗接种预约设计与实现vue+uniapp

对于本小程序的疫苗预约的设计来说&#xff0c;系统开发主要是采用java语言&#xff0c;在整个系统的设计中应用MySql数据库来完成数据存储&#xff0c;具体根据疫苗预约信息的现状来进行开发的&#xff0c;具体根据现实的需求来实现疫苗预约网络化的管理&#xff0c;各类信息有…

一线大厂Redis高并发缓存架构实战与性能优化

多级缓存架构 缓存设计 缓存穿透 缓存穿透是指查询一个根本不存在的数据&#xff0c; 缓存层和存储层都不会命中&#xff0c; 通常出于容错的考虑&#xff0c; 如果从存储层查不到数据则不写入缓存层。 缓存穿透将导致不存在的数据每次请求都要到存储层去查询&#xff0c; 失…

图像处理的创意之旅:逐步攀登Python OpenCV的高峰

目录 介绍OpenCV简介安装OpenCV加载和显示图像图像处理目标检测图像处理的高级应用视频处理综合案例&#xff1a;人脸识别应用总结 介绍 欢迎来到本篇文章&#xff0c;我们将一起探索如何使用Python中的OpenCV库进行图像处理和计算机视觉任务。无论您是初学者还是有一定编程…

系统架构设计师-数据库系统(1)

目录 一、数据库模式 1、集中式数据库 2、分布式数据库 二、数据库设计过程 1、E-R模型 2、概念结构设计 3、逻辑结构设计 三、关系代数 1、并交差 2、投影和选择 3、笛卡尔积 4、自然连接 一、数据库模式 1、集中式数据库 三级模式&#xff1a; &#xff08;1&#xff09;外…

爬虫逆向实战(33)-某联社数据(webpack)

一、数据接口分析 主页地址&#xff1a;某联社 1、抓包 通过抓包可以发现数据接口是/nodeapi/telegraphList 2、判断是否有加密参数 请求参数是否加密&#xff1f; 通过查看“载荷”模块可以发现有一个sign加密参数 请求头是否加密&#xff1f; 无 响应是否加密&#x…

嵌入式学习笔记(31)异常向量表的编程处理

6.5.1像内存一样去访问异常向量表 &#xff08;1&#xff09;S5PV210的异常向量表可以改变&#xff08;在CP15协处理器中&#xff09;&#xff0c;以适应操作系统的需求。但是目前系统刚启动&#xff0c;此时DRAM尚未初始化&#xff0c;程序哦都市在iSRAM中运行。210在iSRAM中…

K8S集群中部署服务之应用环境配置

微服务项目sangomall应用环境配置说明 一、应用环境配置文件创建 可以创建多个application.properties或application.yml文件,通过关键配置进行激活使用&#xff0c;例如测试环境和生产环境等。 1.1 创建开发环境&#xff08;dev&#xff09; 名称&#xff1a;application-…

炒期权的资金门槛是多少 ?

期权是一种合约&#xff0c;买方向卖方支付一定费用后有权利在特定的时间&#xff0c;以特定的价格买入或卖出一定数量的特定资产&#xff0c;卖方需履行相应义务&#xff0c;期权开户支持线上和零门槛开头&#xff0c;下文介绍炒期权的资金门槛是多少 ?本文来自&#xff1a;期…

C++面试记录之中望软件

上次面试体验不好&#xff0c;记录了&#xff0c;这次同样记录一次体验不好的面试&#xff0c;中望软件…直接写了名字&#xff0c;因为真的很无语&#x1f613; 记录一下我不知道的问题 忘记录音了&#x1f622; 1. main函数之前做了什么&#xff1f; 我&#xff1a;实话我…

【SpringMVC】自定义注解

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Spring MVC》。&#x1f3…

Oracle数据如何迁移导入到MySQL

使用Navicat工具建立数据连接&#xff0c;进行数据传输 1、打开Navicat工具&#xff0c;分别连接Oracle数据库和MySQL数据库。 2、连接源选择你的oracle数据&#xff0c;目标选mysql 即可成功导入

Scholarcy:AI在线论文摘要总结工具

【产品介绍】 名称 scholarcy 成立/上线时间 2018年 具体描述 scholarcy是一个基于AI的在线论文文献摘要总结工具&#xff0c;可以帮助研究人员和学生快速阅读和理解各种类型的文献&#xff0c;如研究论文、报告和书籍章节。 scholarcy可以在几秒钟…

CSS 修改el-calendar的样式,自定义样式

需求&#xff1a;自定义elementui的日历的样式&#xff1b;给符合条件的时间展示红点。 elementui的原始样式&#xff1a; 目标样式&#xff1a; 代码实现&#xff1a; html: <el-calendar v-model"calendarValue"><template slot"dateCell" …

pycharm安装jupyter,用德古拉主题,但是输入行全白了,看不清,怎么办?

问题描述 今天换了以下pycharm主题&#xff0c;但是jupyter界面输入代码行太白了&#xff0c;白到看不清楚这行的字&#xff0c;更不知道写的是什么&#xff0c;写到哪了&#xff0c;这还是挺烦人的&#xff0c;其他都挺正常的。 问题分析 目前来看有两个原因&#xff1a; 1、…

浅谈C++|STL之list+forward_list篇

一.list基本概念 功能:将数据进行链式存储 链表&#xff08;list)是一种物理存储单元上非连续的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接实现的 链表的组成:链表由—系列结点组成 结点的组成:一个是存储数据元素的数据域&#xff0c;另一个是存储下一个结…

腾讯云4核8G云服务器租用价格选轻量还是CVM?性能如何?

腾讯云4核8G云服务器可以选择轻量应用服务器或CVM云服务器标准型S5实例&#xff0c;轻量4核8G12M服务器446元一年&#xff0c;CVM S5云服务器935元一年&#xff0c;相对于云服务器CVM&#xff0c;轻量应用服务器性价比更高&#xff0c;轻量服务器CPU和CVM有区别吗&#xff1f;性…

基于YOLOv8模型的海洋生物目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要&#xff1a;基于YOLOv8模型的海洋生物目标检测系统可用于日常生活中检测与定位海洋生物目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的目标检测&#xff0c;另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算法训…