【Redis】List

List 列表

列表类型是用来存储多个有序的字符串

如下图所示,a、b、c、d、e 五个元素从左到右组成了一个有序的列表,列表中的每个字符串称为元素(element),一个列表最多可以存储 (232-1) 个元素。

在 Redis 中,可以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等

列表是一种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发中有很多应用场景。

在这里插入图片描述

在这里插入图片描述

列表类型的特点:

  1. 列表中的元素是有序的,这意味着可以通过索引下标获取某个元素或者某个范围的元素列表,例如要获取图 2-20 的第 5 个元素,可以执行 lindex user:1:messages 4 或者倒数第 1 个元素,lindex user:1:messages -1 就可以得到元素 e。
  2. 区分获取和删除的区别,例如图 2-20 中的 lrem 1 b 是从列表中把从左数遇到的前 1 个 b 元素删除,这个操作会导致列表的长度从 5 变成 4;但是执行 lindex 4 只会获取元素,但列表长度是不会变化的。
  3. 列表中的元素是允许重复的,例如图 2-21 中的列表中是包含了两个 a 元素的。

key:user:1:messages ,value 中包含重复的 a 元素。

命令

LPUSH

  • 功能:将一个或者多个元素从左侧放入(头插)到 list 中。
  • 语法LPUSH key element [element ...]
  • 命令有效版本:1.0.0 之后
  • 时间复杂度:只插入一个元素为 O(1),插入多个元素为 O(N),N 为插入元素个数。
  • 返回值:插入后 list 的长度。
  • 示例
redis> LPUSH mylist "world"
(integer) 1
redis> LPUSH mylist "hello"
(integer) 2
redis> LRANGE mylist 0 -1
1) "hello"
2) "world"

LPUSHX

  • 功能:在 key 存在时,将一个或者多个元素从左侧放入(头插)到 list 中。不存在,直接返回。
  • 语法LPUSHX key element [element ...]
  • 命令有效版本:2.0.0 之后
  • 时间复杂度:只插入一个元素为 O(1),插入多个元素为 O(N),N 为插入元素个数。
  • 返回值:插入后 list 的长度。
  • 示例
redis> LPUSH mylist "World"
(integer) 1
redis> LPUSHX mylist "Hello"
(integer) 2
redis> LPUSHX myotherlist "Hello"
(integer) 0
redis> LRANGE mylist 0 -1
1) "Hello"
2) "World"
redis> LRANGE myotherlist 0 -1
(empty array)

RPUSH

  • 功能:将一个或者多个元素从右侧放入(尾插)到 list 中。
  • 语法RPUSH key element [element ...]
  • 命令有效版本:1.0.0 之后
  • 时间复杂度:只插入一个元素为 O(1),插入多个元素为 O(N),N 为插入元素个数。
  • 返回值:插入后 list 的长度。
  • 示例
redis> RPUSH mylist "world"
(integer) 1
redis> RPUSH mylist "hello"
(integer) 2
redis> LRANGE mylist 0 -1
1) "world"
2) "hello"

RPUSHX

  • 功能:在 key 存在时,将一个或者多个元素从右侧放入(尾插)到 list 中。
  • 语法RPUSHX key element [element ...]
  • 命令有效版本:2.0.0 之后
  • 时间复杂度:只插入一个元素为 O(1),插入多个元素为 O(N),N 为插入元素个数。
  • 返回值:插入后 list 的长度。
  • 示例
redis> RPUSH mylist "World"
(integer) 1
redis> RPUSHX mylist "Hello"
(integer) 2
redis> RPUSHX myotherlist "Hello"
(integer) 0
redis> LRANGE mylist 0 -1
1) "World"
2) "Hello"
redis> LRANGE myotherlist 0 -1
(empty array)

LRANGE

  • 功能:获取从start到end区间的所有元素,左闭右闭。
  • 语法LRANGE key start stop
  • 命令有效版本:1.0.0之后
  • 时间复杂度:O(N)
  • 返回值:指定区间的元素。
  • 示例
redis> RPUSH mylist "one"
(integer) 1
redis> RPUSH mylist "two"
(integer) 2
redis> RPUSH mylist "three"
(integer) 3
redis> LRANGE mylist 0 0
1) "one"
redis> LRANGE mylist -3 2
1) "one"
2) "two"
3) "three"
redis> LRANGE mylist -100 100
1) "one"
2) "two"
3) "three"
redis> LRANGE mylist 5 10
(empty array)

LPOP

  • 功能:从list左侧取出元素(即头删)。
  • 语法LPOP key
  • 命令有效版本:1.0.0之后
  • 时间复杂度:O(1)
  • 返回值:取出的元素或者nil。
  • 示例
redis> RPUSH mylist "one" "two" "three" "four" "five"
(integer) 5
redis> LPOP mylist
"one"
redis> LPOP mylist
"two"
redis> LPOP mylist
"three"
redis> LRANGE mylist 0 -1
1) "four"
2) "five"

