Redis List 类型操作及常用命令

Redis List 类型操作及常用命令

Scroll Down

七个原则

  1. Redis 是一个操作数据结构的语言工具,它提供基于 TCP 的协议以操作丰富的数据结构。在 Redis 中,数据结构这个词的意义不仅表示在某种数据结构上的操作,更包括了结构本身及这些操作的时间空间复杂度。
  2. Redis 定位于一个内存数据库,正是由于内存的快速访问特性,才使得 Redis 能够有如此高的性能,才使得 Redis 能够轻松处理大量复杂的数据结构, Redis 会尝试其它的存储方面的选择,但是永远不会改变它是一个内存数据库的角色。
  3. Redis 使用基础的 API 操作基础的数据结构, Redis 的 API 与数据结构一样,都是一些最基础的元素,你几乎可以将任何信息交互使用此 API 格式表示。作者调侃说,如果有其它非人类的智能生物存在,他们也能理解 Redis 的 API。因为它是如此的基础。
  4. Redis 有着诗一般优美的代码,经常有一些不太了解 Redis 有的人会建议 Redis 采用一些其它人的代码,以实现一些 Redis 未实现的功能,但这对我们来说就像是非要给《红楼梦》接上后四十回一样。
  5. Redis 始终避免复杂化,我们认为设计一个系统的本质,就是与复杂化作战。我们不会为了一个小功能而往源码里添加上千行代码,解决复杂问题的方法就是让复杂问题永远不要提复杂的问题。
  6. Redis 支持两个层成的 API,第一个层面包含部分操作 API,但它支持用于分布式环境下的 Redis。第二个层面的 API 支持更复杂的 multi-key 操作。它们各有所长,但是我们不会推出两者都支持的 API,但我们希望能够提供实例间数据迁移的命令,并执行 multi-key 操作。
  7. 我们以优化代码为乐,我们相信编码是一件辛苦的工作,唯一对得起这辛苦的就是去享受它。如果我们在编码中失去了乐趣,那最好的解决办法就是停下来。我们决不会选择让 Redis 不好玩的开发模式。

lists 类型及操作

list 是一个链表结构,主要功能是 push、 pop、获取一个范围的所有值等等, 操作中 key 理解为链表的名字。

Redis 的 list 类型其实就是一个每个子元素都是 string 类型的双向链表。链表的最大长度是(2的 32 次方)。我们可以通过 push,pop 操作从链表的头部或者尾部添加删除元素。这使得 list 既可以用作栈,也可以用作队列。

有意思的是 list 的 pop 操作还有阻塞版本的,当我们[lr]pop 一个 list 对象时,如果 list 是空,或者不存在,会立即返回 nil。但是阻塞版本的 b[lr]pop 可以则可以阻塞,当然可以加超时时间,超时后也会返回 nil。为什么要阻塞版本的 pop 呢,主要是为了避免轮询。举个简单的例子如果我们用 list 来实现一个工作队列。执行任务的 thread 可以调用阻塞版本的 pop 去获取任务这样就可以避免轮询去检查是否有任务存在。当任务来时候工作线程可以立即返回, 也可以避免轮询带来的延迟。说了这么多,接下来看一下实际操作的方法吧。

常用命令

lpush

在 key 对应 list 的头部添加字符串元素。返回 list 中元素的个数。

127.0.0.1:6379> lpush mylist Jacob
(integer) 1
127.0.0.1:6379> lpush mylist Jacob2
(integer) 2
lrange

用于去 list 的内容,开始为 0,结束为 list 长度 -1。若结束大于等于 list 长度 -1,默认为 list 长度 -1。

127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob2"
2) "Jacob"
3) "Jacob_r"
rpush

在 key 对应 list 的尾部添加字符串元素。

127.0.0.1:6379> rpush mylist Jacob_r
(integer) 3
linsert

在 key 对应 list 的特定位置之前或之后添加字符串元素。

127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob2"
2) "Jacob"
3) "Jacob_r"
127.0.0.1:6379> linsert mylist before Jacob Jacob_before
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob2"
2) "Jacob_before"
3) "Jacob"
4) "Jacob_r"
lset

