在前几篇咱们介绍了Redis类型中的字符串类型和哈希类型,今天咱们了解一下Redis中的列表类型。在Redis中列表类型,能够简单的理解为存储多个有序字符串的一种新类型,这种类型除了字符串类型中已有的功能外,还提供了其它的功能。如能够对列表的两端插入和弹出元素(在列表中的字符串均可以称之为元素),除此以外还能够获取指定的元素列表,而且还能够经过索引下标获取指定元素等等。下面咱们经过下图来看一下Redis中列表类型的插入和弹出操做:redis
下面咱们看一下Redis中列表类型的获取与删除操做:学习
下面咱们看一下Redis列表类型的特色:测试
lindex命令
而且在Redis中列表类型的索引是从0开始的。ui
下面咱们仍是和学习其它数据类型同样,咱们仍是先学习一下Redis列表类型的命令。编码
命令spa
1、添加操做3d
1.从右边插入元素code
rpush key value [value ...]
咱们看rpush命令在插入时,是有返回值的,返回值的数量就是当前列表中全部元素的个数。blog
咱们也能够用下面的命令从左到右获取当前列表中的全部的元素,也就是如上图所示中那样。索引
lrange 0 -1
2.从左边插入元素
lpush key value [value ...]
lpush命令的返回值及用法和rpush命令同样,这里就不在介绍了,但经过上面的事例证实了咱们前面说的,由于当前key中已经有了3个元素了,因此咱们在执行插入命令时,返回的就是6而不是3,由于rpush命令和lpush命令的返回值并非当前插入元素的个数,而返回的是当前key中所有元素的个数。
3.向某个元素前或者后插入元素
linsert key BEFORE|AFTER pivot value
linsert命令在执行的时候首先会从当前列表中查找到pivot元素,其次在将这个新元素插入到pivot元素的前面或者后面。而且咱们经过上图所示知道linsert命令在执行成功后也是会有返回值的,返回的结果就是当前列表中元素的个数。
2、查找
1.获取指定范围内的元素列表
lrange key start stop
lrange命令会获取列表中指定索引范围的全部元素。经过索引获取列表主要有两个特色:
2.获取列表中指定索引下标的元素
lindex key index
3.获取列表长度
llen key
3、删除
1.从列表左侧弹出元素
lpop key
lpop命令执行成功后会返回当前被删除的元素名称。
2.从列表右侧弹出元素
rpop key
rpop命令和lpop命令的使用方式同样,这里不在作过多介绍了。
3.删除指定元素
lrem key count value
lrem命令会将列表中等于value的元素删除掉,而且会根据count参数,来决定删除value的元素个数。下面咱们看一下count参数的使用说明:
咱们看上图中的命令中,虽然咱们将count参数指定的是5,将value参数指定的是2,但因为当前列表中只有一个2,因此,当前lrem命令最多只能删除1个元素,而且lrem命令也是有返回值的,也就是当前成功删除元素的个数。
4.按照索引范围修剪列表
ltrim key start stop
ltrim命令会直接保留start索引到stop索引的之间的元素,并包括当前元素,而以外的元素则都会删除掉,因此该命令也叫修剪列表。
而且有一点要注意ltrim命令不会返回当前的列表中元素的个数,而是返回改命令是否成功的状态。
4、修改
1.修改指定索引下标的元素
lset key index value
5、阻塞操做
blpop key [key ...] timeout brpop key [key ...] timeout
blpop和brpop命令是lpop和rpop命令的阻塞版本,它们除了弹出方向不一样之外,使用方法基本相同。
下面咱们看一下该命令的详细使用。
因为我期间向列表中插入了元素,不然上述命令将一直阻塞下去。
2.列表不为空:若是timeout=0,而且列表不为空时,则blpop和brpop命令会当即返回结果,不会阻塞。
下面咱们看一下blpop和brpop命令的注意事项。
当列表为空时,上述命令会阻塞,若是向上述中的任何一个键中插入元素,则上述命令会直接返回该键的元素。
我同时启动了3个客户端,由于当前列表为空,因此上述命令执行后会阻塞。若是此时我向该列表中插入元素,则只有第一个客户端会有返回结果,由于第一个客户端是第一个执行上述命令的。
下面咱们看一下列表中命令的相关时间复杂度。
操做类型 | 命令 | 时间复杂度 |
---|---|---|
添加 | rpush key value [value ...] | O(k),k是元素的个数 |
添加 | lpush key value [value ...] | O(k),k是元素的个数 |
添加 | linsert key BEFORE/AFTER pivot value | O(n),n是pivot距离列表头或者尾的距离 |
添加 | lrange key start stop | O(s + n),s是start偏移量,n是start到stop的范围 |
添加 | lindex key index | O(n),n是索引的偏移量 |
添加 | llen key | O(1) |
添加 | lpop key | O(1) |
添加 | rpop key | O(1) |
添加 | lrem key count value | O(n),n是列表长度 |
添加 | ltrim key start stop | O(n),n是要裁剪的元素个数 |
添加 | lset key index value | O(n),n是索引的偏移量 |
添加 | blpop/brpop key [key ...] timeout | O(1) |
内部编码
列表中的内部编码有两种,它们分别是:
下面咱们经过相关命令来验证上述所说。
1.当元素个数较少而且没有大元素时,内部编码为ziplist。
咱们看当咱们在列表中插入少许元素,而且没有大元素时,返回的内部编码并非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列表类型的使用场景。