RPOP

  • 功能:从list右侧取出元素(即尾删)。
  • 语法RPOP key
  • 命令有效版本:1.0.0之后
  • 时间复杂度:O(1)
  • 返回值:取出的元素或者nil。
  • 示例
redis> RPUSH mylist "one" "two" "three" "four" "five"
(integer) 5
redis> RPOP mylist
"five"
redis> LRANGE mylist 0 -1
1) "one"
2) "two"
3) "three"
4) "four"

LINDEX

  • 功能:获取从左数第index位置的元素。
  • 语法LINDEX key index
  • 命令有效版本:1.0.0之后
  • 时间复杂度:O(N)
  • 返回值:取出的元素或者nil。
  • 示例
redis> LPUSH mylist "World"
(integer) 1
redis> LPUSH mylist "Hello"
(integer) 2
redis> LINDEX mylist 0
"Hello"
redis> LINDEX mylist -1
"World"
redis> LINDEX mylist 3
(nil)

LINSERT

  • 功能:在特定位置插入元素。
  • 语法LINSERT key <BEFORE | AFTER> pivot element
  • 命令有效版本:2.2.0之后
  • 时间复杂度:O(N)
  • 返回值:插入后的list长度。
  • 示例
redis> RPUSH mylist "Hello"
(integer) 1
redis> RPUSH mylist "World"
(integer) 2
redis> LINSERT mylist BEFORE "World" "There"
(integer) 3
redis> LRANGE mylist 0 -1
1) "Hello"
2) "There"
3) "World"

LLEN

  • 功能:获取list长度。
  • 语法LLEN key
  • 命令有效版本:1.0.0之后
  • 时间复杂度:O(1)
  • 返回值:list的长度。
  • 示例
redis> LPUSH mylist "World"
(integer) 1
redis> LPUSH mylist "Hello"
(integer) 2
redis> LLEN mylist
(integer) 2

阻塞版本命令

blpop和brpop是lpop和rpop的阻塞版本,和对应非阻塞版本的作用基本一致,除了:

  • 在列表中有元素的情况下,阻塞和非阻塞表现是一致的。但如果列表中没有元素,非阻塞版本会理解返回nil,但阻塞版本会根据timeout阻塞一段时间,期间Redis可以执行其他命令,但要求执行该命令的客户端会表现为阻塞状态。
  • 命令中如果设置了多个键,那么会从左向右进行遍历键,一旦有一个键对应的列表中可以弹出元素,命令立即返回。
  • 如果多个客户端同时对多个键执行pop,则最先执行命令的客户端会得到弹出的元素。
BLPOP
  • 功能:LPOP的阻塞版本。
  • 语法:BLPOP key [key …] timeout
  • 命令有效版本:1.0.0之后
  • 时间复杂度:O(1)
  • 返回值:取出的元素或者nil。
  • 示例
redis> EXISTS list1 list2
(integer) 0
redis> RPUSH list1 a b c
(integer) 3
redis> BLPOP list1 list2 0
1) "list1"
2) "a"
BRPOP
  • 功能:RPOP的阻塞版本。
  • 语法:BRPOP key [key …] timeout
  • 命令有效版本:1.0.0之后
  • 时间复杂度:O(1)
  • 返回值:取出的元素或者nil。
  • 示例
redis> DEL list1 list2
(integer) 0
redis> RPUSH list1 a b c
(integer) 3
redis> BRPOP list1 list2 0
1) "list1"
2) "c"

命令小结

有关列表的命令已经介绍完毕,表2-5是这些命令的作用和时间复杂度,开发人员可以参考。

操作类型命令时间复杂度
添加rpush key value [value …]O(k),k是元素个数
lpush key value [value …]O(k),k是元素个数
lpushx key value [value …]O(k),k是元素个数
linsert key beforeO(n),n是pivot距离头/尾的距离
查找lrange key start endO(s+n),s是start偏移量,n是start到end的范围
lindex key indexO(n),n是索引的偏移量
llen keyO(1)
删除lpop keyO(1)
rpop keyO(1)
lrem key count valueO(k),k是元素个数
ltrim key start endO(k),k是元素个数
修改lset key index valueO(n),n是索引的偏移量
阻塞操作blpop brpopO(1)

内部编码

列表类型的内部编码有两种:

  • ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的长度都小于list-max-ziplist-value配置(默认64字节)时,Redis会选用ziplist来作为列表的内部编码实现来减少内存消耗。
  • linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现。

下面是内部编码转换示例:

  1. 当元素个数较少且没有大元素时,内部编码为ziplist
127.0.0.1:6379> rpush listkey e1 e2 e3
OK
127.0.0.1:6379> object encoding listkey
"ziplist"
  1. 当元素个数超过512时,内部编码为linkedlist
127.0.0.1:6379> rpush listkey e1 e2 e3 ... 省略 ... e512 e513
OK
127.0.0.1:6379> object encoding listkey
"linkedlist"
  1. 当某个元素的长度超过64字节时,内部编码为linkedlist
127.0.0.1:6379> rpush listkey "one string is bigger than 64 bytes ... 省略 ..."
OK
127.0.0.1:6379> object encoding listkey
"linkedlist"
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值