Redis列表 (List) 类型详解:从命令使用到实际应用

🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇

⭐ List 类型 ⭐

🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇


引言

继上篇文章的 hash 类型,这里介绍 Redis 中的列表的基本命令和使用以及实际应用。列表(List)是 Redis 提供的一种常用的数据结构,非常适合用来处理一系列有序的数据。


1. 什么是 Redis 列表?

Redis 列表是一种可以存储多个有序字符串的数据类型。你可以把它想象成一个简单的清单,比如购物清单或者待办事项列表。在这个列表里,每个条目都是一个字符串,并且它们按照添加的顺序排列。你可以在列表的两端进行插入或移除操作,也可以从列表中获取指定位置的数据。

特点:

  • 有序性:列表中的元素是按照添加顺序排列的。
  • 访问方式:可以通过数字索引来访问列表中的元素,索引可以从左到右(0, 1, 2...)或者从右到左(-1, -2, -3...)。
  • 允许重复:列表中的元素可以重复出现。

2. 如何操作 Redis 列表?

添加元素
  • LPUSH 命令:在列表的左侧(头部)添加一个或多个元素。例如:

    redis> LPUSH mylist "apple"
    (integer) 1
    redis> LPUSH mylist "banana" "cherry"
    (integer) 3
    

    这个命令将 "banana""cherry" 依次添加到 mylist 的最左边,结果是 ["cherry", "banana", "apple"]

  • RPUSH 命令:在列表的右侧(尾部)添加一个或多个元素。例如:

    redis> RPUSH mylist "date"
    (integer) 4
    redis> RPUSH mylist "elderberry" "fig"
    (integer) 6
    

    这个命令将 "date""elderberry""fig" 依次添加到 mylist 的最右边,结果是 ["cherry", "banana", "apple", "date", "elderberry", "fig"]

  • LPUSHXRPUSHX 命令 :这些命令类似于 LPUSHRPUSH,但只有当键已经存在时才会执行插入操作。例如:

    redis> LPUSHX myotherlist "grape"
    (integer) 0
    redis> RPUSHX mylist "grape"
    (integer) 7
    

    如果 myotherlist 不存在,则不会添加任何元素;而 mylist 已经存在,所以会在其左侧添加 "grape",结果是 ["grape", "cherry", "banana", "apple", "date", "elderberry", "fig"]

获取元素
  • LRANGE 命令:获取列表中特定范围内的所有元素。例如:

    redis> LRANGE mylist 0 2
    1) "grape"
    2) "cherry"
    3) "banana"
    redis> LRANGE mylist -3 -1
    1) "date"
    2) "elderberry"
    3) "fig"
    

    第一个命令返回了从第 1 个到第 3 个的所有元素,第二个命令返回了最后三个元素。

  • LINDEX 命令:获取列表中某个特定位置的元素。例如:

    redis> LINDEX mylist 2
    "banana"
    redis> LINDEX mylist -1
    "fig"
    

    第一个命令返回了位于第 3 位的元素 "banana",第二个命令返回了最后一个元素 "fig"

删除元素
  • LPOP 命令:从列表的左侧移除并返回第一个元素。例如:

    redis> LPOP mylist
    "grape"
    

    移除了 "grape",新的列表为 ["cherry", "banana", "apple", "date", "elderberry", "fig"]

  • RPOP 命令:从列表的右侧移除并返回最后一个元素。例如:

    redis> RPOP mylist
    "fig"
    

    移除了 "fig",新的列表为 ["cherry", "banana", "apple", "date", "elderberry"]

  • LREM 命令:删除列表中与给定值相匹配的元素。例如:

    redis> LREM mylist 1 "apple"
    (integer) 1
    redis> LREM mylist 0 "banana"
    (integer) 1
    

    第一个命令移除了第一个出现的 "apple",第二个命令移除了所有 "banana" 元素,新的列表为 ["cherry", "date", "elderberry"]

插入元素
  • LINSERT 命令 :在特定位置插入元素。例如:

    redis> LINSERT mylist BEFORE "date" "avocado"
    (integer) 4
    redis> LINSERT mylist AFTER "cherry" "blueberry"
    (integer) 5
    

    第一个命令在 "date" 之前插入了 "avocado",第二个命令在 "cherry" 之后插入了 "blueberry",新的列表为 ["cherry", "blueberry", "avocado", "date", "elderberry"]

查询长度
  • LLEN 命令 :获取列表的长度。例如:

    redis> LLEN mylist
    (integer) 5
    
阻塞式操作

BLPOPBRPOP 命令 :这些命令是 LPOPRPOP 的阻塞版本。当列表为空时,这些命令不会立即返回空结果,而是等待一段时间,直到有新的元素被添加到列表中。例如:

