redis常用数据类型之列表List

209 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

本文讲解下redis五大常用数据类型当中的列表List,主要从其数据结构,以及常用的方法进行讲解。

数据结构

其数据存储的特点是:单键多值

redis的列表,其实就是字符串的列表。具有顺序,按照数据插入的顺序排序。

数据可以从列表的头部插入,也可以从尾部插入。

它的底层是个双向链表

image.png

同时,它的底层也叫做快速链表quickList

redis使用双向链表压缩表zipList组成了快速链表。

当元素量较少的时候,redis会使用一块连续的内存去存储数据这个结构就是zipList,即压缩列表

当元素量大的时候,redis使用双向指针将多个zipList串联起来,形成一个双向的链表,即quickList。如下所示:

未命名文件 (20).png

这样做的好处有两点:

  • 满足快速插入、删除的特性
  • 减少因为冗余指针next、prev造成的空间浪费。

通常具有以下的使用场景:

  • 同向:lpush lpop(rpush rpop) 栈的特性,先进后出
  • 异向:lpush rpop(rpush lpop) 队列,先进先出
  • lindex():数组,根据下标获取list元素

常用命令

pop和push

  • pop是取出元素
  • push是放入元素

前面已经提到,列表的数据结构是一个双向链表,所以它的放入和取出元素分别有下面常用四种:

  • lpush:从左边放入一个元素
  • rpush:从右边放入一个元素
  • lpop:从左边取出一个元素
  • rpop:从右边取出一个元素

push使用示例如下,格式lpush key element [element ...]

127.0.0.1:6379> lpush students tom jerry xiaoming xiaohuang
(integer) 4
127.0.0.1:6379> rpush students datou
(integer) 5

从客户端工具看看结果:

image.png

我们看看上面的结果是不是按照我们前面描述的顺序。

popo使用示例,格式lpop key [count]

127.0.0.1:6379> lpop students 1
1) "xiaohuang"
127.0.0.1:6379> rpop students 2
1) "datou"
2) "tom"

如上所示,从左侧取出一个,右侧取出两个,剩余如下:

image.png

rpoplpush

这是一个特殊的命令,从一个列表的右侧输出一个元素,放入到下一个列表的左侧。

格式rpoplpush source destination

使用示例如下:

127.0.0.1:6379> rpoplpush students people
"jerry"

客户端看结果:

image.png

 

根据下标获得元素

首先我们创建一个列表如下:

127.0.0.1:6379> lpush number 1 2 3 4 5 6 7 8 9 
(integer) 9
  • lrange 获取范围下标内的元素,从左至右,格式lrange key start stop

    使用示例如下:

    127.0.0.1:6379> lrange number 2 5
    1) "7"
    2) "6"
    3) "5"
    4) "4"
    
  • lindex 按照下标获得元素,格式lindex key index

    使用示例如下:

    127.0.0.1:6379> lindex number 5
    "4"
    
  • llen 获取列表长度,格式llen key

    使用示例如下:

    127.0.0.1:6379> llen number
    (integer) 9
    

列表操作

  • linsert 在列表的某个位置查询值,格式linsert key BEFORE|AFTER pivot element

    使用示例如下所示:

    127.0.0.1:6379> linsert number before 5 0
    (integer) 10
    127.0.0.1:6379> lrange number 0 10
     1) "9"
     2) "8"
     3) "7"
     4) "6"
     5) "0"
     6) "5"
     7) "4"
     8) "3"
     9) "2"
    10) "1"
    

    如上所示,在列表number当中的元素5前面插入一个0。

  • lrem 从左侧开始,删除指定个数的某个值,格式lrem key count element

    使用示例如下:

    127.0.0.1:6379> lrem number 1 0
    (integer) 1
    127.0.0.1:6379> lrange number 0 10
    1) "9"
    2) "8"
    3) "7"
    4) "6"
    5) "5"
    6) "4"
    7) "3"
    8) "2"
    9) "1"
    

    如上所示,删除一个0。

  • lset 将指定下标的元素替换成给定值,格式lset key index element

    使用示例如下:

    127.0.0.1:6379> lset number 2 0
    OK
    127.0.0.1:6379> lrange number 0 10
    1) "9"
    2) "8"
    3) "0"
    4) "6"
    5) "5"
    6) "4"
    7) "3"
    8) "2"
    9) "1"
    

    如上所示,将下标为2的第三个元素替换成了0。


到此为止,关于redis列表的简单介绍就完了。