首页 > 数据库 >Redis:10---List对象

Redis:10---List对象

时间:2022-11-01 14:37:18浏览次数:42  
标签:10 source list 元素 Redis 列表 --- 命令 key


一、列表对象概述

      列表类型是用来存储多个有序的字符串,一个列表最多可以存储多个元素。列表是一种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发上有很多应用场景

  • 特点:
  • 一个列表可以存储多个字符串,相同元素可以重复出现
  • 列表中的元素是有序的,根据元素的插入、删除顺序对元素进行排序


  • 优点:可以包含多个字符串值,使得用户可以将数据集中在同一个地方。

二、命令

常用命令 

命令

用例和描述

RPUSH

RPUSH  key-namevaluelvalue...]-将一个或多个值推入列表的右端

LPUSH

LPUSH  key-nanevalue[value...]-将一个或多个值推入列衷的左蹦

RPOP

RPOP  key-name- 移除并返回刚农聂石瑞的元素

LPOP

LPOP   key-name- 移除并返回列农最左瑞印元素

LINDEX

LINDEX  key-nameoffset--返回列表中偏移量为offset的元素

LRANGE

LRANGE key-name start  end-返回列表从start偏移量到end偏移量范围内的所有元素.

其中偏移量为start和偏移量为end的元素也会包否在被返回的元素之内

LTRIM

LTRIM key-name start end-对列表进行修剪,只保留从start偏移量到end偏移量范围

内的元素,其中俯移量为start和偏移量为end的元景也会被床出


linsert

linsert命令会从列表中找到等于pivot的元素,在其前(before)或者后 (after)插入一个新的元素value

linsert key before|after pivot value
  • 例如下面操作会在列表的元素a前插入C++:


llen

  • 获取列表长度
llen key


  • lrem:删除指定元素。lrem命令会从列表中找到等于value的元素进行删除,根据count的不同分为三种情况:
  • count>0,从左到右,删除最多count个元素
  • count<0,从右到左,删除最多count绝对值个元素
  • count=0,删除所有
lrem key count value


  • lset:修改指定索引下标的元素
lset key index newValue


  • lrange注意事项:
  • 第一,索引下标从左到右分别是0到N-1,但是从右到左分别是-1到-N
  •  第二,lrange中的end选项包含了自身,这个和很多编程语言不包含end不太相同


  • 其他演示案例:


  • 接上


  • 接上


其他命令


命令

用例和描述

BLPOP

BLPOP key-name [key-name ...]timeout———从第一个非空列表中弹出位升最左端 1元素,
或者在timeout秒之内阻塞并等待 可弹出的元素出现

BRPOP

BRPOP key-name [key-name ...]timeout—从第一个非空列表中弹出位扌最右端的 元素,

或者在timeout秒之内阻塞并等待中弹出的元素出现

RPOPLPUSH

RPOPLPUSH source-key dest-key 从source-key列表中弹出位于最右端的元素,然后

将这个元素推入dest-key列表的最左端. 并向用户返回这个元素

BRPOPLPUSH

BRPOPLPUSH source-key dest-key timeout——从source-key列表中弹出位于最右端

元素,然后将这个元素推入dest-key列表的最左端,并向用户返回这个元素,如果source-key

为空,那么在timeout秒之内阻塞并等特可弹出的元素出现


  • 在Redis队列的场景下,这些命令会非常有用
  • 对于阻塞弹出命令和弹出并推入命令,最常用的就是消息传递和任务队列

BLPOP命令演示案例

  • 先用BLPOP命令阻塞等待new_list键中有值出现


  • 在右侧客户端中向new_list中压入一个元素,可以看到左侧返回


BRPOPLPUSH命令演示案例

  • 左侧等待source_list中有键值可以移动到dest_list中


  • 右侧向source_list压入值,左侧看到成功返回


  • 查看source_list中的值,可以看到没有了(已经移动到dest_list列表中了),右侧查看dest_list列表


  • 列表命令的复杂度:


