Redis list 类型

news2024/10/9 14:44:21

list类型

类型介绍

列表类型 list 相当于 数组或者顺序表

list内部的编码方式更接近于 双端队列 ,支持头插 头删 尾插 尾删。

需要注意的是,Redis的下标支持负数下标。 比如数组大小为5,那么要访问下标为 -2 的值可以理解为访问 5 - 2 = 3

Redis中的数据是有序的,但是注意这里的有序不是指排序数组中的升序或者降序,而是指数据的顺序很关键。比如把元素位置调换之后,得到的新的list与原来的list是不等价的。

同样的一个词在不同的上下文中,它的意义可能是不一样的。

比如同步这个词在 线程之间和IO之间的意义就不同。 

另外list还提供了其他的一些功能,如图:

关于lindex和lrem两个命令 

在hash类型中,是不允许有重复数据的,也就是不能有重复的field。但是list可以有重复的值。

 lpush / lrange

lpush 

将⼀个或者多个元素从左侧放⼊(头插)到 list 中。  

LPUSH key element [element ...]
时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.
返回值:插⼊后 list 的⻓度。
注意:这里的插入是头插的方式,如果有多个值,那么会依次将这些值头插到list中。
如果key不存在,那么会先创建key再加入,如果key存在,并且不是list类型,那么会报错。

lrange

获取从 start 到 end 区间的所有元素,左闭右闭。 

LRANGE key start stop
时间复杂度:O(N)
返回值:指定区间的元素。

 谈到下标,那么往往就会关注超出范围的问题。

 可以看到Redis的做法是尽可能的获取到指定区间的元素,如果给定区间不合法,比如超出下标,那么依然会尽可能的获取到对应的内容。

lrange这里的l不是指left 而是指 list。 

扩展:一些超出下标范围的情况 

对于C++ :会认为这是一个未定义的行为

对于Java:会抛异常

 对于Redis:尽可能的获取到对应的内容。

lpushx / rpush / rpushx

lpushx

在 key 存在时,将⼀个或者多个元素从左侧放⼊(头插)到 list 中。不存在,直接返回
LPUSHX key element [element ...]
时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.
返回值:插⼊后 list 的⻓度。

rpush

将⼀个或者多个元素从右侧放⼊(尾插)到 list 中。

这样依次插入的元素就是顺序的 ,lpush就是倒序的

RPUSH key element [element ...]
时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.
返回值:插⼊后 list 的⻓度。

rpushx

在 key 存在时,将⼀个或者多个元素从右侧放⼊(尾插)到 list 中。 

RPUSHX key element [element ...]
时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.
返回值:插⼊后 list 的⻓度。

 lpushx 和 rpushx 这里的x可以理解为exists。

lpop / rpop 

lpop

从 list 左侧取出元素(即头删)。 

 LPOP key
时间复杂度:O(1)
返回值:取出的元素或者 nil。

rpop

从 list 右侧取出元素(即尾删)。  

RPOP key
时间复杂度:O(1)
返回值:取出的元素或者 nil。

 

总结:

Redis的list其实就是一个双端队列,从两头插入/删除元素的效率都是 O(1):
搭配 lpush / lpop 可以当作一个队列使用

搭配 rpush/ rpop 可以当作一个栈使用

lindex / linsert / llen

lindex

获取从左数第 index 位置的元素。 

LINDEX key index
时间复杂度:O(N)
返回值:取出的元素或者 nil。

linsert

在特定位置插⼊元素。 

 LINSERT key <BEFORE | AFTER> pivot element
时间复杂度:O(N)
返回值:插⼊后的 list ⻓度。如果插入失败返回-1

因为list的结构不是数组,所以lindex和linsert都需要遍历找到位置,所以时间复杂度为O(N),这里的N指的就是list的长度,当list的长度不大时还好,如果list太长了,那么这两个命令的效率就低了。 

llen

获取 list ⻓度。 

LLEN key
时间复杂度:O(1)
返回值:list 的⻓度。

另外之前说过,list中是允许有重复值的,那么在insert的时候,如果选择的基准值有重复的,那么是如何插入的呢?

可以看见,当基准值有重复值时,Redis会从左向右遍历,找到以第一个符合基准值的位置为主。

lrem

批量删除等于 value的值。

当count > 0时:从左往右删除 count个元素。

当count < 0时:从右往左删除 count 个元素 。

当count = 0时:删除所有符合要求的元素。

rem 其实时 remove的缩写。

 

图中演示的就是从左往右删除 2 个 值 = 1的元素。 

ltrim / lset

ltrim

删除 除了 [left,right]区间之外的所有元素

ltrim key start stop

时间复杂度 O(N)

lset

根据下标来修改元素

lset key index element

时间复杂度O(N)

 另外这里如果下标越界了,是会直接报错的,跟lindex那里会返回一个nil是不同的。

blpop / brpop (阻塞版本命令)

 

blpop/brpop key timeout

 时间复杂度 O(1)
返回值:取出来的元素或者 nil(超时了)

