2.4 列表
列表(list)类型是用来存储多个有序的字符串,如下图所示,a、b、c、d、e五个元素从左到右组成了一个有序的列表,列表中的每个字符串称为元素(element),一个列表最多可以存储232-1个元素。在Redis中,可以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等。列表是一种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发上有很多应用场景。

列表类型有两个特点:第一、列表中的元素是有序的,这就意味着可以通过索引下标获取某个元素或者某个范围内的元素列表,例如要获取上图图的第5个元素,可以执行lindex user:1:message 4(索引从0算起)就可以得到元素e。第二、列表中的元素可以是重复。
这两个特点在后面介绍集合和有序集合后,会显得更加突出,因此在考虑是否使用该数据结构前,首先需要弄清楚列表数据结构的特点。
2.4.1 命令
下面按照增、查、删、改、阻塞的顺序来介绍列表的命令
- 添加操作
- 从右边插入元素
rpush key value [value ...]
- 从左边插入元素
lpush key value [value ...]
- 向某个元素前或者后插入元素
linsert key before|after pivot value
- 查找
- 获取指定范围内的元素列表
lrange key start end
lrange操作会获取列表指定索引范围所有的元素。索引下标有两个特点:第一,索引下标从左到右分别是0到N-1,但是从右到左分别是-1到-N。第二,lrange中的end选项包含了自身,这个和很多编程语言不包含end不太相同,例如想获取列表的第2到第4个元素,可以执行如下操作:
lrange listkey 1 3
- 获取列表指定索引下标的元素
lindex key index
- 获取列表长度
llen key
- 删除
- 从列表左侧弹出元素
lpop key
元素弹出之后就不在列表上了
- 从列表右侧弹出
rpop key
- 删除指定元素
lrem key count value
lrem命令会从列表中找到等于value的元素进行删除,根据count的不同
分为三种情况:
·count>0,从左到右,删除最多count个元素。
·count<0,从右到左,删除最多count绝对值个元素。
·count=0,删除所有。
- 按照索引范围修剪列表
ltrim key start end
- 修改
- 修改指定索引下标的元素
lset key index newValue
- 阻塞操作
- 阻塞式弹出如下:
blpop key [key ...] timeout
brpop key [key ...] timeout
blpop和brpop是lpop和rpop的阻塞版本,它们除了弹出方向不同,使用方法基本相同,所以下面以brpop命令进行说明,brpop命令包含两个参数:
·key[key...]:多个列表的键。
·timeout:阻塞时间(单位:秒)。
在列表为空的时候:如果timeout=3,那么客户端要等到3秒后返回,如果timeout=0,那么客户端一直阻塞等下去。这种情况是不是很容易想到消息队列呢?
2.4.2 内部编码
列表类型的内部编码有两种:ziplist(压缩列表)和linkedlist(链表)。
同哈希的内部编码,在元素个数较小的时候会使用ziplist编码,否则使用linkedlist。
2.4.3 使用场景
- 消息队列
如上面对阻塞操作的介绍,,Redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。 - 文章列表
每个用户有属于自己的文章列表,现需要分页展示文章列表。此时可以考虑使用列表,因为列表不但是有序的,同时支持按照索引范围获取元素。 - 实际上列表的使用场景很多,在选择时可以参考以下口诀:
·lpush+lpop=Stack(栈)
·lpush+rpop=Queue(队列)
·lpsh+ltrim=Capped Collection(有限集合)
·lpush+brpop=Message Queue(消息队列)
网友评论