Redis列表类型

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

img

下面咱们看一下Redis中列表类型的获取与删除操做:学习

img

下面咱们看一下Redis列表类型的特色:测试

  • 列表中全部的元素都是有序的。因此在Redis中列表类型是能够经过索引获取的,也就是上图中的
lindex命令

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

  • 列表中的元素是能够重复的。也就是说在Redis列表类型中,是能够保存重复的元素,也就是以下图所示:

img

下面咱们仍是和学习其它数据类型同样,咱们仍是先学习一下Redis列表类型的命令。编码

命令spa

1、添加操做3d

1.从右边插入元素code

rpush key value [value ...]

img

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

咱们也能够用下面的命令从左到右获取当前列表中的全部的元素,也就是如上图所示中那样。索引

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命令在执行成功后也是会有返回值的,返回的结果就是当前列表中元素的个数。


2、查找

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

lrange key start stop

img

lrange命令会获取列表中指定索引范围的全部元素。经过索引获取列表主要有两个特色:

  • 索引下标从左到右分别是0到N-1,从右到左是-1到-N。
  • lrange命令中的end参数在执行时会包括当前元素的。并非全部的语言都是这样的。如咱们要获取列表中前两个元素则能够以下图所示:

img

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

lindex key index

img


3.获取列表长度

llen key

img


3、删除

1.从列表左侧弹出元素

lpop key

img

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


2.从列表右侧弹出元素

rpop key

img

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


3.删除指定元素

lrem key count value

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

  • count > 0:表示从左到右,最多删除count个元素。也就是以下图所示:

img
咱们看上图中的命令中,虽然咱们将count参数指定的是5,将value参数指定的是2,但因为当前列表中只有一个2,因此,当前lrem命令最多只能删除1个元素,而且lrem命令也是有返回值的,也就是当前成功删除元素的个数。
img

  • count < 0:从右到左,最多删除count个元素。

img

  • count = 0:删除全部元素。

img


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

ltrim key start stop

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

img

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


4、修改

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

lset key index value

img


5、阻塞操做

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

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

  • key [key ...]:能够指定多个列表的键。
  • timeout:阻塞时间(单位:秒)

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

  1. 列表为空:若是timeout=3,则表示客户端等待3秒后才能返回结果,若是timeout=0,则表示客户端会一直等待,也就是会阻塞。

img
因为我期间向列表中插入了元素,不然上述命令将一直阻塞下去。
2.列表不为空:若是timeout=0,而且列表不为空时,则blpop和brpop命令会当即返回结果,不会阻塞。
img


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

  • 若是使用blpop和brpop命令指定多个键时,blpop和brpop命令会从左到右遍历键,而且一旦有一个键能返回元素,则客户端会当即返回。

img
当列表为空时,上述命令会阻塞,若是向上述中的任何一个键中插入元素,则上述命令会直接返回该键的元素。

  • 若是多个客户端都对同一个键执行blpop或者brpop命令,则最早执行该命令的客户端会获取到该键的元素。

img
我同时启动了3个客户端,由于当前列表为空,因此上述命令执行后会阻塞。若是此时我向该列表中插入元素,则只有第一个客户端会有返回结果,由于第一个客户端是第一个执行上述命令的。
img
img


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

操做类型 命令 时间复杂度
添加 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)

内部编码

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

  • ziplist(压缩列表):当列表中元素个数小于512(默认)个,而且列表中每一个元素的值都小于64(默认)个字节。Redis会选择用ziplist来做为列表的内部实现来减小内存的使用。固然上述默认值也能够经过相关参数修改:list-max-ziplist-entried(元素个数)、list-max-ziplist-value(元素值)。
  • linkedlist(链表):当列表类型没法知足ziplist条件时,Redis会选择用linkedlist做为列表的内部实现。

下面咱们经过相关命令来验证上述所说。

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列表类型的使用场景。

原文地址:http://jilinwula.com/article/...

相关文章
相关标签/搜索