blpop 和 brpop 是 lpop 和 rpop 的阻塞版本,和对应⾮阻塞版本的作⽤基本⼀致,除了:
在列表中有元素的情况下,阻塞和⾮阻塞表现是⼀致的。但如果列表中没有元素,⾮阻塞版本会理
解返回 nil,但阻塞版本会根据 timeout,阻塞⼀段时间,期间 Redis 可以执⾏其他命令,但要求执
⾏该命令的客⼾端会表现为阻塞状态(如图 2-22 所⽰)。
命令中如果设置了多个键,那么会从左向右进⾏遍历键,⼀旦有⼀个键对应的列表中可以弹出元
素,命令⽴即返回。
如果多个客⼾端同时多⼀个键执⾏ pop,则最先执⾏命令的客⼾端会得到弹出的元素。

还可以针对多个key进行操作的,返回最先取出来的二元组。 

 

命令总结:

 

 

list内部编码 

 Redis老版本的方式

现在的redis是用一个quicklist的结构。

 

 

在redis的配置文件种,这个就是配置list的ziplist的最大长度的,这里的-2表示的是等级。 

redis配置文件的默认路径

cd /etc/redis

 

 

list的应用场景 

作为数组 

list作为数组,可以储存多个元素。

 在mysql下存储表结构

在Redis下存储

查询起来还是mysql的功能要丰富一些。

作为消息队列 

 

分频道的消息队列 

 

比如我们刷抖音,一个抖音界面有很多元素组成,比如视频,弹幕,点赞和评论等等,那么这些数据没必要由一个通道来传输,可以将这些元素分为多个通道传输。这样的好处是可以解耦合。

 

微博timeline 

每个⽤⼾都有属于⾃⼰的 Timeline(微博列表),现需要分⻚展⽰⽂章列表。此时可以考虑使⽤
列表,因为列表不但是有序的,同时⽀持按照索引范围获取元素。

 

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

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

 2)向⽤⼾ Timeline 添加微博,user:<uid>:mblogs 作为微博的键:

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

这里插入list中的是哈希表的索引。 

 3)分⻚获取⽤⼾的 Timeline,例如获取⽤⼾ 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.coloradmin.cn/o/2195429.html

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

相关文章

Linux dlsym和直接调用函数地址解析分析

dlsym 函数是 Linux 下动态链接库&#xff08;shared library&#xff09;编程中的一个重要函数。它用于在运行时获取动态链接库中符号的地址&#xff0c;通常用于获取函数指针或变量的地址。 以下是 dlsym 函数的基本用法和示例。 1. 函数原型 void *dlsym(void *handle, c…

【超详细】基于YOLOv11的PCB缺陷检测

主要内容如下&#xff1a; 1、数据集介绍 2、下载PCB数据集 3、不同格式数据集预处理&#xff08;Json/xml&#xff09;&#xff0c;制作YOLO格式训练集 4、模型训练及可视化 5、Onnxruntime推理 运行环境&#xff1a;Python3.8&#xff08;要求>3.8&#xff09;&#xff…

ubuntu ssh远程执行k8s命令报错the connection to the server localhost:8080 was refused

修改前&#xff1a; ssh root192.168.31.167 kubectl apply -f /root/jenkinsexcute/saas.demo.api.k8s.yml --recordecho "export KUBECONFIG/etc/kubernetes/admin.conf" >> /root/.bashrc 修改后 添加一段&#xff1a;export KUBECONFIG/etc/kubernetes/a…

【专题】操作系统概述

1. 操作系统的目标和作用 操作系统的目标与应用环境有关。 在查询系统中所用的OS&#xff0c;希望能提供良好的人—机交互性&#xff1b; 对于应用于工 业控制、武器控制以及多媒体环境下的OS&#xff0c;要求其具有实时性&#xff1b; 对于微机上配置的OS&#xff0c;则更看…

什么是强基计划?

“强基计划”是中国教育部于2020年推出的一项全新的高等教育招生改革计划&#xff0c;旨在通过更加科学、公正的选拔机制&#xff0c;选拔出有志于基础学科并具备扎实学科功底、创新潜质的优秀学生&#xff0c;从而推动国家基础学科的发展&#xff0c;提升自主创新能力。与传统…

【自动驾驶】UniAD代码解析

1.参考 论文&#xff1a;https://arxiv.org/pdf/2212.10156 代码&#xff1a;https://github.com/OpenDriveLab/UniAD 2.环境配置 docs/INSTALL.md &#xff08;1&#xff09;虚拟conda环境 conda create -n uniad python3.8 -y conda activate uniad &#xff08;2&#…

微信小程序和抖音小程序的分享和广告接入代码

开发完成小程序或者小游戏之后&#xff0c;我们为什么要接入分享和广告视频功能&#xff0c;主要原因有以下几个方面。 微信小程序和抖音小程序接入分享和广告功能主要基于以下几个原因&#xff1a; 用户获取与增长&#xff1a;分享功能可以帮助用户将小程序内容传播给更多人&…

