🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇
⭐ 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"]
。 -
LPUSHX
和RPUSHX
命令 :这些命令类似于LPUSH
和RPUSH
,但只有当键已经存在时才会执行插入操作。例如: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
阻塞式操作
BLPOP
和 BRPOP
命令 :这些命令是 LPOP
和 RPOP
的阻塞版本。当列表为空时,这些命令不会立即返回空结果,而是等待一段时间,直到有新的元素被添加到列表中。例如:
redis> BLPOP mylist 0
1) "cherry"
2) "blueberry"
redis> BRPOP mylist 0
1) "mylist"
2) "elderberry"
如果 mylist
为空,BLPOP
和 BRPOP
会一直等待,直到有新元素被添加。
3. 实际应用场景
消息队列
在需要实现生产者-消费者模型的应用场景中,可以利用
LPUSH
和BRPOP
来创建一个消息队列。生产者将消息推入队列的一端,而消费者则从另一端取出消息处理。这种方式能够保证消息的有序性和并发消费的能力。
示例:
-
生产者:
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 的列表的知识,后续会继续更新,感谢阅览!!