列表类型(List)
双向链表(double linked list)。这意味着即使在一个list中有数百万个元素,在头部或尾部添加一个元素的操作,其时间复杂度也是常数级别的。用LPUSH 命令在十个元素的list头部添加新元素,和在千万元素list头部添加新元素的速度相同。
那么,坏消息是什么?在数组实现的list中利用索引访问元素的速度极快,而同样的操作在linked list实现的list上没有那么快。
Redis Lists用linked list实现的原因是:对于数据库系统来说,至关重要的特性是:能非常快的在很大的列表上添加元素。另一个重要因素是,正如你将要看到的:Redis lists能在常数时间取得常数长度。
一个列表类型键最多能容纳 2³² - 1
命令
1、向列表两端添加数据
LPUSH key value [value ...]
RPUSH key value [value ...]
LPUSH 命令用来向列表左边那增加元素,返回值表示增加元素后列表的长度。RPUSH命令向列表右边添加元素。
可以使用一个命令把多个元素 push 进入列表,只需在命令末尾加上多个指定的参数。元素是从最左端的到最右端的、一个接一个被插入到 list 的头部。 所以对于这个命令例子 LPUSH mylist a b c,返回的列表是 c 为第一个元素, b 为第二个元素, a 为第三个元素。
127.0.0.1:6379> lpush mylist a b c
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> rpush mylist wo
(integer) 4
2、从列表两端弹出元素
LPOP key
RPOP key
LPOP命令可以从列表左边弹出一个元素。LPOP命令执行两步操作:第一步是将列表左边的元素从列表中移除,第二部是返回被移除的元素值。RPOP命令从列表右边弹出一个元素。如:
127.0.0.1:6379> lpop mylist
"c"
127.0.0.1:6379> rpop mylist
"wo"
结合上面的4个命令,可以使用列表类型来模拟栈和队列的操作:如果想把列表当做栈,则搭配使用LPUSH和LPOP或RPUSH和RPOP;如果想当成队列,则搭配使用LPUSH和RPOP或RPUSH和LPOP。
3、获取列表中元素的个数
LLEN key
LLEN会返回0:
127.0.0.1:6379> LLEN mylist
(integer) 2
4、获取列表片段
LRANGE key start stop
LRANGE命令是列表类型最常用的命令之一,它能够获得列表中的某一片段。LRANGE命令将返回索引从start到stop之间的所有元素(包含两端的元素)。索引从0开始,如:
127.0.0.1:6379> lrange mylist 0 1
1) "b"
2) "a"
LRANGE命令也支持负索引,表示从右边开始计算序号,-1表示最右边第一个元素,-2表示最右边第二个元素,以此类推。如:
127.0.0.1:6379> lrange mylist -2 -1
1) "b"
2) "a"
LRANGE mylist 0 -1
可以获取列表中的所有元素。另外一些特殊情况如下:
- 如果start的索引位置比stop的索引位置靠后,则会返回空列表;
- 如果stop大于实际的索引范围,则会返回到列表最右边的元素。
127.0.0.1:6379> lrange mylist 0 999
1) "b"
2) "a"
5、删除列表中指定的值
LLREM key count value
LREM命令会删除列表中前count个值为value的元素,返回值是实际删除的元素个数。根据count值得不同,LREM命令的执行方式会略有差异。
(1)当 count > 0 时,LREM命令会从列表左边开始删除前 count 个值为value的元素。
(2)当 count < 0 时,LREM命令会从列表右边开始删除前 |count| 个值为value的元素。
(3)当 count = 0 时,LREM命令会删除所有值为value的元素。
如:
127.0.0.1:6379> rpush mylist b c a
(integer) 5
127.0.0.1:6379> lrange mylist 0 -1
1) "b"
2) "a"
3) "b"
4) "c"
5) "a"
127.0.0.1:6379> lrem mylist -1 b
(integer) 1
127.0.0.1:6379> lrange mylist 0 -1
1) "b"
2) "a"
3) "c"
4) "a"
127.0.0.1:6379> lrem mylist 1 a
(integer) 1
127.0.0.1:6379> lrange mylist 0 -1
1) "b"
2) "c"
3) "a"
6、获得/设置指定索引的元素值
LINDEX key index
LSET key index value
LINDEX命令是必不可少的。LINDEX命令用来返回指定索引的元素,索引从0开始。如:
127.0.0.1:6379> lindex mylist 2
"a"
如果index是负数表示从右边开始,最右边元素的索引是-1,如:
127.0.0.1:6379> lindex mylist -2
"c"
LSET是另一个通过索引操作列表的命令,他会将索引为index的元素赋值为value,如:
127.0.0.1:6379> lset mylist 2 xxx
OK
127.0.0.1:6379> lindex mylist 2
"xxx"
7、只保留列表指定片段
LTRIM key start end
LTRIM命令可以删除指定索引范围之外的所有元素,其指定列表范围的方法和LRANGE命令相同,如:
127.0.0.1:6379> lrange mylist 0 -1
1) "b"
2) "c"
3) "xxx"
127.0.0.1:6379> ltrim mylist 0 1
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "b"
LTRIM命令常和LPUSH命令一起使用来限制列表中元素的数量,比如记录日志时,我们希望只保留最近的100条日志,则每次加入新元素时调用一次LTRIM命令即可:
LPUSH logs $newlog
LTRIM logs 0 99
8、向列表中插入元素
LINSERT key BEFORE|AFTER pivot value
LINSERT命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。返回值是插入后列表的元素个数。如:
127.0.0.1:6379> lrange mylist 0 -1
1) "b"
2) "c"
127.0.0.1:6379> linsert mylist before c t
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "b"
2) "t"
3) "c"
127.0.0.1:6379> linsert mylist after c s
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "b"
2) "t"
3) "c"
4) "s"
9、将元素从一个列表转到另一个列表
RPOPLPUSH source destination
RPOPLPUSH
127.0.0.1:6379> lrange mylist 0 -1
1) "b"
2) "t"
3) "c"
4) "s"
127.0.0.1:6379> RPOPLPUSH mylist yourlist
"s"
127.0.0.1:6379> RPOPLPUSH mylist yourlist
"c"
127.0.0.1:6379> RPOPLPUSH mylist yourlist
"t"
127.0.0.1:6379> RPOPLPUSH mylist yourlist
"b"
127.0.0.1:6379> RPOPLPUSH mylist yourlist
(nil)
127.0.0.1:6379> lrange yourlist 0 -1
1) "b"
2) "t"
3) "c"
4) "s"
当把列表类型作为队列使用时,RPOPLPUSH命令可以很直观地在多个队列中传递数据。当source和destination相同时,RPOPLPUSH命令会不断地将队尾的元素移到队首,借助这个特性我们可以实现一个网站监控系统:使用一个队列存储需要监控的网址,然后监控程序不断使用RPOPLPUSH命令循环取出一个网址来测试可用性。这里使用RPOPLPUSH命令的好处在于在程序执行过程中仍然可以不断地想网址列表中加入新网址,而且整个系统容易扩展,允许多个客户端同时处理队列。
官方提供
127.0.0.1:6379> help @list
BLMOVE source destination LEFT|RIGHT LEFT|RIGHT timeout
summary: Pop an element from a list, push it to another list and return it; or block until one is available
since: 6.2.0
BLPOP key [key ...] timeout
summary: Remove and get the first element in a list, or block until one is available
since: 2.0.0
BRPOP key [key ...] timeout
summary: Remove and get the last element in a list, or block until one is available
since: 2.0.0
BRPOPLPUSH source destination timeout
summary: Pop an element from a list, push it to another list and return it; or block until one is available
since: 2.2.0
LINDEX key index
summary: Get an element from a list by its index
since: 1.0.0
LINSERT key BEFORE|AFTER pivot element
summary: Insert an element before or after another element in a list
since: 2.2.0
LLEN key
summary: Get the length of a list
since: 1.0.0
LMOVE source destination LEFT|RIGHT LEFT|RIGHT
summary: Pop an element from a list, push it to another list and return it
since: 6.2.0
LPOP key [count]
summary: Remove and get the first elements in a list
since: 1.0.0
LPOS key element [RANK rank] [COUNT num-matches] [MAXLEN len]
summary: Return the index of matching elements on a list
since: 6.0.6
LPUSH key element [element ...]
summary: Prepend one or multiple elements to a list
since: 1.0.0
LPUSHX key element [element ...]
summary: Prepend an element to a list, only if the list exists
since: 2.2.0
LRANGE key start stop
summary: Get a range of elements from a list
since: 1.0.0
LREM key count element
summary: Remove elements from a list
since: 1.0.0
LSET key index element
summary: Set the value of an element in a list by its index
since: 1.0.0
LTRIM key start stop
summary: Trim a list to the specified range
since: 1.0.0
RPOP key [count]
summary: Remove and get the last elements in a list
since: 1.0.0
RPOPLPUSH source destination
summary: Remove the last element in a list, prepend it to another list and return it
since: 1.2.0
RPUSH key element [element ...]
summary: Append one or multiple elements to a list
since: 1.0.0
RPUSHX key element [element ...]
summary: Append an element to a list, only if the list exists
since: 2.2.0