Redis中的List类型

目录

List类型的命令

lpush

lpushx

rpush

lrange

lpop

rpop

lindex

linsert

llen

lrem

ltrim

lset

阻塞命令

阻塞命令的使用场景

1.针对一个非空的列表进行操作

2.针对一个空的列表进行操作

3.针对多个key进行操作.

内部编码

lisi类型的应用场景

存储(班级)信息

消息队列

分频道的消息队列

微博Timeline


列表(List)相当于是数组或者是顺序表.

结构示意图

Redis中的List类型_第1张图片

约定最左侧的元素下标是0,redis的下标支持负数下标.

注意list内部的编码方式并非是一个简单的数组,而是更接近于双端队列.

列表中的元素是有序的,指的并不是其按照元素的数据大小进行排列,而是意味着当你向列表中插入元素时,它们会按照插入的顺序进行排序(比如尾插abc,得到的列表也是abc),并且每个元素都有一个关联的索引值来表示其位置。

列表中的元素是允许重复的.

List类型的命令

lpush

将一个或者多个元素从左侧放入到list中.(头插)

LPUSH key element [element ...]
返回的是插入后list的长度.

时间复杂度是O(N),N代表插入元素的个数.

lpushx

当key存在时,将一个或者多个元素从左侧放入到list中,不存在则直接返回.

x->exists.

LPUSHX key element [element ...]
返回的是插入后list的长度.
时间复杂度是O(N),N代表插入元素的个数.
Redis中的List类型_第2张图片

rpush

将一个或者多个元素从右侧放入到list中,尾插.

RPUSH key element [element...........]
返回的是插入后list的长度.

时间复杂度是O(N),N代表插入元素的个数.

rpushx,类似与lpushx,尾插,不存在直接返回.

Redis中的List类型_第3张图片

lrange

LRANGE key start stop
获取从start到end区间的所有元素,闭区间.下标是支持负数的.
返回的是指定区间的元素.

对于超出下标的情况,redis会尽可能的获取对应的内容.

Redis中的List类型_第4张图片

lpop

LPOP key

从list左侧取出元素,即头删.

返回的是取出的元素或者nil.

Redis中的List类型_第5张图片

rpop

从list右侧取出元素,尾删.

RPOP key
返回的是取出的元素或者nil.
Redis中的List类型_第6张图片

lindex

LINDEX key index

获取从左数第index位置的元素.

Redis中的List类型_第7张图片

时间复杂度是O(N),N指的是list中元素的个数.

返回的是取出的元素或者是nil.

linsert

LINSERT key pivot element

返回的是插入后list的长度.

时间复杂度是O(N).N代表列表的长度.

如果进行插入的时候,基准值有多个,redis是从左往右找,找到第一个符合基准值的位置.

Redis中的List类型_第8张图片

llen

获取list的长度.

LLEN key

时间复杂度是O(1).

时间复杂度为什么是O(1):这是因为Redis将列表的长度存储在列表对象的内部数据结构中,并且在每次插入或删除元素时都会更新该长度。因此,当执行LLEN命令时,Redis可以直接返回列表的长度,无需遍历整个列表,所以时间复杂度是固定的,与列表的长度无关。

lrem

lrem key count element

count表示要删除的个数,element表示要删除的值.

 当count>0时表示从左向右删除元素.

当count<0时表示从右向左删除元素.

当count=0时表示删除全部指定元素.

Redis中的List类型_第9张图片

Redis中的List类型_第10张图片

Redis中的List类型_第11张图片


ltrim

LTRIM key start stop

保留start和stop之间区间内的元素,区间外面的元素就直接被删除了.

Redis中的List类型_第12张图片

lset

LSET  key index element

根据下标修改元素.

时间复杂度:O(N).

如果下标越界会直接报错.

Redis中的List类型_第13张图片


阻塞命令

blpop key [key.....] timeout

brpop key [key.....] timeout

blpop和brpop是lpop和rpop的阻塞版本.

相当于我们之前学习的阻塞队列一样.

当队列元素为满的时候,在往里插入元素会阻塞;当队列元素为空的时候,往外取元素也会阻塞.

redis只针对队列为空往外取的时候做了阻塞.因为redis中对于list什么时候为满没有明确的要求.

所以blpop和brpop.

blpop和brpop是lpop和rpop的阻塞版本,和对应的非阻塞版本的作用基本一致,除了:

1.在列表有元素的情况下,阻塞和非阻塞版本表现一致.但是如果列表为空,非阻塞版本会立即执行并返回nil,但阻塞版本会根据timeout阻塞一段时间,期间redis可以执行其他命令,但执行阻塞命令的客户端会表现为阻塞状态.

2.命令中如果设置了多个键,那么会从左向右进行遍历键,一旦有一个键对应的列表可以弹出元素,命令立即返回.

3.如果多个客户端对一个键执行brpop或blpop,最先执行命令的客户端会得到弹出的元素.


阻塞命令的使用场景

1.针对一个非空的列表进行操作

Redis中的List类型_第14张图片

返回的结果是一个二元组,一方面告诉我们当前的数据来自哪个key,一方面告诉我们取到的数据是什么.

2.针对一个空的列表进行操作

Redis中的List类型_第15张图片

返回二元组并且显示阻塞时间.

3.针对多个key进行操作.

Redis中的List类型_第16张图片


内部编码

之前的版本list的内部编码是ziplist(压缩列表)和linkedlist(链表).

和hash类型的类似,当元素个数过多的时候,ziplist会转换为linkedlist;当某个value过长的时候,ziplist也会转换为linkedList.

同样也存在两个配置项:list-max-ziplist-entries和list-max-ziplist-value.

而现在的版本list的内部编码只有一个quicklist.

quicklist相当于是结合了链表和压缩列表.

整体还是一个链表,但是链表的每一个节点是一个压缩列表.

每个压缩列表都不要太大,同时再把多个压缩列表通过链式结构的方式连接起来.


lisi类型的应用场景

存储(班级)信息

用list作为像数组这样的结构,来存储多个元素.

用mysql表示两个表,一个学生表一个班级表.

Redis中的List类型_第17张图片

通过这样的表结构,可以很方便的实现查询指定班级中有哪些同学.

而redis中没有这么强调的查询功能,我们只能设置合适的键值对来实现对应的效果.

Redis中的List类型_第18张图片

学生的个人信息用hash表示,而班级信息我们就可以使用list类型来表示.

通过classStudent:1来获取对应的学生id.


消息队列

redis阻塞消息的队列模型

Redis中的List类型_第19张图片

在当前的场景下,如果列表为空,消费者就会阻塞等待,直到有了数据或者到了timeout时间.

谁先执行brpop命令,谁就可以先拿到新来的数据.

如果消费者不停的brpop,这样的设定就能构成一个轮询的效果.

分频道的消息队列

Redis中的List类型_第20张图片

多个频道的场景非常常见,比如一个短视频,可以有一个频道来传输短视频数据,还可以有一个频道来传输弹幕数据,还可以有一个频道来传输点赞,转发和收藏的数据,可以有一个频道来传输评论数据.

设置成多个频道,就可以在某种数据发生问题的时候,不会对其他数据造成影响.


微博Timeline

1.每篇微博使用hash结构存储.

Redis中的List类型_第21张图片

2.向用户的timeline添加微博.user::myblogs作为键.

Redis中的List类型_第22张图片

3.分页获取用户的timeline,例如获取用户1的10篇微博.

Redis中的List类型_第23张图片

你可能感兴趣的:(redis,redis,数据库,缓存)