redis 数据类型 List(列表)

1 基本命令

  • 插入
      和 Java 的 List 类似,可重复插入数据,这里的插入操作相当于栈、队列。也可以看成是默认从左到右插入。在这里插入图片描述
127.0.0.1:6379> LPUSH num one 	# 向列表中插入值
(integer) 1
127.0.0.1:6379> LPUSH num two	
(integer) 2
127.0.0.1:6379> LPUSH num three
(integer) 3
127.0.0.1:6379> LRANGE num 0 -1	# 获取列表所有值
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LRANGE num 0 1	# 获取列表下标 [0,1] 范围的值,可以看出,后插入的在左边或队尾或栈底
1) "three"
2) "two"
127.0.0.1:6379> RPUSH num four	# 向右边或队头或栈顶插入值
(integer) 4
127.0.0.1:6379> LRANGE num 0 -1
1) "three"
2) "two"
3) "one"
4) "four"
  • 移除
127.0.0.1:6379> LPOP num	# 移除 list 的第一个元素(最左边)并返回值
"three"
127.0.0.1:6379> RPOP num	# 移除 list 的最后一个元素(最右边)并返回值
"four"
127.0.0.1:6379> LRANGE num 0 -1
1) "two"
2) "one"
  • 获取长度
127.0.0.1:6379> LLEN num
(integer) 2
  • 移除
127.0.0.1:6379> LRANGE num 0 -1
1) "three"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> LREM num 1 one	# 移除 1 个指定的值
(integer) 1
127.0.0.1:6379> LRANGE num 0 -1
1) "three"
2) "three"
3) "two"
127.0.0.1:6379> LREM num 2 three	# 移除指定数量的指定值
(integer) 2
127.0.0.1:6379> LRANGE num 0 -1
1) "two"
  • 截取
127.0.0.1:6379> LRANGE num 0 -1
1) "three"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> LTRIM num 1 2	# 截取指定下标范围的值
OK
127.0.0.1:6379> LRANGE num 0 -1
1) "three"
2) "two"
  • 移除元素并移动到另一个列表
127.0.0.1:6379> LRANGE num 0 -1
1) "two"
2) "one"
3) "three"
4) "three"
127.0.0.1:6379> RPOPLPUSH num num2	# 移除 num 列表中最右边的元素,并插入到 num2 列表中
"three"
127.0.0.1:6379> LRANGE num2 0 -1
1) "three"
127.0.0.1:6379> LRANGE num 0 -1
1) "two"
2) "one"
3) "three"
  • 将列表中已存在的值替换,相当于更新
127.0.0.1:6379> LRANGE num 0 -1
1) "two"
2) "one"
3) "three"
127.0.0.1:6379> lset num 0 zero	# 替换下标 0 的值为 zero
OK
127.0.0.1:6379> LRANGE num 0 -1
1) "zero"
2) "one"
3) "three"
127.0.0.1:6379> lset num 3 four	# 下标不存在则报错
(error) ERR index out of range
  • 向列表中某个值 before / after 插入指定值
127.0.0.1:6379> LRANGE num 0 -1
1) "zero"
2) "one"
3) "three"
127.0.0.1:6379> LINSERT num before three two	# 向 three 前面插入 two
(integer) 4
127.0.0.1:6379> LRANGE num 0 -1
1) "zero"
2) "one"
3) "two"
4) "three"
127.0.0.1:6379> LINSERT num after three four# 向 three 后面插入 four
(integer) 5
127.0.0.1:6379> LRANGE num 0 -1
1) "zero"
2) "one"
3) "two"
4) "three"
5) "four"

这种情况相当于链表,使用于两边插入。

2 使用场景

  • 消息队列

  list 类型的 lpop 和 rpush(或者反过来,lpush 和 rpop)能实现队列的功能,故而可以用 Redis 的 lis t类型实现简单的点对点的消息队列。不过我不推荐在实战中这么使用,因为现在已经有 Kafka、NSQ、RabbitMQ 等成熟的消息队列了,它们的功能已经很完善了,除非是为了更深入地理解消息队列,不然我觉得没必要去重复造轮子。

  • 排行榜

  list 类型的 lrange 命令可以分页查看队列中的数据。可将每隔一段时间计算一次的排行榜存储在 list 类型中,如京东每日的手机销量排行、学校每次月考学生的成绩排名、斗鱼年终盛典主播排名等。
  但是,并不是所有的排行榜都能用 list 类型实现,只有定时计算的排行榜才适合使用 list 类型存储,与定时计算的排行榜相对应的是实时计算的排行榜,list 类型不能支持实时计算的排行榜,之后在介绍有序集合 sorted set 的应用场景时会详细介绍实时计算的排行榜的实现

  • 最新列表

  list 类型的 lpush 命令和 lrange 命令能实现最新列表的功能,每次通过 lpush 命令往列表里插入新的元素,然后通过lrange命令读取最新的元素列表,如朋友圈的点赞列表、评论列表。

  但是,并不是所有的最新列表都能用list类型实现,因为对于频繁更新的列表,list 类型的分页可能导致列表元素重复或漏掉,举个例子,当前列表里由表头到表尾依次有(E,D,C,B,A)五个元素,每页获取 3 个元素,用户第一次获取到(E,D,C)三个元素,然后表头新增了一个元素 F,列表变成了(F,E,D,C,B,A),此时用户取第二页拿到(C,B,A),元素 C 重复了。只有不需要分页(比如每次都只取列表的前 5 个元素)或者更新频率低(比如每天凌晨更新一次)的列表才适合用 list 类型实现。对于需要分页并且会频繁更新的列表,需用使用有序集合 sorted set 类型实现。另外,需要通过时间范围查找的最新列表,list 类型也实现不了,也需要通过有序集合 sorted set 类型实现,如以成交时间范围作为条件来查询的订单列表。之后在介绍有序集合 sorted set 类型的应用场景时会详细介绍 sorted set 类型如何实现最新列表。

  那么问题来了,对于排行榜和最新列表两种应用场景,list 类型能做到的 sorted set 类型都能做到,list 类型做不到的 sorted set 类型也能做到,那为什么还要使用 list 类型去实现排行榜或最新列表呢,直接用 sorted set 类型不是更好吗?原因是 sorted set 类型占用的内存容量是 list 类型的数倍之多(之后会在容量章节详细介绍),对于列表数量不多的情况,可以用 sorted se 类型来实现,比如上文中举例的打擂金曲排行榜,每天全国只有一份,两种数据类型的内存容量差距可以忽略不计,但是如果要实现某首歌曲的翻唱作品地区排行榜,数百万的歌曲,300 多个地区,会产生数量庞大的榜单,或者数量更加庞大的朋友圈点赞列表,就需要慎重地考虑容量的问题了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值