Redis入门指南 第3章 Redis的5种主要数据类型及相应的命令(三) 列表类型
一、介绍
-
列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段
-
列表类型内部是使用双向链表实现的,所以向列表两端添加元素的时间复杂度为 ,要获取的元素越接近两端则速度越快。这意味着即使是一个长度上千万的列表,获取头部或者尾部的 10 条记录的速度是极快的(和从长度为 100 的列表中获取头部或者尾部 10 条记录的速度是一样的)
-
这种特性使列表类型能够非常快速地完成关系数据库难以应付的场景:如社交网站的新鲜事,我们关心的只是最新内容,使用列表类型存储,即使新鲜事的总数达到了几千万个,获取其中最新的 100 条数据也是极快的。同样,因为在链表两端插入记录的时间复杂度是 ,列表类型也适合用来记录日志,可以保证加入新日志的速度不会受到已有日志数量的影响
二、命令
-
1.向列表两端添加元素
-
LPUSH 命令用来向列表左边增加元素,返回值是增加元素后列表的长度,其用法如下:
redis> LPUSH numbers 1 (integer) 1
-
执行上述命令后,numbers 键中的数据为 “1”。LPUSH 命令还支持同时增加多个元素,用法如下:
redis> LPUSH numbers 2 3 (integer) 3
-
上述命令会先向列表的左边加入 “2”,然后再加入 “3”,执行后 numbers 键中的数据为 “3-2-1”
-
如果要向列表右边增加元素的话,则使用 RPUSH 命令,其用法和 LPUSH 命令一样:
redis> RPUSH numbers 0 1 (integer) 5
-
此时 numbers 键中的数据为 “3-2-1-0-1”
-
-
2.从列表两端弹出元素
-
有进相应的也要有出,LPOP 命令可以从列表左边弹出一个元素,它的执行有两个步骤:第一步是将列表左边的元素从列表中删除,第二步就返回被删除的元素值。例如,从 numbers 列表左边弹出一个元素:
redis> LPOP numbers "3"
-
同样,RPOP 命令可以从列表右边弹出一个元素:
redis> RPOP numbers "1"
-
结合上面提到的 4 个命令可以使用列表类型来模拟栈和队列的操作:如果想把列表当成栈,则搭配使用 LPUSH 和 LPOP 或者 RPUSH 和 RPOP;如果想把列表当成队列,则搭配使用 LPUSH 和 RPOP 或者 RPUSH 和 LPOP
-
-
3.获取列表中元素的个数
-
LLEN 命令获取一个列表中元素的个数,当键不存在的时候会返回 0,用法如下:
redis> LLEN numbers (integer) 3
-
-
4.获得列表片段
-
LRANGE 命令是列表类型最常使用的命令之一,它能够获得列表中的某一个片段。LRANGE 命令将返回索引从 start 到 stop 之间的所有元素(包含两端的元素)。其中,Redis 的列表起始索引为 0
redis> LRANGE numbers 0 2 1) "2" 2) "1" 3) "0"
-
LRANGE 命令在取得列表片段的同时不会像 LPOP 一样删除该片段。而且 LRANGE 命令还支持负索引(熟悉 python 的应该都懂),表示从右边开始计算序数,如 “-1” 表示右边第一个元素,“-1” 表示最右边第二个元素,以此类推:
redis> LRANGE numbers -2 -1 1) "1" 2) "0"
-
显然,LRANGE numbers 0 -1 可以获得列表中的所有元素。另外一些特殊情况如下:
-
1)如果 start 的索引位置比 stop 的索引位置靠后,则会返回空列表
-
2)如果 stop 大于实际的索引范围,则会返回列表最右边的元素
redis> LRANGE numbers 1 999 1) "1" 2) "0"
-
-
-
5.删除列表中指定的值
-
LREM 命令会删除列表中前 count 个值为 value 的元素,返回值是十几删除的元素个数。而且根据 count 值的不同,LREM 命令的执行方式会略有不同:
-
1)当 count > 0 时 LREM 命令会从列表左边开始删除前 count 个值为 value 的元素
-
2)当 count < 0 时 LREM 命令会从列表右边开始删除前 |count| 个值为 value 的元素
-
3)当 count = 0 时 LREM 命令会删除所有值为 value 的元素
redis> RPUSH numbers 2 (integer) 4 redis> LRANGE numbers 0 -1 1) "2" 2) "1" 3) "0" 4) "2" # 从右边开始删除第一个值为 “-2” 的元素 redis> LREM numbers -1 2 (integer) 1 redis> LRANGE numbers 0 -1 1) "2" 2) "1" 3) "0"
-
-
-
6.获得\设置指定索引的元素值
-
LINDEX 命令用来返回指定索引的元素,索引从 0 开始,其用法如下:
redis> LINDEX numbers 0 "2"
-
如果 index 是负数的话则从列表右边开始计算索引,最右边元素的索引是 -1。例如:
redis> LINDEX numbers -1 "0"
-
LSET 是另一个通过索引操作列表的命令,它会将索引为 index 的元素赋值为 value,用法如下:
redis> LSET numbers 1 7 OK redis> LINDEX numbers 1 "7"
-
-
7.只保留列表指定片段
-
LTRIM 命令可以删除指定索引范围之外的所有元素,其指定列表范围的方法和 LRANGE 命令相同,用法如下:
redis> LRANGE numbers 0 -1 1) "2" 2) "7" 3) "0" redis> LTRIM numbers 1 2 OK redis> LRANGE numbers 0 -1 1) "7" 2) "0"
-
LTRIM 命令常和 LPUSH 命令一起使用来限制列表中元素的数量。比如,记录日志文件时我们只想要保留最近的 100 条日志,则每次加入新的元素后调用一次 LTRIM 命令即可:
LPUSH logs $newLog LTRIM logs 0 99
-
-
8.向列表中插入元素
-
LINSERT 命令首先会在列表中从左往右查找值为 pivot 的元素,然后根据第二个参数是 BEFORE 还是 AFTER 来决定将 value 插入到该元素的前面还是后面。LINSRERT 命令的返回值是插入后列表的元素个数,例如:
redis> LRANGE numbers 0 -1 1) "2" 2) "7" 3) "0" redis> LINSERT numbers AFTER 7 3 (integer) 4 redis> LRANGE numbers 0 -1 1) "2" 2) "7" 3) "3" 4) "0" redis> LINSERT numbers BEFORE 2 1 (integer) 5 redis> LRANGE numbers 0 -1 1) "1" 2) "2" 3) "7" 4) "3" 5) "0"
-
-
9.将元素从一个列表转到另一个列表
-
RPOPLPUSH 是一个很有意思的命令,它先执行 RPOP 命令再执行 LPUSH 命令。RPOPLPUSH 命令会先从 source 列表的右边弹出一个元素,然后将其加入到 destination 列表的左边,并返回该元素的值。用法如下:
RPOPLPUSH source destination
-