redis数据类型:list

数据结构

  • 源码版本:7.2.2
  • 路径:src/adlist.h

关于list的 头文件中涉及到的这三个结构体如下

/* Node, List, and Iterator are the only data structures used currently. */
# 节点
typedef struct listNode {
    struct listNode *prev; # 前元素的指针
    struct listNode *next; # 后元素的指针
    void *value; # 节点的值
} listNode;
# 遍历
typedef struct listIter {
    listNode *next; 相邻节点的指针
    int direction; # 遍历方向
} listIter;
# list
typedef struct list {
    listNode *head; # 链表的头指针
    listNode *tail; # 链表的尾指针
    void *(*dup)(void *ptr); # Duplicate .
    void (*free)(void *ptr); # 释放资源
    int (*match)(void *ptr, void *key); # 匹配
    unsigned long len; # list 的长度
} list;
双向链表图示
next
next
next
prev
prev
prev
node
node
node
node

简介

Redis lists are linked lists of string values. Redis lists are frequently used to:

  • Implement stacks and queues.
  • Build queue management for background worker systems.

list 结构示意图,可参考 python 中的 list,特别是范围查找逻辑

在这里插入图片描述

list 类型支持双向查找:

  • 正序查找:如 0 到 5,从头开始算起,
  • 负序查找:如 0 到 -5,

通常用于实现栈和队列

  • 栈:先进后出,使用 list 的 lpush 可以实现栈的功能,依次向前插入数据,按正序索引取值的时候,可以实现栈的功能。
  • 队列:先进先出,使用 rpush可以实现队列的功能,依次向后插入数据,按正序索引取值的时候,可以实现队列的功能。

The max length of a Redis list is 2 32 − 1 2^{32} - 1 2321 (4,294,967,295) elements.

list 的相关命令配合使用的应用场景:

  • 栈和队列:插入和弹出命令的配合,亦可实现栈和队列的功能
    实现哪种数据结构,取决于插入和弹出命令的配合,如
  • 左插右出右插左出:这两种种方式实现先进先出的数据结构,即异侧配合可以实现队列结构。
  • 左插左出或者右插右出:这两种方式可以实现先进后出的数据结构,即同侧配合可以实现栈结构。
  • 消息队列:实现发布与订阅模型。
    • 生产者使用尾部插入命令RPUSH 将消息插入 list; 消费者使用LPOP 命令从 list 的左边消费消息
    • 生产者使用尾部插入命令LPUSH 将消息插入 list; 消费者使用RPOP 命令从 list 的左边消费消息
  • 限流:
    • 每次请求时向 List 添加时间戳,通过检查 List 长度来决定是否允许新的请求,实现 API 请求频率控制。
  • 缓存记录:聊天记录、文章推送,热点数据等。

命令

插入元素

  • 头部插入LPUSH adds a new element to the head of a list;
LPUSH key element [element ...]

该命令会向list 的头部依次插入给定的元素,在读取该命令插入数据的时候,就像在使用栈一样,元素先进后出。

  • 逐次插入元素示意图,这种方式可以将 list 当栈来使用
127.0.0.1:6379> lpush block jj1
(integer) 1
127.0.0.1:6379> lindex block 0
"jj1"
127.0.0.1:6379> lpush block jj2
(integer) 2
127.0.0.1:6379> lindex block 0
"jj2"
127.0.0.1:6379> 

在这里插入图片描述

  • 批量插入元示意图,取出元素的时候,可以发现符合栈的结构特点:先进后出。
127.0.0.1:6379> lpush block jj1 jj2 jj3 jj4 jj5
(integer) 5

上述命令执行逻辑是,元素依次入栈。jj1 将位于栈低,jj5将位于栈顶。

127.0.0.1:6379> lrange block 0 5
1) "jj5"
2) "jj4"
3) "jj3"
4) "jj2"
5) "jj1"

上述命令执行结果存储示意图

在这里插入图片描述

  • 尾部插入RPUSH adds to the tail.
RPUSH key element [element ...]

该命令会向list 的尾部依次插入给定的元素,在读取该命令插入数据的时候,就像在使用队列一样,元素先进先出。

127.0.0.1:6379> rpush block1 jj1 jj2 jj3 jj4 jj5
(integer) 5
127.0.0.1:6379> lindex block1 0
"jj1"
127.0.0.1:6379> 

查找元素的索引

