Redis列表类型

/ Redis / 没有评论 / 324浏览

在前几篇我们介绍了Redis类型中的字符串类型和哈希类型,今天我们了解一下Redis中的列表类型。在Redis中列表类型,可以简单的理解为存储多个有序字符串的一种新类型,这种类型除了字符串类型中已有的功能外,还提供了其它的功能。如可以对列表的两端插入和弹出元素(在列表中的字符串都可以称之为元素),除此之外还可以获取指定的元素列表,并且还可以通过索引下标获取指定元素等等。下面我们通过下图来看一下Redis中列表类型的插入和弹出操作:

img

下面我们看一下Redis中列表类型的获取与删除操作:

img

下面我们看一下Redis列表类型的特点:

lindex命令

并且在Redis中列表类型的索引是从0开始的。

img

下面我们还是和学习其它数据类型一样,我们还是先学习一下Redis列表类型的命令。

命令

一、添加操作

1.从右边插入元素

rpush key value [value ...]

img

我们看rpush命令在插入时,是有返回值的,返回值的数量就是当前列表中所有元素的个数。

我们也可以用下面的命令从左到右获取当前列表中的所有的元素,也就是如上图所示中那样。

lrange 0 -1 

2.从左边插入元素

lpush key value [value ...]

img

lpush命令的返回值及用法和rpush命令一样,这里就不在介绍了,但通过上面的事例证明了我们前面说的,因为当前key中已经有了3个元素了,所以我们在执行插入命令时,返回的就是6而不是3,因为rpush命令和lpush命令的返回值并不是当前插入元素的个数,而返回的是当前key中全部元素的个数。


3.向某个元素前或者后插入元素

linsert key BEFORE|AFTER pivot value

img

linsert命令在执行的时候首先会从当前列表中查找到pivot元素,其次在将这个新元素插入到pivot元素的前面或者后面。并且我们通过上图所示知道linsert命令在执行成功后也是会有返回值的,返回的结果就是当前列表中元素的个数。


二、查找

1.获取指定范围内的元素列表

lrange key start stop

img

lrange命令会获取列表中指定索引范围的所有元素。通过索引获取列表主要有两个特点:


2.获取列表中指定索引下标的元素

lindex key index

img


3.获取列表长度

llen key

img


三、删除

1.从列表左侧弹出元素

lpop key

img

lpop命令执行成功后会返回当前被删除的元素名称。


2.从列表右侧弹出元素

rpop key

img

rpop命令和lpop命令的使用方式一样,这里不在做过多介绍了。


3.删除指定元素

lrem key count value

lrem命令会将列表中等于value的元素删除掉,并且会根据count参数,来决定删除value的元素个数。下面我们看一下count参数的使用说明:


4.按照索引范围修剪列表

ltrim key start stop

ltrim命令会直接保留start索引到stop索引的之间的元素,并包括当前元素,而之外的元素则都会删除掉,所以该命令也叫修剪列表。

img

并且有一点要注意ltrim命令不会返回当前的列表中元素的个数,而是返回改命令是否成功的状态。


四、修改

1.修改指定索引下标的元素

lset key index value

img


五、阻塞操作

blpop key [key ...] timeout
brpop key [key ...] timeout

blpop和brpop命令是lpop和rpop命令的阻塞版本,它们除了弹出方向不同以外,使用方法基本相同。

下面我们看一下该命令的详细使用。

  1. 列表为空:如果timeout=3,则表示客户端等待3秒后才能返回结果,如果timeout=0,则表示客户端会一直等待,也就是会阻塞。 img 由于我期间向列表中插入了元素,否则上述命令将一直阻塞下去。 2.列表不为空:如果timeout=0,并且列表不为空时,则blpop和brpop命令会立即返回结果,不会阻塞。 img

下面我们看一下blpop和brpop命令的注意事项。


下面我们看一下列表中命令的相关时间复杂度。

操作类型命令时间复杂度
添加rpush key value [value ...]O(k),k是元素的个数
添加lpush key value [value ...]O(k),k是元素的个数
添加linsert key BEFORE/AFTER pivot valueO(n),n是pivot距离列表头或者尾的距离
添加lrange key start stopO(s + n),s是start偏移量,n是start到stop的范围
添加lindex key indexO(n),n是索引的偏移量
添加llen keyO(1)
添加lpop keyO(1)
添加rpop keyO(1)
添加lrem key count valueO(n),n是列表长度
添加ltrim key start stopO(n),n是要裁剪的元素个数
添加lset key index valueO(n),n是索引的偏移量
添加blpop/brpop key [key ...] timeoutO(1)

内部编码

列表中的内部编码有两种,它们分别是:

1.当元素个数较少并且没有大元素时,内部编码为ziplist。 img 我们看当我们在列表中插入少量元素,并且没有大元素时,返回的内部编码并不是ziplist而是quicklist。这又是什么编码呢。简单来说,quicklist编码是Redis3.2版本之后(包括当前版本)提供了一种新的内部编码。它和ziplist和linkedlist编码相比它结合了这两种编码的优势,具体的区别以后的文章中在做详细介绍。由于我电脑安装的Redis的版本是4.0.9,在3.2版本之后所以,上述代码执行后的内部编码为quicklist。


2.当元素个数超过512个元素时,内部编码将变为linkedlist。以下代码都是本人在Redis4.0.9中的测试,所以上述的验证本人没有验证成功。

import redis

r = redis.Redis(host='127.0.0.1', port=6379)

print('Key为【listkey】的字节编码为【%s】' % r.object('encoding', 'listkey').decode('utf-8'))

for i in range(1,512):
    r.rpush('listkey', i)

print('Key为【listkey的字节编码为【%s】' % r.object('encoding', 'listkey').decode('utf-8'))
Key为【listkey】的字节编码为【quicklist】
Key为【listkey的字节编码为【quicklist】

3.当列表中某个元素超过64个字节时,内部编码也会变成linkedlist。以下代码也是本人在Redis4.0.9中的测试,所以上述的验证本人也没有验证成功。

import redis

r = redis.Redis(host='127.0.0.1', port=6379)

print('Key为【listkey】的字节编码为【%s】' % r.object('encoding', 'listkey').decode('utf-8'))

value = ''

for i in range(1,512):
    value += str(i)

r.rpush('listkey', i)

print('Key为【listkey的字节编码为【%s】' % r.object('encoding', 'listkey').decode('utf-8'))
Key为【listkey】的字节编码为【quicklist】
Key为【listkey的字节编码为【quicklist】

上述内容就是Redis列表类型的相关知识,如有不正确的地方,欢迎指出,在下一篇中,我将分享Redis列表类型的使用场景。