【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
LPUSH
和RPUSH
LPUSH
命令的作用是将一个或多个元素从左侧(头插)插入到 list 中;而 RPUSH
命令的作用则是将一个或多个元素从右侧(尾插)插入到 list 中。
语法:
LPUSH key element [element ...]RPUSH key element [element ...]
LPUSHX
和RPUSHX
LPUSHX
命令的作用是当 key 存在时,将⼀个或者多个元素从左侧放⼊(头插)到 list 中,不存在则直接返回;而 RPUSHX
命令的作用是是当 key 存在时,将⼀个或者多个元素从右侧放⼊(头插)到 list 中,不存在则直接返回。
语法:
LPUSHX key element [element ...]RPUSHX key element [element ...]
2.2 LPOP 和 RPOP、BLPOP 和 BRPOP
LPOP
和RPOP
LPOP
命令的作用是从左侧删除一个元素(头删),并返回删除的值;而 RPOP
则是从右侧删除(尾删),然后返回删除的值。
语法:
LPOP keyRPOP key
BLPOP
和BRPOP
BLPOP
和 BRPOP
命令的作用和LPOP
、 RPOP
一样,只是需要指定一个超时时间,如果没有元素可以删除的时候,会进行阻塞,如果在设定的超时时间内向 Redis 中插入元素,则会立即执行;否则超时则之间退出。
语法:
BLPOP key [key ...] timeoutBRPOP key [key ...] timeout
另外,BLPOP
和 BRPOP
可以同时指定多个 key 进行删除。
2.3 LRANGE、LINDEX、LINSERT、LLEN
LRANGE
LRANGE
命令的作用是获取从 start 到 stop 区间的所有元素,区间左闭右闭,并且指定的位置可以是负数,表示倒数第几个。
语法:
LRANGE key start stop
LINDEX
LINDEX
命令的作用是获取从左边开始第 index 位置的元素。
语法:
LINDEX key index
LINSERT
LINSERT
命令的作用是在特定的位置插入元素。
语法:
LINSERT key BEFORE|AFTER pivot element
说明:
BEFORE
表示插入到 pivot 元素之前;AFTER
表示插入到 pivot 元素之后。
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 + n 问题。即如果每次分页获取的微博个数较多,需要执行多次
hgetall
操作,此时可以考虑使用pipeline
(流水线)模式批量提交命令,或者微博不采用哈希类型,而是使用序列化的字符串类型,使用 mget 获取。 - 分页获取文章时,
lrange
在列表两端表现较好,获取列表中间的元素表现较差,此时可以考虑将列表做拆分。
相关文章:
【Redis】深入探索 Redis 的数据类型 —— 列表 List
文章目录 一、List 类型介绍二、List 类型相关命令2.1 LPUSH 和 RPUSH、LPUSHX 和 RPUSHX2.2 LPOP 和 RPOP、BLPOP 和 BRPOP2.3 LRANGE、LINDEX、LINSERT、LLEN2.4 列表相关命令总结 三、List 类型内部编码3.1 压缩列表(ziplist)3.2 链表(lin…...
高精度乘除法(超详细)
高精度乘除法(超详细) 题目1-高精度乘法 给定两个非负整数(不含前导 0) A 和 B,请你计算 AB 的值。 输入格式 共两行,第一行包含整数 A,第二行包含整数 B。 输出格式 共一行,包含…...
List 获取前N条数据
1.使用for循环遍历 public static void main(String[] args) {int limit 5;List<Integer> oldList Lists.newArrayList(1, 2, 3, 4, 5, 6, 7);List<Integer> newList Lists.newArrayList();if (oldList.size() < limit) {newList.addAll(oldList);return;}fo…...
Spring入门控制反转(或依赖注入)AOP的关键概念 多配置文件与web集成
目录 1. 什么是spring,它能够做什么? 2. 什么是控制反转(或依赖注入) 3. AOP的关键概念 4. 示例 4.1 创建工程 4.2 pom文件 4.3 spring配置文件 4.4 示例代码 4.4.1 示例1 4.4.2 示例2 (abstract,parent示例) 4.4.3 使…...
排序算法-希尔排序
属性 1. 希尔排序是对直接插入排序的优化。 2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap 1时,数组已经接近有序的了,这样就会很 快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。 3.…...
ClientDataSet运行中出现“ClientDataSet:dataset not in edit or insert mode”(一)
在打开数据表文件,对ClientDataSet执行Append或Insert时,“ClientDataSet:dataset not in edit or insert mode”: 一、搜索问题 1、执行“显示数据后”,再执行Append,出错,说明ClientDataSet处…...
华为GaussDB数据库
Gauss数据库初识_高斯数据库_ygpGoogle的博客-CSDN博客 Redhat 7.6安装GaussDB_100_1.0.1详细攻略_gaussdb_100_1.0.1-database-redhat-64bit.tar.gz dow_博德1999的博客-CSDN博客 https://www.ngui.cc/el/3381579.html?actiononClick 初识GaussDB——GaussDB的发展历程、部…...
Flink、Spark、Hive集成Hudi
环境描述: hudi版本:0.13.1 flink版本:flink-1.15.2 spark版本:3.3.2 Hive版本:3.1.3 Hadoop版本:3.3.4 一.Flink集成Hive 1.拷贝hadoop包到Flink lib目录 hadoop-client-api-3.3.4.jar hadoop-client-runtime-3.3.4.jar 2.下载上传flink-hive的jar包 flink-co…...
百度编辑器 Ueditor 视频上传时 目录创建失败 解决办法
找到百度编辑器的上传类 Uploader.class.php文件.大约111左右 //$this->stateInfo $this->getStateInfo("ERROR_CREATE_DIR");//这句注释掉 $this->stateInfo $dirname;//换成这一句然后,进编辑器上传.会提示出一个错误的文件保存路径 双击复制下来这个路…...
Go 字符串处理
一、 字符串处理函数 我们从文件中将数据读取出来以后,很多情况下并不是直接将数据打印出来,而是要做相应的处理。例如:去掉空格等一些特殊的符号,对一些内容进行替换等。 这里就涉及到对一些字符串的处理。在对字符串进行处理时…...
家政服务接单小程序开发源码 家政保洁上门服务小程序源码 开源完整版
分享一个家政服务接单小程序开发源码,家政保洁上门服务小程序源码,一整套完整源码开源,可二开,含完整的前端后端和详细的安装部署教程,让你轻松搭建家政类的小程序。家政服务接单小程序开发源码为家政服务行业带来了诸…...
SuperMap iClient3D 11i (2023) SP1 for Cesium之移动实体对象
作者:nannan 目录 前言 一、代码思路 1.1 绘制面实体对象 1.2 鼠标左键按下事件 1.3 鼠标移动事件 1.4 鼠标左键抬起事件 二、运行效果 三、注意事项 前言 SuperMap 官网三维前端范例 编辑线面,可以对面实体对象的节点进行增加、删除以及修改位置…...
【深度学习 AIGC】stablediffusion-infinity 在无界限画布中输出绘画 Outpainting
代码:https://github.com/lkwq007/stablediffusion-infinity/tree/master 启动环境: git clone --recurse-submodules https://github.com/lkwq007/stablediffusion-infinity cd stablediffusion-infinity conda env create -f environment.yml conda …...
Flutter插件之阿里百川
上一篇:Flutter插件的制作和发布,我们已经了解了如何制作一个通用的双端插件,本篇就带领大家将阿里百川双端sdk制作成一个flutter插件供项目调用! 目录 登录并打开控制台,创建应用:填写应用相关信息开通百川…...
✔ ★ 算法基础笔记(Acwing)(三)—— 搜索与图论(17道题)【java版本】
搜索与图论 1. DFS1. 排列数字(3分钟)2. n-皇后问题 2. BFS(队列)1. 走迷宫二刷总结(队列存储一个节点pair<int,int>)三刷总结 走过的点标记上距离(既可以记录距离,也可以判断是否走过) ★ ★ 例题2. 八数码二刷…...
初试占比70%,计算机招生近200人,安徽理工大学考情分析
安徽理工大学 考研难度(☆) 内容:23考情概况(拟录取和复试分析)、院校概况、23专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文980字,预计阅读:3分钟 2023考情概况 安徽理工大…...
LeetCode题解:1720. 解码异或后的数组,异或,JavaScript,详细注释
原题链接: https://leetcode.cn/problems/decode-xored-array/ 解题思路: 异或有如下性质: a ^ a 0a ^ 0 aa ^ b b ^ a 根据题意,已知encoded[i - 1] arr[i - 1] ^ arr[i],可以做如下转换: encoded[i…...
【C刷题】day2
一、选择题 1、以下程序段的输出结果是( ) #include<stdio.h> int main() { char s[] "\\123456\123456\t"; printf("%d\n", strlen(s)); return 0; } A: 12 B: 13 C: 16 D: 以上都不对【答案】: A 【解析】…...
Apollo源码安装的问题及解决方法
问题一 在进行git clone时,会报错Failed to connect to github.com port 443: Timed out,经过实践后推荐以下两种方法。 方法一:在原地址前加https://ghproxy.com 原地址:git clone https://github.com/ApolloAuto/apollo.git …...
Flutter 挖孔屏的状态栏占用问题怎么解决,横屏后去掉了状态栏,还是会有一块黑色的竖条
使用下方代码后依旧有一条黑色的区域 overridevoid initState() {// TODO: implement initStatesuper.initState();///关闭状态栏,与底部虚拟操作按钮SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);//隐藏状态栏,底部按钮栏S…...
Layui快速入门之第九节 表格事件的使用
目录 一:事件 二:头部工具栏事件 三:排序切换事件 四:列拖拽宽度后的事件 五:列筛选(显示或隐藏)后的事件 六:行单击和双击事件 七:行右键菜单事件 八:…...
[2023.09.14]: Rust的条件编译
关于条件编译,我的记忆是10多年前,写C#的时代了,最近10年写Python和Javascript代码,虽然Javascript中也可以通过插件实现条件编译的效果,但是用起来太憋足了。当我在Yew的SSR开发模式中看到条件编译的配置时࿰…...
数据清洗:数据挖掘的前期准备工作
⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据…...
基于FPGA的图像sobel锐化实现,包括tb测试文件和MATLAB辅助验证
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 将FPGA的仿真结果导入到matlab显示图像效果 2.算法运行软件版本 MATLAB2022a,vivado2019.2 3.部分核心程序 .................................…...
HDMI 直通 ILA 调试实验
FPGA教程学习 第十四章 HDMI 直通 ILA 调试实验 文章目录 FPGA教程学习前言实验原理程序设计实验过程实验尝试总结TODO 前言 HDMI 输入直通到 HDMI 输出的显示,完成一个简单的 HDMI 输入输出检测。 实验原理 开发板 HDMI 输出接口芯片使用 ADV7511,HD…...
基于Qt4开发曲线绘制交互软件Plotter
目前市面上有很多曲线绘制软件,但其交互功能较差。比如,想要实现数据的交互,同步联动等,都需要大量繁琐的人工操作。所以讲想开发一款轻量级的曲线绘制交互软件。下面就以此为案例,记录一下基于Qt4的开发过程。 目录 1 需求 2 技术路线 3 开发流程 1 框架搭建 2 菜单…...
数据分享|R语言逻辑回归、Naive Bayes贝叶斯、决策树、随机森林算法预测心脏病...
全文链接:http://tecdat.cn/?p23061 这个数据集(查看文末了解数据免费获取方式)可以追溯到1988年,由四个数据库组成。克利夫兰、匈牙利、瑞士和长滩。"目标 "字段是指病人是否有心脏病。它的数值为整数,0无…...
【深度学习】 Python 和 NumPy 系列教程(十五):Matplotlib详解:2、3d绘图类型(1):线框图(Wireframe Plot)
目录 一、前言 二、实验环境 三、Matplotlib详解 1、2d绘图类型 2、3d绘图类型 0. 设置中文字体 1. 线框图(Wireframe Plot) 一、前言 Python是一种高级编程语言,由Guido van Rossum于1991年创建。它以简洁、易读的语法而闻名࿰…...
阿里云CDN缓存配置及优化-oss绑定CDN缓存自动刷新功能
参考阿里云官网文档:https://help.aliyun.com/practice_detail/603170 1.缓存时间配置 在缓存管理中,可以方便地指定目录和文件后缀名在CDN节点上的缓存时间,缓存时长配置的长短,取决于源站对该文件的变更频率。我们需要分析下业务…...
气象站有什么用?有哪些类型
气象站是一种用于收集、分析和处理气象数据的设备,能够为人们提供及时、准确的气象数据和决策支持。 一、气象站的作用 预测天气变化 气象站最重要的作用之一是进行预测天气变化。通过气象站的连续监测和数据分析,可以预测未来的天气情况,…...
flash网站制作实例/有什么公司要做推广的
什么是python的迭代如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。(在Python中,迭代是通过for ... in来完成的)Python的for循环抽象程度要高于C的for循环,因为Python的for…...
保定网站制作套餐/交换链接适合哪些网站
参考链接: Matplotlib官网 参考链接: Python数据分析与展示 参考链接: Matplotlib官网 API Overview 实验1:简单画图 # 实验1:简单画图 import matplotlib.pyplot as plt plt.plot([3,1,4,5,2]) # 只传入一个列表时,默认作为Y轴,x轴是列表索引 plt.ylabel("grade4cxq&q…...
自己在线制作图片免费下载/夫唯老师seo
作业需求: 用户入口:1.商品信息存在文件里 2.已购商品,余额记录。第一次启动程序时需要记录工资,第二次启动程序时谈出上次余额 3.允许用户根据商品编号购买商品 4.用户选择商品后,检测是否够,够就直接扣款…...
建网站和建网页的区别/成人短期技能培训
RabbitMQ集群概述通过 Erlang 的分布式特性(通过 magic cookie 认证节点)进行 RabbitMQ 集群,各 RabbitMQ 服务为对等节点,即每个节点都提供服务给客户端连接,进行消息发送与接收。这些节点通过 RabbitMQ HA 队列&…...
ftp制作网站/seo关键词排名优化制作
由于细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容(这里只展示2级目录)! 整理了一份Java核心知识点。覆盖了JVM,Java基础,并发编程,分布式…...
七牛云wordpress图床/湖南网站托管
Ping使用的是ICMP(Internet控制消息协议)协议。它不使用端口,因为它是一个网络层协议,而端口是传输层协议(如TCP或UDP)的概念。...