LPOS key element [RANK rank] [COUNT num-matches] [MAXLEN len]
  • RANK rank : 排名,次序
    • 假设 list 中有多个 a,则 rank 2 表示查找 第二个 a 出现的位置,可参考案例
    • rank :可以是赋值,表示倒数第一个, rank -1 表示倒数第一个

The command returns the index of matching elements inside a Redis list. By default, when no options are given, it will scan the list from head to tail, looking for the first match of “element”. If the element is found, its index (the zero-based position in the list) is returned. Otherwise, if no match is found, nil is returned.

  1. 该命令返回 Redis 列表中匹配元素的索引。
  2. 默认情况下,如果没有给出任何选项,它将从头到尾扫描列表,寻找第一个匹配的“元素”。
  3. 如果找到元素,则返回其索引(列表中从零开始的位置)。否则,如果未找到匹配项,则返回 nil。
  • 查看现有数据
127.0.0.1:6379> lrange block 0 8
1) "jj5"
2) "a"
3) "jj4"
4) "a"
5) "a"
6) "jj3"
7) "jj2"
8) "jj1"
127.0.0.1:6379>
  • 查找第一个 a 所在的索引(位置): rank n 表示第一个,
    • n为正序:表示正数第几个
    • n为负数:表示倒数第几个:
127.0.0.1:6379> lpos block a
(integer) 1
127.0.0.1:6379> lpos block a rank 1
(integer) 1
127.0.0.1:6379> lpos block a rank -1  # 倒数第1个 a的位置
(integer) 4
127.0.0.1:6379> lpos block a rank -2  # 倒数第2个 a的位置
(integer) 3
127.0.0.1:6379>
  • 返回前n 个 指定元素所在的位置,如返回 list 中前两个 a 的位置:
127.0.0.1:6379> lpos block a count 2 # 前2 个所在的位置
1) (integer) 1
2) (integer) 3
127.0.0.1:6379>

元素的个数

  • LLEN returns the length of a list.

Returns the length of the list stored at key. If key does not exist, it is interpreted as an empty list and 0 is returned. An error is returned when the value stored at key is not a list.

返回按键存储的列表的长度。

  1. 如果键不存在,则将其解释为空列表并返回0。
  2. 如果键上存储的值不是列表,则返回错误。
  • 查看 block元素的个数
127.0.0.1:6379> llen block
(integer) 5
127.0.0.1:6379>
  • 查看所有的键
127.0.0.1:6379> keys *
1) "coinmarketapikey"
2) "block"
3) "exchangerate"
4) "apikeyexceeded"
5) "mysite"
127.0.0.1:6379>
  • 查看不存在的键的元素个数,返回 0
127.0.0.1:6379> llen block1
(integer) 0
127.0.0.1:6379>
  • 使用此命令查看 hash 类型:命令错误的使用方式
