c++获取内存条类型_Redis值类型之list

介绍

列表类型可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。列表类型内部是使用双向链表实现的,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。不过通过索引访问元素就比较慢了。

0081351b0389e0e2cb787665f885b672.png

列表类型能非常快速地完成关系数据库难以应付的场景:如社交网站的新鲜事,我们关心的只是最新的内容,使用列表类型存储,即使新鲜事的总数达到几千万个,获取其中最新的100条数据也是极快的。同样因为在两端插入记录的时间复杂度是0(1),列表类型也适合用来记录日志,可以保证加入新日志的速度不会受到已有日志数量的影响。一个列表类型键最多能容纳2^32-1个元素。


一、列表类型特点

b753088fef39761d5b922fe61dbaf887.png

特点:

  • 有序的(插入顺序)

  • 可以重复的

  • 左右两边插入弹出

二、应用场景

场景一:微博的时间轴功能TimeLine,取数据做分页

  • 微博按照发表时间倒序排列

  • 按照一定范围(每10条数据)做分页

6af94b5d6bbcb3993a54260cab9e3c94.png

场景二:抢红包

127.0.0.1:6379> FLUSHALLOK127.0.0.1:6379> LPUSH k1 2 4 1 3(integer) 4127.0.0.1:6379> RPOP k1"2"127.0.0.1:6379> RPOP k1"4"127.0.0.1:6379> RPOP k1"1"127.0.0.1:6379> RPOP k1"3"

三、命令拾遗

127.0.0.1:6379> help @list  BLPOP key [key ...] timeout  summary: Remove and get the first element in a list, or block until one is available  since: 2.0.0  BRPOP key [key ...] timeout  summary: Remove and get the last element in a list, or block until one is available  since: 2.0.0  BRPOPLPUSH source destination timeout  summary: Pop a value from a list, push it to another list and return it; or block until one is available  since: 2.2.0  LINDEX key index  summary: Get an element from a list by its index  since: 1.0.0  LINSERT key BEFORE|AFTER pivot value  summary: Insert an element before or after another element in a list  since: 2.2.0  LLEN key  summary: Get the length of a list  since: 1.0.0  LPOP key  summary: Remove and get the first element in a list  since: 1.0.0  LPUSH key value [value ...]  summary: Prepend one or multiple values to a list  since: 1.0.0  LPUSHX key value  summary: Prepend a value to a list, only if the list exists  since: 2.2.0  LRANGE key start stop  summary: Get a range of elements from a list  since: 1.0.0  LREM key count value  summary: Remove elements from a list  since: 1.0.0  LSET key index value  summary: Set the value of an element in a list by its index  since: 1.0.0  LTRIM key start stop  summary: Trim a list to the specified range  since: 1.0.0  RPOP key  summary: Remove and get the last element in a list  since: 1.0.0  RPOPLPUSH source destination  summary: Remove the last element in a list, prepend it to another list and return it  since: 1.2.0  RPUSH key value [value ...]  summary: Append one or multiple values to a list  since: 1.0.0  RPUSHX key value  summary: Append a value to a list, only if the list exists  since: 2.2.0127.0.0.1:6379>

命令演示

1. LPUSH(左边添加)和RPUSH(右边添加)

list是有序的,数据的放入顺序,返回值表示增加元素后列表的长度:

127.0.0.1:6379> lpush k1 a b c d e(integer) 5127.0.0.1:6379> LRANGE k1 0 -11) "e"2) "d"3) "c"4) "b"5) "a"127.0.0.1:6379> rpush k1 x y z(integer) 8127.0.0.1:6379> LRANGE k1 0 -11) "e"2) "d"3) "c"4) "b"5) "a"6) "x"7) "y"8) "z"127.0.0.1:6379> 

2. LPOP(左边弹出)和RPOP(右边弹出)

LPOP命令执行两步操作:第一步是 将列表左边的元素从列表中移除,第二步是返回被移除的元素值。例如:

127.0.0.1:6379> LPOP k1"e"127.0.0.1:6379> RPOP k1"z"127.0.0.1:6379>

可以使用列表模拟栈和队列操作:

  • 同向(左压左出或右压右出):栈

  • 异向(左压右出或右压左出):队列

3. LINDEX(根据下标获取元素值)和LSET(通过索引赋值)

