the-way-to-go - 3. Redis 数据类型: List 列表

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: the-way-to-go - 3. Redis 数据类型: List 列表

Redis 数据类型: List 列表

  1. 单键多值
  2. Redis 列表是简单的 字符串列表 ,按照插入顺序排序。你可以添加一个元素到列表的 头部(左边) 或者 尾部(右边)
  3. 它的底层实际是个 双向链表 ,对两端的操作性能很高,通过索引下标的操作 中间的节点性能会较差

20220311102948

常用命令

把双向链表想象成一根水管, 加入数据 (Push) 就是向水管里 放入 乒乓球。 弹出数据(Pop) 就是从水管理 拿出 乒乓球。

由于可以左右两边分别操作, 因此使用 L / R 表示方向

20220311102927

添加数据 LPush and RPush

LPush 从左侧加入数据, RPush 从右侧加入数据。 一次操作可以 添加 多个数据。

LPUSH key element [element ...]
RPUSH key element [element ...]

从下面案例可以得知, 无论从左右侧添加, 先添加的数据都更靠中间

127.0.0.1:6379[10]> lpush chan zero
(integer) 1
127.0.0.1:6379[10]> lrange chan 0 -1
1) "zero"
127.0.0.1:6379[10]> lrange chan 0 -1
1) "zero"
127.0.0.1:6379[10]> lpush chan l1 l2 l3
(integer) 4
127.0.0.1:6379[10]> rpush chan r1 r2 r3
(integer) 7
127.0.0.1:6379[10]> lrange chan 0 -1
1) "l3"
2) "l2"
3) "l1"
4) "zero"
5) "r1"
6) "r2"
7) "r3"

当数组存在时再添加: LPushX and RPushX

只有到目标数组 存在时LPushXRPushX 才会将元素加入到数组中。

LPUSHX key element [element ...]
RPUSHX key element [element ...]

分别 从左或从右 向数组中添加 至少一个 元素。

127.0.0.1:6379> lpush list_x "world"
(integer) 1
127.0.0.1:6379> LPUSHX list_x "hello"
(integer) 2
127.0.0.1:6379> LRANGE list_x 0 -1
1) "hello"
2) "world"
127.0.0.1:6379>
127.0.0.1:6379> LPUSHX lsit_no "hello"
(integer) 0
127.0.0.1:6379> LRANGE list_no 0 -1
(empty array)
127.0.0.1:6379>

遍历元素: LRANGE

遍历数据只有命令 LRange, 即只能从左侧开始,不能从右侧开始。

LRANGE key start stop

start/stop 表示了数据的下标位置。 0 表示第一个元素, -1 表示最后一个元素。

127.0.0.1:6379[10]> LRANGE chan 0 -1
1) "l3"
2) "l2"
3) "l1"
4) "zero"
5) "r1"
6) "r2"
7) "r3"
127.0.0.1:6379[10]> LRANGE chan 3 -3
1) "zero"
2) "r1"

取出元素: LPOPRPOP

与 push 相反, pop 是取出左右两边最外面的 N个 元素

LPOP key [count]

count 为可选参数, 默认值为 1

127.0.0.1:6379[10]> LPOP chan 2
1) "l3"
2) "l2"

127.0.0.1:6379[10]> RPOP chan
"r3"

127.0.0.1:6379[10]> LRANGE chan 0 -1
1) "l1"
2) "zero"
3) "r1"
4) "r2"

根据索引获取列表元素: LIndex

根据列表中元素的索引获取元素。

LINDEX key index

index 表示元素索引位置。 0 表示第一个元素, -1 表示最后一个元素。

127.0.0.1:6379[10]> LRANGE chan 0 -1
1) "l1"
2) "zero"
3) "r1"
4) "r2"
127.0.0.1:6379[10]> LINDEX chan 0
"l1"
127.0.0.1:6379[10]> LINDEX chan 2
"r1"
127.0.0.1:6379[10]> LINDEX chan -2
"r1"

列表长度: LLEN

返回列表元素个数

LLEN key

ex:

127.0.0.1:6379[10]> LLEN chan
(integer) 4

在列表中间插入元素: LINSERT

列表 所有两侧 push/pop 数据效率是最高的, 但 redis 也支持在列表中间添加元素。

LINSERT key BEFORE|AFTER pivot element

pivot

127.0.0.1:6379[10]> LRANGE chan 0 -1
1) "l1"
2) "zero"
3) "r1"
4) "r2"
127.0.0.1:6379[10]> LINSERT chan BEFORE zero insL1
(integer) 5
127.0.0.1:6379[10]> LINSERT chan AFTER zero insR1
(integer) 6
127.0.0.1:6379[10]> LRANGE chan 0 -1
1) "l1"
2) "insL1"
3) "zero"
4) "insR1"
5) "r1"
6) "r2"

删除元素: LREM

通过 LREM 可以删除列表中 指定数量特定元素

LREM key count element
  1. element 需要倍删除的元素。
  2. count 删除数量个数

    • count > 0 从左往右 计数。
    • count < 0 从右往左 计数。
    • count = 0 删除所有 符合的元素。
127.0.0.1:6379> RPUSH mylist hello
(integer) 1
127.0.0.1:6379> RPUSH mylist hello
(integer) 2
127.0.0.1:6379> RPUSH mylist foo
(integer) 3
127.0.0.1:6379> RPUSH mylist hello
(integer) 4
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "hello"  # 被删
3) "foo"
4) "hello"  # 被删
127.0.0.1:6379> LREM mylist -2 hello
(integer) 2
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "foo"