redis> BLPOP mylist 0
1) "cherry"
2) "blueberry"
redis> BRPOP mylist 0
1) "mylist"
2) "elderberry"

如果 mylist 为空,BLPOPBRPOP 会一直等待,直到有新元素被添加。


3. 实际应用场景

消息队列

在需要实现生产者-消费者模型的应用场景中,可以利用 LPUSHBRPOP 来创建一个消息队列。生产者将消息推入队列的一端,而消费者则从另一端取出消息处理。这种方式能够保证消息的有序性和并发消费的能力。

示例

  • 生产者:

    redis> LPUSH queue "message1"
    (integer) 1
    redis> LPUSH queue "message2"
    (integer) 2
    
  • 消费者:

    redis> BRPOP queue 0
    1) "queue"
    2) "message2"
    redis> BRPOP queue 0
    1) "queue"
    2) "message1"
    
社交媒体时间线

对于社交媒体平台来说,用户的动态更新通常按照时间顺序展示。通过使用 Redis 列表,我们可以轻松地维护每个用户的时间线。每当用户发布新内容时,就将其添加到列表顶部;而当用户浏览时,则按需加载最新的几条动态。

示例

  • 发布新微博:

    redis> LPUSH user:1:timeline "tweet1"
    (integer) 1
    redis> LPUSH user:1:timeline "tweet2"
    (integer) 2
    
  • 查看最新 10 条微博:

    redis> LRANGE user:1:timeline 0 9
    1) "tweet2"
    2) "tweet1"
    
任务调度

在某些后台系统中,可能需要定期执行一些任务。这时就可以把即将要执行的任务放进一个列表里,然后设置定时器逐个取出并执行这些任务。

示例

  • 添加任务:

    redis> RPUSH tasks "task1"
    (integer) 1
    redis> RPUSH tasks "task2"
    (integer) 2
    
  • 执行任务:

    redis> LPOP tasks
    "task1"
    redis> LPOP tasks
    "task2"
    

4. 内部机制简介

为了提高效率,Redis 会根据列表的实际大小选择不同的内部表示方法:

  • 压缩列表(ziplist):如果列表中的元素不多且每个元素都很小,那么 Redis 会选择一种叫做压缩列表的方式来存储,这样可以节省内存空间。
  • 链表(linkedlist):当列表变得很大或者包含大量大尺寸的元素时,Redis 会转而使用链表来表示这个列表,从而保持操作性能不受影响。

示例

  • 使用压缩列表:

    redis> RPUSH smalllist "a" "b" "c"
    (integer) 3
    redis> OBJECT ENCODING smalllist
    "ziplist"
    
  • 使用链表:

    redis> RPUSH biglist "a" "b" "c" ... (超过 512 个元素)
    (integer) 513
    redis> OBJECT ENCODING biglist
    "linkedlist"
    

5. 命令小结

操作类型 命令 时间复杂度
添加 RPUSH key value [value ...] O(k),k 是元素个数
LPUSH key value [value ...] O(k),k 是元素个数
`LINSERT key BEFORE AFTER pivot value`
查找 LRANGE key start end O(s+n),s 是 start 偏移量,n 是 start 到 end 的范围
LINDEX key index O(n),n 是索引的偏移量
LLEN key O(1)
删除 LPOP key O(1)
RPOP key O(1)
LREM key count value O(k),k 是元素个数
LTRIM key start end O(k),k 是元素个数
修改 LSET key index value O(n),n 是索引的偏移量
阻塞操作 BLPOP key [key ...] timeout O(1)
BRPOP key [key ...] timeout O(1)

以上就是有关 Redis 的列表的知识,后续会继续更新,感谢阅览!!

相关推荐
栀夏6134 分钟前
Linux 基础
linux
程序人生51812 分钟前
PostgreSQL分区表
数据库·postgresql·分区表
喻师傅13 分钟前
Linux-du命令使用方法
linux·服务器·命令
埋头编程~29 分钟前
【Linux】趣味讲解“权限“的那些事(重点讲解文件权限,内含su、sudo、chmod、chown、umask等指令)
java·linux·运维
和煦的糖果34 分钟前
Linux下的基本指令
linux·运维·服务器
bug菌¹35 分钟前
滚雪球学MySQL[3.1讲]: 高级SQL查询
数据库·sql·mysql
燕雀安知鸿鹄之志哉.37 分钟前
玄机:第二章 日志分析-mysql应急响应
数据库·经验分享·mysql·安全·web安全·网络安全
Amelio_Ming41 分钟前
linux semaphore信号量操作
linux
小强不秃头1 小时前
Linux C——网络编程
linux·c语言·开发语言
我是果子哥1 小时前
Git的安装 + 基本操作
linux·git