redis学习-14- Redis list列表操作
redis学习-14- Redis list列表操作
10.list列表
- Redis list(列表)是简单的字符串列表,相当于 Java 语言中的 LinkedList 结构,是一个链表而非数组,其插入、删除元素的时间复杂度为 O(1),但是查询速度差,时间复杂度为 O(n)。
- 当向列表中添加元素值时,首先需要给这个列表指定一个 key 键,若是键不存在,建立新的链表,然后使用相应的命令,从列表的左侧(头部)或者右侧(尾部)来添加元素,这些元素会以添加时的顺序排列。一个列表最多可以包含 2^32 - 1 个元素(约 40 亿个元素),当列表弹出最后一个元素时,该结构会被自动删除。
链表的操做不管是头和尾效率都极高,但假如是对中间元素进行操做,效率就很差了
- Redis 列表的底层存储结构,其实是一个被称为快速链表(quicklist)的结构。当列表中存储的元素较少时,Redis 会使用一块连续的内存来存储这些元素,这个连续的结构被称为 ziplist(压缩列表),它将所有的元素紧挨着一起存储。
压缩列表是 Redis 为节省内存而开发的,它是由一系列特殊编码的连续内存块组成的顺序型数据结构,一个压缩列表了可以包含任意多个节点,每个节点都可以保存一个字符数组或者整数值。
- 而当数据量较大时,Redis 列表就会是用普通链表存储元素。Redis 之所以采用两种方法相结合的方式来存储元素。这是因为单独使用普通链表存储元素时,所需的空间较大,会造成存储空间的浪费。因此采用了链表和压缩列表相结合的方式,也就是 quicklist + ziplist,结构如下图:
-
上图所示,将多个 ziplist 使用双向指针串联起来,这样既能满足快速插入、删除的特性,又节省了一部分存储空间。
-
使用命令操作 Redis 列表。示例:如何从列表的左侧、右侧添加和弹出元素。
#从左侧头部插入元素
remote:0>lpush listcontext php java C++
"3"
remote:0>lpush listcontext php java C++
"6"
#查看插入的元素
remote:0>lrange listcontext 0 5
1) "C++"
2) "java"
3) "php"
4) "C++"
5) "java"
6) "php"
#从右侧尾部插入元素
remote:0>rpush listcontext dubbo c# lua
"9"
remote:0>rpush listcontext dubbo c# lua
"12"
#查看元素
remote:0>lrange listcontext 0 14
1) "C++"
2) "java"
3) "php"
4) "C++"
5) "java"
6) "php"
7) "C++"
8) "java"
9) "php"
10) "dubbo"
11) "c#"
12) "lua"
13) "dubbo"
14) "c#"
15) "lua"
#在php前面插入元素
remote:0>linsert listcontext before php vue
"8"
remote:0>lrange listcontext 0 7
1) "C++"
2) "java"
3) "sql"
4) "vue"
5) "php"
6) "dubbo"
7) "c#"
8) "lua"
#从左侧弹出元素
remote:0>lpop listcontext
"C++"
#从右侧弹出元素
remote:0>rpop listcontext
"dubbo"
10.1 队列和栈实现
- Redis 列表可以被当做栈、队列、阻塞队列来使用,栈和队列就是操作受限的线性表。如果列表的元素是“左进右出”那就是队列模型(一个一个进出理解);如果元素是“右进右出”那就是栈模型(一个一个进出理解),示例如下:
- 如果key不存在,创建新的链表。
- 如果key存在,新增内容。
- 如果移除了所有值,空链表代表不存在!
- 在两边插入或者改动值,效率最高!操作中间元素,相对来说效率会低一点。
- 左进右出,LPUSH 命令将一个或多个值插入到列表头部(从左侧开始操作),如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入。
remote:0>lpush course c java ai
"3"
remote:0>rpop course
"c"
remote:0>rpop course
"java"
remote:0>rpop course
"ai"
- 右进左出
remote:0>rpush course c java ai
"3"
remote:0>lpop course
"c"
remote:0>lpop course
"java"
remote:0>lpop course
"ai"
remote:0>lpop course
null
remote:0>lrange course 0 2
- 右进右出
remote:0>rpush course c java ai
"3"
remote:0>rremote:0>pop course
"ai"
remote:0>rpop course
"java"
remote:0>rpop course
"c"
remote:0>rpop course
null
- 除上述模型外,Redis 的列表也常被用作异步队列。使用流程大致如下:一个线程将需要延时处理的任务序列化成字符串,并“塞”进 Redis 列表中,而另外一个线程则以轮询的方式从该列表中读取“任务”。作为消息队列队列、栈的特性可以替代mq进行使用。
list可以记录用户的最近浏览商品记录
10.2 常用命令汇总
- List 是 Redis 中最常用数据类型之一(单值多value)。Redis 提供了诸多用于操作列表类型的命令,通过这些命令可以实现将一个元素添加到列表的头部,或者尾部等诸多操作。Redis不区分大小命令。
命令 | 说明 |
---|---|
LPUSH key value1 [value2] | 在列表头部插入一个或者多个值。 |
LRANGE key start stop | 获取列表指定范围内的元素。 |
RPUSH key value1 [value2] | 在列表尾部添加一个或多个值。 |
LPUSHX key value | 当储存列表的 key 存在时,用于将值插入到列表头部。 |
RPUSHX key value | 当存储列表的 key 存在时,用于将值插入到列表的尾部。 |
LINDEX key index | 通过索引获取列表中的元素,都是从零开始。 |
LINSERT key before|after pivot value | 指定列表中一个元素在它之前或之后插入另外一个元素。 |
LREM key count value | 表示从列表中left往right删除元素与 value 相等的元素。count 表示删除的数量,为 0 表示全部移除,返回的值为实际删除的数量。 |
LSET key index value | 表示通过其索引设置列表中元素的值。 |
LTRIM key start stop | 保留列表中指定范围内的元素值。 |
LPOP key | 从列表的头部弹出元素,默认为第一个元素。 |
RPOP key | 从列表的尾部弹出元素,默认为最后一个元素。 |
LLEN key | 用于获取列表的长度。 |
RPOPLPUSH source destination | 用于删除列表中的最后一个元素,然后将该元素添加到另一个列表的头部,并返回该元素值。 |
BLPOP key1 [key2 ] timeout | 用于删除并返回列表中的第一个元素(头部操作),如果列表中没有元素,就会发生阻塞, 直到列表等待超时或发现可弹出元素为止。 |
BRPOP key1 [key2 ] timeout | 用于删除并返回列表中的最后一个元素(尾部操作),如果列表中没有元素,就会发生阻塞, 直到列表等待超时或发现可弹出元素为止。 |
BRPOPLPUSH source destination timeout | 从列表中取出最后一个元素,并插入到另一个列表的头部。如果列表中没有元素,就会发生 阻塞,直到等待超时或发现可弹出元素时为止。 |
10.3 BLPOP命令
- Redis BLPOP 命令是列表弹出元素的阻塞模式,当给定列表内没有任何元素可供弹出的时候,连接将被 BLPOP 命令阻塞,直到等待超时或发现可弹出元素为止。
- 当给定多个 key 时,按 key 的先后顺序依次检查各个列表,弹出第一个非空列表的头元素。命令可用版本:>= 2.0.0。 BLPOP 命令的基本语法如下:
BLPOP key [key ...] timeout
- BLPOP 命令的返回值:如果列表为空,返回一个 null 。否则,返回一个含有两个元素的列表,第一个元素是被弹出元素所属的 key,第二个元素是被弹出元素的值。命令演示:
remote:0>lpush course java c++ c#
"3"
#弹出列表中第一个元素,并返回存储它的key
remote:0>blpop course 5
1) "course"
2) "c#"
remote:0>blpop course 5
1) "course"
2) "c++"
remote:0>blpop course 5
1) "course"
2) "java"
#设置超时时间,否则将一直阻塞
remote:0>blpop course 5
10.4 BRPOP命令
- BRPOP 命令是 RPOP 的阻塞模式,当给定列表内没有任何元素可供弹出的时候,连接将被 BRPOP 命令阻塞,直到等待超时或发现可弹出元素为止。
- 当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的尾部元素。命令可用版本:>= 2.0.0.BRPOP 命令的基本语法如下:
BRPOP key [key ...] timeout
- BRPOP 命令的返回值:假如在指定时间内没有任何元素被弹出,则返回一个 nil 和等待时长。否则,返回一个含有两个元素的列表,第一个元素是被弹出元素所属的 key,第二个元素是被弹出元素的值。
remote:0>lpush course java c++ c#
"3"
remote:0>brpop course 5
1) "course"
2) "java"
remote:0>brpop course 5
1) "course"
2) "c++"
remote:0>brpop course 5
1) "course"
2) "c#"
remote:0>brpop course 5
10.5 BRPOPLPUSH命令
- RPOPLPUSH 命令执行以下两步操作:首先将列表(source)中的最后一个元素(尾元素)弹出,并返回给客户端。然后将弹出的元素插入到另外一个指定的列表(destination)中,并作为该列表的的头元素。命令可用版本:>= 1.2.0。BPOPLPUSH 命令的基本语法如下:
非语法糖,语法糖是简写,这个组合命令保证原子性,不算简写
RPOPLPUSH source destination
-
如果 source 不存在,那么将 返回 null,并且不再执行其他操作。 如果 source 和 destination 相同,则列表中的表尾元素被移动到表头,并返回该元素,可以把这种特殊情况看做翻转列表操作。
-
BPOPLPUSH 命令的返回值被弹出的元素。
#创建列表并添加元素
remote:0>lpush course java c++ c#
"3"
remote:0>lrange course 0 2
1) "c#"
2) "c++"
3) "java"
#将course的尾部元素弹出,添加到web列表的头部
remote:0>rpoplpush course lesson
"java"
remote:0>rpoplpush course lesson
"c++"
remote:0>rpoplpush course lesson
"c#"
remote:0>rpoplpush course lesson
null
remote:0>lrange lesson 0 2
1) "c#"
2) "c++"
3) "java"
#如果 source 和 destination 相同,
remote:0>lpush course java c++ c#
"3"
remote:0>rpoplpush course lesson
"java"
remote:0>lrange course 0 2
1) "c#"
2) "c++"
remote:0>lrange lesson 0 4
1) "java"
2) "c#"
3) "c++"
4) "java"
10.6 LINDEX命令
- LINDEX 命令返回列表中,下标为 index 的元素且从上到下。命令可用版本:>= 1.0.0。LINDEX 命令的基本语法如下:
LINDEX key index
- Redis LINDEX 命令的返回值:列表中下标为 index 的元素。如果 index 参数值超出列表的区间范围(out of range),则返回null。命令演示
remote:0>lrange lesson 0 4
1) "java"
2) "c#"
3) "c++"
4) "java"
##下标为0的元素
remote:0>lindex lesson 0
"java"
##超出索引范围返回null
remote:0>lindex lesson 4
null
remote:0>lindex lesson 3
"java"
10.7 LINSERT命令
- Redis LINSERT 命令将值 value 插入到列表 key 当中,位于值 pivot 之前或之后。
- 当 pivot (参照值)不存在于列表 key 时,不执行任何操作。当 key 不存在时, key 被视为空列表,不执行任何操作。如果 key 不是列表类型,返回一个错误。命令可用版本:>= 2.2.0。LINSERT 命令的基本语法如下:
LINSERT key BEFORE|AFTER pivot value
- LINSERT 命令的返回值:如果命令执行成功,返回插入操作完成之后,列表的长度;如果没有找到 pivot ,返回 -1 。如果 key 不存在或为空列表,返回 0 。命令演示
#同时添加多个value
remote:0>lpush lesson java c# php
"3"
#在c#之前添加提个值
remote:0>linsert lesson before c# php
"4"
#在c#之后添加一个值
remote:0>linsert lesson after c# php
"5"
#在redis之后添加一个值
remote:0>linsert lesson after c## php
"-1"
#浏览列表中所有元素
remote:0>lrange lesson 0 8
1) "php"
2) "php"
3) "c#"
4) "php"
5) "java"
10.8 LLEN命令
- LLEN命令返回列表 key 的长度。如果 key 不是列表类型,返回一个错误。命令可用版本:>= 1.0.0。LLEN 命令的基本语法如下:
LLEN key
- LLEN 命令的返回值列表 key 的长度。命令演示
remote:0>lrange lesson 0 8
1) "php"
2) "php"
3) "c#"
4) "php"
5) "java"
#查看长度
remote:0>llen lesson
"5"
10.9 LPOP命令
- LPOP 命令移除并返回列表 key 的头元素。命令可用版本:>= 1.0.0。LPOP 命令的基本语法如下:
LPOP key
- LPOP 命令的返回值是列表的头部的第一个元素。当 key 不存在时,则返回 null 。命令演示:
#同时添加多个value
remote:0>lpush lesson java c++ php
"3"
#添加重复的值
remote:0>lpush lesson java c++ php
"6"
#只添加一个值
remote:0>lpush lesson sql
"7"
#从左侧头部弹出第一个元素
remote:0>lpop lesson
"sql"
10.10 LPUSH、LPUSHX命令
- LPUSH 命令将一个或多个值插入到列表头部(从左侧开始操作),如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入。如果 key 不存在,那么一个空列表会被自动创建并执行 LPUSH 操作;当 key 存在但不是列表类型时,则返回一个错误。 命令可用版本:>= 1.0.0
注意:在 Redis 2.4 版本以前的 LPUSH 命令,都只接受单个 value 值。 左进右为顶;右进右为底
-
LPUSHX 命令,当且仅当 key 存在,并且类型为列表时,将值 value 插入到列表的头部。和 LPUSH 命令相反,当 key 不存在时, LPUSHX 命令什么也不执行。命令可用版本:>= 2.2.0
-
命令的基本语法如下:
#LPUSH 命令的基本语法如下:
LPUSH key value [value ...]
#LPUSHX 命令的基本语法如下:
LPUSHX key value
- LPUSH 命令的返回值:执行 LPUSH 命令后,返回列表中元数的的个数。即列表的长度。
- LPUSHX 命令的返回值:表的长度。命令演示:
#同时添加多个value,左进右为顶;右进右为底
remote:0>lpush lesson java c++ php
"3"
#添加重复的值
remote:0>lpush lesson java c++ php
"6"
#只添加一个值
remote:0>lpush lesson sql
"7"
remote:0>set name zs
"OK"
#类型不符,name是字符串类型的key
remote:0>lpush name ls
"WRONGTYPE Operation against a key holding the wrong kind of value"
#执行lpushx命令,添加成功并返回元素的个数
remote:0>lpushx lesson c#
"7"
#添加不存在的key,则失败
remote:0>lpushx lessons c#
"0"
10.11 LRANGE命令
- Redis LRANGE 命令返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。
- 下标(index)参数 start 和 stop 都是以 0 开始,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素。命令可用版本:>= 1.0.0
注意:LRANGE 命令是一个闭区间操作,取值范围包括 stop 值。它不同于 Python 的 range()函数。
- Redis LRANGE 命令的基本语法如下:
LRANGE key start stop
- LRANGE 命令的返回值:一个列表,包含指定区间内的元素。
#同时添加多个value
remote:0>lpush lesson java c++ php
"3"
#查看元素
remote:0>lrange lesson 0 8
1) "php"
2) "c++"
3) "java"
10.12 LREM命令
-
LREM 命令根据 count 的值,移除列表中与参数 value 相等的元素。命令可用版本:>= 1.0.0。场景:取关特定的值。
-
count 取值有以下几种情况:
- count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
- count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
- count = 0 : 移除表中所有与 value 相等的值。
-
LREM 命令的基本语法如下:
LREM key count value
- LREM 命令的返回值被移除元素的数量。若 key 不存在时, 则 LREM 命令总是返回 0 。
remote:0>lpush lesson java c++ php
"3"
remote:0>lpush lesson java c++ php
"6"
remote:0>lpush lesson java c++ php
"9"
#count决定删除数量,这里取其绝对值
remote:0>lrem lesson 2 php
"2"
remote:0>lrange lesson 0 20
1) "c++"
2) "java"
3) "c++"
4) "java"
5) "php"
6) "c++"
7) "java"
remote:0>lrem lesson -2 java
"2"
remote:0>lrange lesson 0 20
1) "c++"
2) "java"
3) "c++"
4) "php"
5) "c++"
10.13 LSET 命令
- LSET 命令能够将列表中下标为 index 的元素的值设置为 value。当 index 参数超出范围,或对一个空列表( key 不存在)进行 LSET 时,将会返回一个错误。命令可用版本:>= 1.0.0。LSET 命令的基本语法如下:
LSET key index value
- LSET 命令的返回值:操作成功返回 ok ,否则返回错误信息。命令演示
remote:0>lrange lesson 0 20
1) "c++"
2) "java"
3) "c++"
4) "php"
5) "c++"
#更改值
remote:0>lset lesson 0 C#
"OK"
remote:0>lrange lesson 0 10
1) "C#"
2) "java"
3) "c++"
4) "php"
5) "c++"
#index 参数超出范围
remote:0>lset lesson 8 C#
"ERR index out of range"
10.14 LTRIM命令
- LTRIM 命令对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除,然后再赋值给key。命令可用版本:>= 1.0.0。LTRIM 命令的基本语法如下:
LTRIM key start stop
注意:如果 start 的值大于列表的最大长度,或者 start > stop,那么 LTRIM 命令会将整个列表清空,并返回一个空列表。
- LTRIM 命令的返回值操作成功返回 ok ,否则返回错误信息。命令演示
remote:0>lrange lesson 0 10
1) "C#"
2) "java"
3) "c++"
4) "php"
5) "c++"
#裁剪元素只保留三个元素
remote:0>ltrim lesson 1 3
"OK"
#查看结果
remote:0>lrange lesson 0 10
1) "java"
2) "c++"
3) "php"
下一篇:redis学习-15- Redis hash哈希散列
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)