替换元素: LSET

使用 LSET 根据 下标 替换数组中的对应元素。

LSET key index element
  1. index 下标位置。 0 为第一元素; -1 为最后一个元素。
  2. element 新元素的值
127.0.0.1:6379> LRANGE mylist 0 -1
1) "foo"
2) "foo"
3) "hello"
4) "foo"

127.0.0.1:6379> LSET mylist 0 FOO
OK
127.0.0.1:6379> LSET mylist -1 __FOO__
OK
127.0.0.1:6379> LRANGE mylist 0 -1
1) "FOO"
2) "foo"
3) "hello"
4) "__FOO__"

元素转移: 右出左进 RpopLpush

将一个元素从 数组A右侧 取出, 并放入 数组B 的左侧

RPOPLPUSH source destination
  1. source 源数组
  2. destination 目标数组
127.0.0.1:6379> rpush list_A 1 2 3 4
(integer) 4
127.0.0.1:6379> rpush list_B a b c d
(integer) 4
127.0.0.1:6379> RPOPLPUSH list_A list_B
"4"
127.0.0.1:6379> LRANGE list_A 0 -1
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> lrange list_B 0 -1
1) "4"
2) "a"
3) "b"
4) "c"
5) "d"

其他命令

更多 list 相关命令

https://redis.io/commands/#list

数据结构

  1. List 的数据结构为 快速链表 quickList
  2. 首先在列表 元素较少的情况下会使用一块连续的内存存储 ,这个结构是 ziplist,也即是 压缩列 。它将所有的元素紧挨着一起存储,分配的是一块连续的内存。
  3. 当数据量比较多的时候才会改成 quicklist 。 因为普通的链表需要的附加指针空间太大,会比较浪费空间。比如这个列表里存的只是 int 类型的数据,结构上还需要两个额外的指针prev和next。
  4. Redis 将链表和 ziplist 结合起来组成了 quicklist 。也就是将多个 ziplist 使用双向指针串起来使用。 这样既满足了快速的插入删除性能, 又不会出现太大的空间冗余。

20220311145251

相关文章
|
2月前
|
消息中间件 缓存 NoSQL
Redis各类数据结构详细介绍及其在Go语言Gin框架下实践应用
这只是利用Go语言和Gin框架与Redis交互最基础部分展示;根据具体业务需求可能需要更复杂查询、事务处理或订阅发布功能实现更多高级特性应用场景。
275 86
|
2月前
|
存储 消息中间件 NoSQL
【Redis】常用数据结构之List篇:从常用命令到典型使用场景
本文将系统探讨 Redis List 的核心特性、完整命令体系、底层存储实现以及典型实践场景,为读者构建从理论到应用的完整认知框架,助力开发者在实际业务中高效运用这一数据结构解决问题。
|
4月前
|
存储 NoSQL 定位技术
Redis数据类型面试给分情况
Redis常见数据类型包括:string、hash、list、set、zset(有序集合)。此外还包含高级结构如bitmap、hyperloglog、geo。不同场景可选用合适类型,如库存用string,对象存hash,列表用list,去重场景用set,排行用zset,签到用bitmap,统计访问量用hyperloglog,地理位置用geo。
126 5
|
4月前
|
NoSQL Java Redis
Redis基本数据类型及Spring Data Redis应用
Redis 是开源高性能键值对数据库,支持 String、Hash、List、Set、Sorted Set 等数据结构,适用于缓存、消息队列、排行榜等场景。具备高性能、原子操作及丰富功能,是分布式系统核心组件。
555 2
|
11月前
|
存储 缓存 NoSQL
解决Redis缓存数据类型丢失问题
解决Redis缓存数据类型丢失问题
439 85
|
9月前
|
SQL JSON 关系型数据库
开箱即用的GO后台管理系统 Kratos Admin - 列表查询规则
Kratos Admin 是一个开箱即用的GO后台管理系统,支持通用列表查询请求。通过 `page`、`pageSize`、`query`(AND过滤)、`or`(OR过滤)、`orderBy`(排序)、`noPaging`(不分页)和 `fieldMask`(字段掩码)等参数,灵活配置查询条件。过滤规则遵循Python ORM风格,支持多种查找类型如 `in`、`gte`、`icontains` 等,适用于不同数据库。
158 1
|
8月前
|
NoSQL Redis
Redis的常用数据类型有哪些 ?
Redis 有 5 种基础数据结构,它们分别是:string(字符串)、list(列表)、hash(字典)、set(集 合) 和 zset(有序集合)
|
编译器 Go C语言
go语言基本数据类型和变量
go语言基本数据类型和变量
113 0
|
Go 存储
02-Go语言数据类型与变量
Go基本类型 布尔型: bool - 长度: 1字节 - 取值范围: true,false - 注意事项: 不可以用数字代表true或false 整型: int/uint - 根据运行平台可能为32或64 8位整型:int8/uint8 - 长度: 1字节 - 取值范围: -128~127/0-25...
1037 0
|
Go Java
Golang数据类型和变量
数据类型 先来介绍一下Golang的数据类型。 布尔型 bool类型代表逻辑值,有真值true和假值false两种取值。 整数类型 整数类型有如下几种,这些整数都是有符号的类型,它们的无符号版本是类型名前面添加u,例如uint32。
817 0
下一篇
oss云网关配置