127.0.0.1:6379> llen mysite
(error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379>

删除元素

  • 头部移除LPOP removes and returns an element from the head of a list;

Removes and returns the first elements of the list stored at key.

By default, the command pops a single element from the beginning of the list. When provided with the optional count argument, the reply will consist of up to count elements, depending on the list’s length.

  1. 移除并返回 list 的第一个元素。
  2. 如果给定了个数 count,则会从 list前面移除指定个数的元素。
LPOP key [count]
  • 尾部移除RPOP does the same but from the tails of a list.
LPOP key [count]

Removes and returns the last elements of the list stored at key.

By default, the command pops a single element from the end of the list. When provided with the optional count argument, the reply will consist of up to count elements, depending on the list’s length.

  1. 移除并返回 list 的最后一个元素。
  2. 如果给定了个数 count,则会从 list后面移除指定个数的元素。

移走元素

LMOVE atomically moves elements from one list to another.

LMOVE source destination <LEFT | RIGHT> <LEFT | RIGHT>
  • <LEFT | RIGHT>
    • 第一个选项,指要移出位于source 的头部|尾部的元素
    • 第二个选项,从source 移除的元素要插入 destination 的位置头部|尾部

Atomically returns and removes the first/last element (head/tail depending on the wherefrom argument) of the list stored at source, and pushes the element at the first/last element (head/tail depending on the whereto argument) of the list stored at destination.

原子地返回并删除存储在源中的列表的第一个/最后一个元素(head/tail 取决于 where 参数) ,并将元素推送到存储在目的地的列表的第一个/最后一个元素(head/tail 取决于 where 参数)。

For example: consider source holding the list a,b,c, and destination holding the list x,y,z. Executing LMOVE source destination RIGHT LEFT results in source holding a,b and destination holding c,x,y,z.

举例说明:假设现有两个 list:

  • key 为 source 值为 a,b,c,
  • key 为 destination 值为 x,y,z

执行移走命令:

LMOVE source destination RIGHT LEFT 

结果为:

  • source 值为 a,b,
  • destination 值为 c,x,y,z

获取元素

按下表(索引)检索
LINDEX key index

Returns the element at index index in the list stored at key. The index is zero-based, so 0 means the first element, 1 the second element and so on. Negative indices can be used to designate elements starting at the tail of the list. Here, -1 means the last element, -2 means the penultimate and so forth.

When the value at key is not a list, an error is returned.

  1. 返回键存储的列表中索引位置的元素。
    1. 索引是从零开始的,所以0表示第一个元素,1表示第二个元素,依此类推。
    2. 负索引可用于指定从列表尾部开始的元素。在这里,-1表示最后一个元素,-2表示倒数第二个元素,依此类推。
  2. 当 key 值不是列表时,将返回错误。
按范围检索

可参考 python 中的 list

if __name__ == '__main__':
    list_ = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    print(list_[0:-1])
    print(list_[-5:-3])

LRANGE extracts a range of elements from a list,与 python 中的 list 有着同样的结构。

LRANGE key start stop
  • start:包含此位置的元素
  • stop:包含此位置的元素

Returns the specified elements of the list stored at key. The offsets start and stop are zero-based indexes, with 0 being the first element of the list (the head of the list), 1 being the next element and so on.

These offsets can also be negative numbers indicating offsets starting at the end of the list. For example, -1 is the last element of the list, -2 the penultimate, and so on.

Out of range indexes will not produce an error. If start is larger than the end of the list, an empty list is returned. If stop is larger than the actual end of the list, Redis will treat it like the last element of the list.

  1. 返回按键存储的列表的指定元素。
    1. 偏移量 start 和 stop 是从零开始的索引,0是列表的第一个元素(列表的头) ,1是下一个元素,依此类推。
    2. 这些偏移量也可以是负数,表示从列表末尾开始的偏移量。例如,-1是列表的最后一个元素,-2是倒数第二个元素,依此类推。
  2. 索引越界:不存在这种异常,redis 会自动处理
127.0.0.1:6379> lrange block -8 -3
1) "jj5"
2) "a"
3) "jj4"
4) "a"
5) "a"
6) "jj3"
127.0.0.1:6379>

插入元素

LINSERT key <BEFORE | AFTER> pivot element
  • <BEFORE | AFTER> :要在指定值 pivot 前|后 插入 element
  • element :要插入的元素
  • pivot:list 中已存在的数据

Inserts element in the list stored at key either before or after the reference value pivot.

When key does not exist, it is considered an empty list and no operation is performed.

An error is returned when key exists but does not hold a list value.

  1. 在引用值 pivot 之前或之后按键存储的列表中插入元素。
  2. 如果键不存在,则将其视为空列表,不执行任何操作。
  3. 如果键存在但不包含列表值,则返回错误。
  • 插入一个元素
127.0.0.1:6379>  linsert block before  jj3 a
(integer) 6
127.0.0.1:6379> lrange block 0 8
1) "jj5"
2) "jj4"
3) "a"
4) "jj3"
5) "jj2"
6) "jj1"
127.0.0.1:6379>
  • 在不存在的值前后插入元素
127.0.0.1:6379> linsert block before  love me
(integer) -1
127.0.0.1:6379>

减少元素

LTRIM reduces a list to the specified range of elements.

Trim an existing list so that it will contain only the specified range of elements specified. Both start and stop are zero-based indexes, where 0 is the first element of the list (the head), 1 the next element and so on.

For example: LTRIM foobar 0 2 will modify the list stored at foobar so that only the first three elements of the list will remain.

start and end can also be negative numbers indicating offsets from the end of the list, where -1 is the last element of the list, -2 the penultimate element and so on.

Out of range indexes will not produce an error: if start is larger than the end of the list, or start > end, the result will be an empty list (which causes key to be removed). If end is larger than the end of the list, Redis will treat it like the last element of the list.

  1. 修剪现有列表,使其仅包含指定的元素范围。
  2. Start 和 stop 都是从零开始的索引,其中0是列表的第一个元素(head) ,1是下一个元素,依此类推。
    1. 例如: LTRIM foobar 02将修改存储在 foobar 中的列表,以便只保留列表的前三个元素。
    2. Start 和 end 也可以是负数,表示从列表末尾开始的偏移量,其中 -1是列表的最后一个元素,-2是倒数第二个元素,依此类推。
  3. 超出范围的索引不会产生错误:
    1. 如果 start 大于列表的末尾,或 start > end,结果将是一个空列表(这将导致删除键)。
    2. 如果 end 大于列表的末尾,Redis 会将其视为列表的最后一个元素。