C语言刷题--有关闰年

满足以下一种即是闰年 能被4整除&#xff0c;但不能被100整除能被400整除 //输入年&#xff0c;月&#xff0c;输出该月的天数 //1月 31,28,31,30,31,30,31,31,30,31,30,31int is_leap_year(int y) {if (((y % 4 0) && (y % 100 ! 0)) || y % 400 0)return 1;return…

步进电机和步进电机驱动器详解

一、步进电机的概念 步进电机是通过步进电机配套的驱动器&#xff0c;将控制器传来的脉冲信号转换成角位移的开环电机&#xff08;没有反馈&#xff09;。 步进电机工作时的位置和速度信号不反馈给控制系统&#xff0c;如果电机工作时的位置和速度信号反馈给控制系统&#xff…

《从零开始大模型开发与微调》真的把大模型说透了!零基础入门一定要看!

2022年底&#xff0c;ChatGPT震撼上线&#xff0c;大语言模型技术迅速“席卷”了整个社会&#xff0c;人工智能技术因此迎来了一次重要进展。与大语言模型相关的研发岗薪资更是水涨船高&#xff0c;基本都是5w月薪起。很多程序员也想跟上ChatGPT脚步&#xff0c;今天给大家带来…

apache.poi读取.xls文件时The content of an excel record cannot exceed 8224 bytes

目录 问题描述版本定位&#xff1a;打印size最大的Record定位&#xff1a;RefSubRecord解决代码 问题描述 使用apache.poi读取.xls文件时有The content of an excel record cannot exceed 8224 bytes的报错。待读取的文件的内容也是通过apache.poi写入的&#xff0c;我的文件修…

【sqlmap】sqli-labs速通攻略

sqli-labs工具速通 Less-1 sqlmap -u http://127.0.0.1:8081/Less-1/?id1 --batch --dbs sqlmap -u http://127.0.0.1:8081/Less-1/?id1 --batch -D security --tables sqlmap -u http://127.0.0.1:8081/Less-1/?id1 --batch -D security -T users --columns sqlmap -u ht…

购物清单 | 双十一加购率最高好物合集,数码购物车必备!

​双十一来临&#xff0c;小伙伴们肯定已经被种草了很多很多清单&#xff0c;开始买买买了&#xff01;但是&#xff0c;作为一个数码博主&#xff0c;怎么能少了数码产品&#xff01;今天我给大家准备了一份数码人专属的购物清单&#xff0c;快来看看吧&#xff01; 运动耳机…

[水墨:创作周年纪念] 特别篇!

本篇是特别篇&#xff01;&#xff01; 个人主页水墨不写bug // _ooOoo_ // // o8888888o // // 88" . "88 …

如何方便地打出「」和『』

比起英文中的引号 ‘’和 “”&#xff0c;我更喜欢使用中文直角引号&#xff1a;「」和 『』。 此外&#xff0c;在港澳台、日本这几个地区中&#xff0c;就经常使用『』和「」&#xff1a; ​ ‍ 注意&#xff1a;不同地区的习惯可能有所不同。在汉语中『』、「」分别为双…

数学公式编辑器免费版下载,mathtype和latex哪个好用

选择适合自己的公式编辑器需要考虑多个因素。首先&#xff0c;您需要确定编辑器支持的功能和格式是否符合您的需求&#xff0c;例如是否可以插入图片、导出各种文件格式等。其次&#xff0c;您可以考虑编辑器的易用性和界面设计是否符合您的个人喜好。另外&#xff0c;您还可以…

面向对象特性中 继承详解

目录 概念&#xff1a; 定义&#xff1a; 定义格式 继承关系和访问限定符 基类和派生类对象赋值转换&#xff1a; 继承中的作用域&#xff1a; 派生类的默认成员函数 继承与友元&#xff1a; 继承与静态成员&#xff1a; 复杂的菱形继承及菱形虚拟继承&#xff1a; 虚…

手机号归属地查询-手机号归属地-手机号归属地-运营商归属地查询-手机号码归属地查询手机号归属地-运营商归属地

手机号归属地查询API接口是一种网络服务接口&#xff0c;允许开发者通过编程方式查询手机号码的注册地信息。关于快证签API接口提供的手机号归属地查询服务&#xff0c;以下是一些关键信息&#xff1a; 一、快证签API接口简介 快证签API接口可能是一个提供多种验证和查询服务…

「自动化测试」Selenium 的使用

使用 Selenium 需要先导入相关依赖 <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.0.0</version> </dependency><dependency><groupId>io.gith…

免费录屏神器!这四款软件让你快捷录屏~

随着技术的进步&#xff0c;免费的录屏软件如雨后春笋般涌现&#xff0c;为我们的工作、学习和娱乐提供了极大的便利。今天&#xff0c;就让我来为大家推荐几款备受好评的免费录屏软件&#xff0c;并分享一下使用感受吧&#xff01; 一、福昕录屏 直通车&#xff08;粘贴到浏览…