设置 list 中指定下标的元素值(下标从 0 开始)

127.0.0.1:6379> lrange mylist 0 1
1) "Jacob2"
2) "Jacob_before"
3) "Jacob"
4) "Jacob_r"
127.0.0.1:6379> lset mylist 0 Jacob1
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob1"
2) "Jacob_before"
3) "Jacob"
4) "Jacob_r"
lrem

从 key 对应 list 中删除 count 个和 value 相同的元素。
count>0 时,按从头到尾的顺序删除,具体如下:

127.0.0.1:6379> lrange mylist 0 -1
 1) "Jacob"
 2) "Jacob"
 3) "Jacob"
 4) "Jacob"
 5) "Jacob"
 6) "Jacob"
 7) "Jacob1"
 8) "Jacob_before"
 9) "Jacob"
10) "Jacob_r"
127.0.0.1:6379> lrem mylist 2 Jacob
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob"
2) "Jacob"
3) "Jacob"
4) "Jacob"
5) "Jacob1"
6) "Jacob_before"
7) "Jacob"
8) "Jacob_r"

count<0 时,按从尾到头的顺序删除,具体如下:

127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob"
2) "Jacob"
3) "Jacob"
4) "Jacob"
5) "Jacob1"
6) "Jacob_before"
7) "Jacob"
8) "Jacob_r"
127.0.0.1:6379> lrem mylist -2 Jacob
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob"
2) "Jacob"
3) "Jacob"
4) "Jacob1"
5) "Jacob_before"
6) "Jacob_r"

count=0 时,删除全部,具体如下:

127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob"
2) "Jacob"
3) "Jacob"
4) "Jacob1"
5) "Jacob_before"
6) "Jacob_r"
127.0.0.1:6379> lrem mylist 0 Jacob
(integer) 3
127.0.0.1:6379> lrange mylist 0 100
1) "Jacob1"
2) "Jacob_before"
3) "Jacob_r"
ltrim

保留指定 key 的值范围内的数据。

127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob1"
2) "Jacob_before"
3) "Jacob_r" 
127.0.0.1:6379> ltrim mylist 1 -1
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob_before"
2) "Jacob_r"
lpop

从 list 的头部删除元素,并返回删除元素。

127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob_before"
2) "Jacob_r"
127.0.0.1:6379> lpop mylist
"Jacob_before"
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob_r"
rpop

从 list 的尾部删除元素,并返回删除元素。

127.0.0.1:6379> rpop mylist
"Jacob_r"
127.0.0.1:6379> lrange mylist 0 -1
(empty list or set)
rpoplpush

从第一个 list 的尾部移除元素并添加到第二个 list 的头部,最后返回被移除的元素值,整个操作是原子的.如果第一个 list 是空或者不存在返回 nil。

127.0.0.1:6379> lpush mylist Jacob1
(integer) 1
127.0.0.1:6379> lpush mylist Jacob2
(integer) 2
127.0.0.1:6379> lpush mylist Jacob3
(integer) 3
127.0.0.1:6379> lpush mylist Jacob4
(integer) 4
127.0.0.1:6379> lpush mylist Jacob5
(integer) 5
127.0.0.1:6379> lpush mylist2 Jacob6
(integer) 1
127.0.0.1:6379> lpush mylist2 Jacob7
(integer) 2
127.0.0.1:6379> lpush mylist2 Jacob8
(integer) 3
127.0.0.1:6379> rpoplpush mylist mylist2
"Jacob1"
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob5"
2) "Jacob4"
3) "Jacob3"
4) "Jacob2"
127.0.0.1:6379> lrange mylist2 0 -1
1) "Jacob1"
2) "Jacob8"
3) "Jacob7"
4) "Jacob6"

ps:lpush 是往头部添加。

lindex

返回名称为 key 的 list 中 index 位置的元素

127.0.0.1:6379> lindex mylist2 0
"Jacob1"
llen

返回 key 对应 list 的长度

127.0.0.1:6379> llen mylist
(integer) 4
127.0.0.1:6379> llen mylist2
(integer) 4