127.0.0.1:6379> lrange block 0 100
1) "jj5" # 0
2) "a" # 1
3) "jj4" # 2
4) "a"
5) "a"
6) "jj3" # -3
7) "jj2" #-2
8) "jj1"  #-1
127.0.0.1:6379> ltrim block 2 -3
OK
127.0.0.1:6379> lrange block 0 100
1) "jj4"
2) "a"
3) "a"
4) "jj3"
127.0.0.1:6379>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

达梦8数据库备份与还原

通过命令找到达梦数据库进程所在位置 ps -ef | grep dm 得到达梦相关进程 pwd 进程ID得到进程目录 [rootdmdb01 bin]# pwd /data/dmdbms/bin [rootdmdb01 bin]# ps -ef | grep dm root 1183 2 0 Nov04 ? 00:00:33 [kworker/8:1H-xfs-log/dm-0] root …

电气设计 | 低压接地系统:TN-C 、TN-S、TN-C-S、TT适用哪些场所?

电气设计 | 低压接地系统&#xff1a;TN-C 、TN-S、TN-C-S、TT适用哪些场所&#xff1f; 1、低压配电系统简介2、各种低压配电系统介绍2.1、TN-C系统2.2、TN-S系统2.3、TN-C-S 系统2.4、TT 系统2.5、IT 系统 1、低压配电系统简介 低压配电系统有TN-C、TN-S、TN-C-S、TT和IT五种…

重温设计模式--组合模式

文章目录 1 、组合模式&#xff08;Composite Pattern&#xff09;概述2. 组合模式的结构3. C 代码示例4. C示例代码25 .应用场景 1 、组合模式&#xff08;Composite Pattern&#xff09;概述 定义&#xff1a;组合模式是一种结构型设计模式&#xff0c;它允许你将对象组合成…

漏洞检测工具:Swagger UI敏感信息泄露

Swagger UI敏感信息泄露 漏洞定义 Swagger UI是一个交互式的、可视化的RESTful API文档工具&#xff0c;它允许开发人员快速浏览、测试API接口。Swagger UI通过读取由Swagger&#xff08;也称为OpenAPI&#xff09;规范定义的API描述文件&#xff08;如swagger.json或swagger…

Linux下学【MySQL】表中插入和查询的进阶操作(配实操图和SQL语句通俗易懂)

绪论​ 每日激励&#xff1a;挫折是会让我们变得越来越强大的重点是我们敢于积极的面对它。—Jack叔叔 绪论​&#xff1a; 本章是表操作的进阶篇章&#xff08;没看过入门的这里是传送门&#xff0c;本章将带你进阶的去学习表的插入insert和查找select&#xff0c;本质也就是…

JavaScript 标准内置对象——Object

1、构造函数 2、静态方法 // 将源对象中所有可枚举的自有属性复制到目标对象&#xff0c;&#xff0c;并返回修改后的目标对象 Object.assign(target, ...sources) Object.create(proto, propertiesObject) // 以一个现有对象作为原型&#xff0c;创建一个新对象Object.defineP…

Robot Framework搭建自动化测试框架

1.配置环境 需要安装jdk8&#xff0c;andrid sdk&#xff08;安装adb&#xff09;&#xff0c;pycharm编译环境以及软件 安装Robot Framework 首先&#xff0c;你需要安装Robot Framework&#xff0c;可以使用 pip 进行安装&#xff1a; pip install robotframework安装所需的…

fastjson诡异报错

1、环境以及报错描述 1.1 环境 操作系统为中标麒麟、cpu 为国产鲲鹏服务器。 jdk为openjdk version 1.8.0._242 1.2 错误 com.alibaba.fastjson2.JSONException: syntax error : f at com.alibaba.fastjson2.JSONReaderUTF16.readBoolValue(JSONReaderUTF16.java:6424) at c…

Unity3d 基于UGUI和VideoPlayer 实现一个多功能视频播放器功能(含源码)