三、内部编码

  • 列表类型的内部编码有两种:
  • ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置 (默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时 (默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使 用
  • linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用 linkedlist作为列表的内部实现。
  • Redis3.2版本提供了quicklist内部编码,简单地说它是以一个ziplist为节点的linkedlist,它结合了ziplist和linkedlist两者的优势,为列表类型提供了一 种更为优秀的内部编码实现.

四、使用场景

①消息队列

  • 如下图所示,Redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性


②文章列表

  • 每个用户有属于自己的文章列表,现需要分页展示文章列表。此时可以考虑使用列表,因为列表不但是有序的,同时支持按照索引范围获取元素
  • ①每篇文章使用哈希结构存储,例如每篇文章有3个属性title、 timestamp、content:
  1. hmset acticle:1 title xx timestamp 1476536196 content xxxx
  2. ...
  3. hmset acticle:k title yy timestamp 1476512536 content yyyy
  4. ...
  • ②向用户文章列表添加文章,user:{id}:articles作为用户文章列表的键:
  1. lpush user:1:acticles article:1 article3
  2. ...
  3. lpush user:k:acticles article:5
  4. ...
  • ③分页获取用户文章列表,例如下面伪代码获取用户id=1的前10篇文章:
  1. articles = lrange user:1:articles 0 9
  2. for article in {articles}
  3. hgetall {article}
  • 使用列表类型保存和获取文章列表会存在两个问题:
  • 第一,如果每次分 页获取的文章个数较多,需要执行多次hgetall操作,此时可以考虑使用Pipeline(后面文章有介绍)批量获取,或者考虑将文章数据序列化为字符串类 型,使用mget批量获取
  • 第二,分页获取文章列表时,lrange命令在列表两 端性能较好,但是如果列表较大,获取列表中间范围的元素性能会变差,此 时可以考虑将列表做二级拆分,或者使用Redis3.2的quicklist内部编码实现, 它结合ziplist和linkedlist的特点,获取列表中间范围的元素时也可以高效完成
  • 实际上列表的使用场景很多,在选择时可以参考以下口诀:
  • lpush+lpop=Stack(栈)

  • lpush+rpop=Queue(队列)

  • lpsh+ltrim=Capped Collection(有限集合)

  • lpush+brpop=Message Queue(消息队列)


标签:10,source,list,元素,Redis,列表,---,命令,key
From: https://blog.51cto.com/u_14934686/5813617

相关文章

  • C++:44---关键字virtual、override、final
    一、虚函数概念:在函数前面加virtual,就是虚函数虚函数的一些概念:只有成员函数才可定义为虚函数,友元/全局/static/构造函数都不可以虚函数需要在函数名前加上关键字virtual成......
  • C++:45---多态
    一、多态介绍面向对象的核心思想是多态性,其含义是“多种形式”概念:在子类覆盖了父类函数的情况下,用父类的指针(或引用)调用子类对象,或者通过父类指针调用覆盖函数的时候(动......
  • C++(STL):26 ---关联式容器set用法
    set容器都会自行根据键的大小对存储的键值对进行排序,只不过set容器中各键值对的键key和值value是相等的,根据key排序,也就等价为根据value排序。另外,使用set容器......
  • 怎么查小河流名称--河流数据库
    全国最大的河流名称数据库,没有你找不到的当一条河流自上而下不同河段有不同的名称时,一般以下游的河名作为整个河流的名称。当河流在地形图上没有标注名称时,可采用下列方法......
  • C++(STL):06---数值的极值(numeric_limits类)
    一、数值的极值概述数值类型有着与平台相依的极值C++标准规定了各种类型必须保证的最小精度。这些最小值如下图所示: 类型最小长度char1byte(8bits)shortint2bytesint2bytes......
  • C++:51---继承中的构造函数、析构函数、拷贝控制一系列规则
    一、继承中的构造函数根据构造函数的执行流程我们知道:派生类定义时,先执行基类的构造函数,再执行派生类的构造函数拷贝构造函数与上面是相同的原理二、继承中的析构函数根据析......
  • C++:46---绝不重新定义继承而来的non-virtual函数
    一、看一个隐藏non-virtual函数的例子假设classD以public的方式继承于classB,代码如下:classB{public:voidmf();};classD:publicB{};intmain(){Dx;B*pB=&x;pB->......
  • 动态规划-回文串
    回文串是从左到右和从右到左读起来一样的字符串,变种还有回文子序列,区别就是字符可以不连续。求回文串个数、最长回文串、最长回文序列也是典型的二维动态规划问题。我们......
  • C++(STL):05---智能指针之unique_ptr
    一、unique_ptr类头文件:#include<memory>智能指针,是一个模板。创建智能指针时,必须提供指针所指的类型与shared_ptr的不同之处:shared_ptr所指向的对象可以有多个其他shared_p......
  • C++:31---对象引用和赋值
    一、对象移动概述C++11标准引入了“对象移动”的概念对象移动的特性是:可以移动而非拷贝对象在C++旧标准中,没有直接的方法移动对象。因此会有很多不必要的资源拷贝标准库容器......