127.0.0.1:6379> LINDEX k1 3"a"127.0.0.1:6379> LINDEX k1 5"y"127.0.0.1:6379>lset k1 5 "yy"OK127.0.0.1:6379> LINDEX k1 5"yy"
  • 可以用来模拟数组

  • 如果index是负数则表示从右边开始计算的索引,最右边元素的索引是-1

4. LLEN(获取列表中元素个数)

当键不存在时返回0:

127.0.0.1:6379> llen num(integer) 0127.0.0.1:6379> llen k1(integer) 6

LLEN命令的功能类似SQL语句SELECT COUNT(*) FROM TABLE_NAME,但是LLEN的时间复杂度是O(1),使用时Redis会直接读取现成的值,而不需要像InnoDB那样需要遍历一遍数据表来统计数量。

5. LRANGE(获取列表片段)

Redis的列表起始索引是0:

127.0.0.1:6379> LRANGE k1 0 -11) "e"2) "d"3) "c"4) "b"5) "a"6) "x"7) "y"8) "z"

LRANGE命令也支持负索引,表示从右边开始计算序数,如"-1"表示最右边第一个元 素,"-2"表示最右边第二个元素,依次类推。特殊情况:

  • 如果start的索引位置比stop的索引位置靠后,则会返回空列表

  • 如果stop大于实际的索引范围,则会返回到列表最右边的元素

6. LREM(删除列表中指定的值)

LREM命令会删除列表中前count个值为value的元素,返回值是实际删除的元素个数。根据count值的不同,LREM命令的执行方式会略有差异:

  • 当count>0时LREM命令会从列表左边开始删除前count个值为value的元素

  • 当count<0时LREM 命令会从列表右边开始删除前|count|个值为value的元素

  • 当count=0时LREM命令会删除所有值为value的元素

// 从右边开始删除第一个值为"y"的元素127.0.0.1:6379> lrem k1 -1 "y"(integer) 1127.0.0.1:6379> LRANGE k1 0 -11) "e"2) "d"3) "c"4) "b"5) "a"6) "x"7) "z"

7. LTRIM(删除区间之外的数据)

127.0.0.1:6379> LRANGE  k1 0 -11) "d"2) "c"3) "b"4) "a"5) "x"6) "y"127.0.0.1:6379> LTRIM k1 0 -1OK127.0.0.1:6379> LRANGE  k1 0 -11) "d"2) "c"3) "b"4) "a"5) "x"6) "y"127.0.0.1:6379> LTRIM k1 0 4OK127.0.0.1:6379> LRANGE  k1 0 -11) "d"2) "c"3) "b"4) "a"5) "x"127.0.0.1:6379> 
  • 可以用来保留热数据

  • 删除中间的没有办法(可以分多次删两边的)

8. LINSERT(向列表中插入元素)

LINSERT key BEFORE|AFTER pivot value。LINSERT命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是 BEFORE还是AFTER来决定将value插入到该元素的前面还是后面:

127.0.0.1:6379> LRANGE  k1 0 -11) "d"2) "c"3) "b"4) "a"5) "x"127.0.0.1:6379> linsert k1 after "a" "w"(integer) 6127.0.0.1:6379> LRANGE  k1 0 -11) "d"2) "c"3) "b"4) "a"5) "w"6) "x"

9. POPLPUSH(将元素从一个列表转到另一个列表)

先执行RPOP命令再执行 LPUSH 命令。RPOPLPUSH命令会先从source列表类型键的右边弹出一个元素,然后将其加入到destination列表类型键的左边,并返回这个元素的值,整个过程是原子的。

当把列表类型作为队列使用时,RPOPLPUSH命令可以很直观地在多个队列中传递数据。当source和destination相同时,RPOPLPUSH命令会不断地将队尾的元素移到队首,借助这个特性我们可以实现一个网站监控系统:使用一个队列存储需要监控的网址,然后监控程序不断地使用RPOPLPUSH命令循环取出一个网址来测试可用性。这里使用RPOPLPUSH命令的好处在于在程序执行过程中仍然可以不断地向网址列表中加入新网址,而且整个系统容易扩展,允 许多个客户端同时处理队列。

四、列表总结

  • LRUSH + LPOP = Stack

  • LPUSH + RPOP = Queue

  • LPUSH + LTRIM = Capped Collection

  • LPUSH + BRPOP = Message Queue

推荐阅读

Redis开篇介绍

Redis值类型之string

1ab4da7815df4dae02e3c59093340f6f.gif

看完本文有收获?请转发分享给更多人

关注「并发编程之美」,一起交流Java学习心得

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值