前言 随着Unity3d引擎在数字沙盘、智慧工厂、数字孪生等场景的广泛应用&#xff0c;视频已成为系统程序中展示时&#xff0c;不可或缺的一部分。在 Unity3d 中&#xff0c;我们可以通过强大的 VideoPlayer 组件和灵活的 UGUI 系统&#xff0c;将视频播放功能无缝集成到用户界面…

蓝牙协议——音乐启停控制

手机播放音乐 手机暂停音乐 耳机播放音乐 耳机暂停音乐

【EthIf-13】EthIfGeneral容器配置-01

1.EthIfGeneral类图结构 下面是EthIfGeneral配置参数的类图&#xff0c;比较重要的参数就是配置&#xff1a; 接收中断是否打开发送确认中断是否打开EthIf轮询周期 1.EthIfGeneral参数的含义

如何看待2024年诺贝尔物理学奖颁给了机器学习与神经网络?

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于2024年诺贝尔物理学奖颁给了机器学习与神…

有没有检测吸烟的软件 ai视频检测分析厂区抽烟报警#Python

在现代厂区管理中&#xff0c;安全与规范是重中之重&#xff0c;而吸烟行为的管控则是其中关键一环。传统的禁烟管理方式往往依赖人工巡逻&#xff0c;效率低且存在监管死角&#xff0c;难以满足当下复杂多变的厂区环境需求。此时&#xff0c;AI视频检测技术应运而生&#xff0…

VSCode搭建Java开发环境 2024保姆级安装教程(Java环境搭建+VSCode安装+运行测试+背景图设置)

名人说&#xff1a;一点浩然气&#xff0c;千里快哉风。—— 苏轼《水调歌头》 创作者&#xff1a;Code_流苏(CSDN) 目录 一、Java开发环境搭建二、VScode下载及安装三、VSCode配置Java环境四、运行测试五、背景图设置 很高兴你打开了这篇博客&#xff0c;更多详细的安装教程&…

二手车交易平台开发:安全与效率的双重挑战

3.1系统体系结构 系统的体系结构非常重要&#xff0c;往往决定了系统的质量和生命周期。针对不同的系统可以采用不同的系统体系结构。本系统为二手车交易平台系统&#xff0c;属于开放式的平台&#xff0c;所以在体系结构中采用B/s。B/s结构抛弃了固定客户端要求&#xff0c;采…

共享无人系统,从出行到生活全面覆盖

共享无人系统已经覆盖到我们生活中的方方面面&#xff0c;出行上&#xff0c;比如共享自行车小程序、共享自行车&#xff1b;生活中&#xff0c;比如说棋牌室、茶室。我们以棋牌室举例。 通过开发使用共享无人系统&#xff0c;可以极大地降低人力成本&#xff0c;共享无人棋牌室…

FPGA学习(基于小梅哥Xilinx FPGA)学习笔记

文章目录 一、整个工程的流程二、基于Vivado的FPGA开发流程实践&#xff08;二选一多路器&#xff09;什么是二选一多路器用verilog语言&#xff0c;Vivado软件进行该电路实现1、设计输入&#xff1a;Design Sources中的代码2、分析和综合&#xff1a;分析设计输入中是否有错误…

四相机设计实现全向视觉感知的开源空中机器人无人机

开源空中机器人 基于深度学习的OmniNxt全向视觉算法OAK-4p-New 全景硬件同步相机 机器人的纯视觉避障定位建图一直是个难题&#xff1a; 系统实现复杂 纯视觉稳定性不高 很难选到实用的视觉传感器 为此多数厂家还是采用激光雷达的定位方案。 OAK-4p-New 为了弥合这一差距…

突破续航瓶颈:数字样机技术引领新能源汽车复合制动新方向

随着我国经济快速发展和人民生活水平不断提升&#xff0c;汽车保有量截至2023年9月底就已达到了3.3亿&#xff0c;同比增长6.32%。庞大的汽车保有量对我国的环境和能源都产生了巨大的压力&#xff0c;具备节能环保优势的新能源汽车对于有效解决环境恶化和能源危机问题具有重要意…

基于股票日频 K 线的自动因子挖掘实践

遗传算法最初由美国密歇根大学的 J.Holland 提出&#xff0c;是一种通过模拟自然界生物进化的过程来搜索最优解的算法&#xff0c;应用于量子计算、电子设计、游戏比赛等多种场景。 以大家熟知的 python gplearn 为例&#xff0c;它就是一款基于遗传算法开发的数据分析工具&am…