Redis的 散列(Hash) 和 列表(List) 数据结构操作详解

Redis的 ​​散列(Hash)​​ 和 ​​列表(List)​​ 数据结构操作详解

Redis 提供了丰富的数据结构操作命令,其中 ​​散列(Hash)​ ​ 和 ​​列表(List)​​ 是最常用的两种结构。以下分别详细介绍它们的常见操作、命令语法及应用场景,并附示例说明。


一、散列(Hash)操作

散列(Hash)是 Redis 中存储​​键值对集合​​的数据结构,适合表示"对象"的属性(如用户的姓名、年龄、邮箱等)。每个散列键对应一个字段(field)和值(value)的映射表,字段和值均为字符串类型。

1. 基础操作

(1)添加/修改字段(HSET)
  • ​命令​ ​:HSET key field value [field value ...]

  • ​作用​ ​:向散列 key中添加或修改一个或多个字段的值(若字段不存在则创建,存在则覆盖)。

  • ​返回值​​:成功添加的字段数量(整数)。

  • ​示例​​:

    复制代码
    # 向用户对象(key=user:1001)中添加姓名和年龄
    redis> HSET user:1001 name "Alice" age 28
    (integer) 2  # 成功添加2个字段
(2)获取单个字段值(HGET)
  • ​命令​ ​:HGET key field

  • ​作用​ ​:获取散列 key中字段 field的值(若字段不存在返回 nil)。

  • ​示例​​:

    复制代码
    redis> HGET user:1001 name
    "Alice"  # 返回姓名字段的值
(3)批量获取多个字段值(HMGET)
  • ​命令​ ​:HMGET key field [field ...]

  • ​作用​ ​:批量获取散列 key中多个字段的值(不存在的字段返回 nil)。

  • ​示例​​:

    复制代码
    redis> HMGET user:1001 name age email
    1) "Alice"   # name 字段的值
    2) "28"      # age 字段的值
    3) (nil)     # email 字段不存在,返回 nil
(4)获取散列所有字段和值(HGETALL)
  • ​命令​ ​:HGETALL key

  • ​作用​ ​:获取散列 key中所有字段(field)和对应的值(value),结果按 field1, value1, field2, value2, ...的顺序返回。

  • ​返回值​​:字段和值的列表(若散列为空则返回空列表)。

  • ​示例​​:

    复制代码
    redis> HSET user:1001 email "alice@example.com"  # 先添加 email 字段
    (integer) 1
    redis> HGETALL user:1001
    1) "name"      # 字段1
    2) "Alice"     # 值1
    3) "age"       # 字段2
    4) "28"       # 值2
    5) "email"     # 字段3
    6) "alice@example.com"  # 值3
(5)删除字段(HDEL)
  • ​命令​ ​:HDEL key field [field ...]

  • ​作用​ ​:删除散列 key中的一个或多个字段(返回成功删除的字段数量)。

  • ​示例​​:

    复制代码
    redis> HDEL user:1001 age email  # 删除 age 和 email 字段
    (integer) 2  # 成功删除2个字段
(6)检查字段是否存在(HEXISTS)
  • ​命令​ ​:HEXISTS key field

  • ​作用​ ​:检查散列 key中是否存在字段 field(存在返回 1,不存在返回 0)。

  • ​示例​​:

    复制代码
    redis> HEXISTS user:1001 name  # name 字段存在
    (integer) 1
    redis> HEXISTS user:1001 age   # age 字段已被删除
    (integer) 0
(7)获取所有字段名(HKEYS)
  • ​命令​ ​:HKEYS key

  • ​作用​ ​:获取散列 key中所有字段名(返回列表,若散列为空则返回空列表)。

  • ​示例​​:

    复制代码
    redis> HKEYS user:1001
    1) "name"  # 仅剩 name 字段
(8)获取所有字段值(HVALS)
  • ​命令​ ​:HVALS key

  • ​作用​ ​:获取散列 key中所有字段的值(返回列表,若散列为空则返回空列表)。

  • ​示例​​:

    复制代码
    redis> HVALS user:1001
    1) "Alice"  # name 字段的值
(9)字段值自增(HINCRBY)
  • ​命令​ ​:HINCRBY key field increment

  • ​作用​ ​:将散列 key中字段 field的值(需为整数)增加 increment(若字段不存在则初始化为 0后再增加)。

  • ​返回值​​:增加后的值(整数)。

  • ​示例​​:

    复制代码
    redis> HSET user:1001 login_count 5  # 初始化登录次数
    (integer) 1
    redis> HINCRBY user:1001 login_count 3  # 增加3次
    (integer) 8  # 当前值为8
(10)获取散列长度(HLEN)
  • ​命令​ ​:HLEN key

  • ​作用​ ​:获取散列 key中字段的数量(返回整数,若散列不存在返回 0)。

  • ​示例​​:

    复制代码
    redis> HLEN user:1001
    (integer) 1  # 仅 name 字段

2. 散列的典型应用场景

  • ​对象存储​ ​:如用户信息(user:1001对应姓名、年龄、手机号等字段)。

  • ​动态配置​ ​:存储系统的动态参数(如 config:redis对应 max_memorytimeout等配置项)。

  • ​统计聚合​ ​:按维度统计数据(如 stats:202408对应 pvuvorder_count等统计值)。


二、列表(List)操作

列表(List)是 Redis 中​​有序、可重复​ ​的字符串集合,支持​​双向插入和删除​​(头部或尾部),底层通过快速列表(QuickList)实现,适合实现队列、栈、消息缓冲区等场景。

1. 基础操作

(1)从左侧插入元素(LPUSH)
  • ​命令​ ​:LPUSH key element [element ...]

  • ​作用​ ​:将一个或多个元素插入到列表 key的头部(左侧),返回插入后列表的长度。

  • ​示例​​:

    复制代码
    redis> LPUSH mylist "a" "b" "c"  # 从左插入 a、b、c
    (integer) 3  # 列表长度为3
    redis> LRANGE mylist 0 -1  # 查看全部元素(0到末尾)
    1) "c"  # 插入顺序:a→b→c,头部插入后顺序变为 c→b→a
    2) "b"
    3) "a"
(2)从右侧插入元素(RPUSH)
  • ​命令​ ​:RPUSH key element [element ...]

  • ​作用​ ​:将一个或多个元素插入到列表 key的尾部(右侧),返回插入后列表的长度。

  • ​示例​​:

    复制代码
    redis> RPUSH mylist "d" "e"  # 从右插入 d、e
    (integer) 5  # 原长度3,插入后长度5
    redis> LRANGE mylist 0 -1
    1) "c"  # 原列表:c→b→a
    2) "b"
    3) "a"
    4) "d"  # 新增 d→e(尾部插入)
    5) "e"
(3)从左侧弹出元素(LPOP)
  • ​命令​ ​:LPOP key [count]

  • ​作用​ ​:移除并返回列表 key头部(左侧)的 count个元素(count默认为 1,若列表为空返回 nil)。

  • ​示例​​:

    复制代码
    redis> LPOP mylist 2  # 弹出左侧2个元素
    1) "c"  # 第一个弹出的元素
    2) "b"  # 第二个弹出的元素
    redis> LRANGE mylist 0 -1
    1) "a"  # 剩余元素:a→d→e
    2) "d"
    3) "e"
(4)从右侧弹出元素(RPOP)
  • ​命令​ ​:RPOP key [count]

  • ​作用​ ​:移除并返回列表 key尾部(右侧)的 count个元素(count默认为 1)。

  • ​示例​​:

    复制代码
    redis> RPOP mylist 1  # 弹出右侧1个元素
    "e"
    redis> LRANGE mylist 0 -1
    1) "a"
    2) "d"  # 剩余元素:a→d
(5)获取指定范围的元素(LRANGE)
  • ​命令​ ​:LRANGE key start end

  • ​作用​ ​:获取列表 key中从索引 startend的元素(索引从 0开始,-1表示最后一个元素)。

  • ​示例​​:

    复制代码
    redis> LRANGE mylist 0 -1  # 获取全部元素
    1) "a"
    2) "d"
    redis> LRANGE mylist 0 0  # 获取第一个元素
    1) "a"
    redis> LRANGE mylist -2 -1  # 获取最后两个元素(仅两个元素时即全部)
    1) "a"
    2) "d"
(6)获取列表长度(LLEN)
  • ​命令​ ​:LLEN key

  • ​作用​ ​:返回列表 key的长度(元素个数,若列表不存在返回 0)。

  • ​示例​​:

    复制代码
    redis> LLEN mylist
    (integer) 2  # 当前列表有2个元素
(7)按索引获取元素(LINDEX)
  • ​命令​ ​:LINDEX key index

  • ​作用​ ​:返回列表 key中索引 index对应的元素(索引从 0开始,-1表示最后一个元素)。

  • ​示例​​:

    复制代码
    redis> LINDEX mylist 0  # 第一个元素
    "a"
    redis> LINDEX mylist 1  # 第二个元素
    "d"
    redis> LINDEX mylist -1  # 最后一个元素(等同于索引1)
    "d"
(8)修改指定索引的元素(LSET)
  • ​命令​ ​:LSET key index element

  • ​作用​ ​:将列表 key中索引 index对应的元素设置为 element(若索引超出范围则返回错误)。

  • ​示例​​:

    复制代码
    redis> LSET mylist 1 "x"  # 修改第二个元素为 x
    OK  # 操作成功
    redis> LRANGE mylist 0 -1
    1) "a"
    2) "x"  # 原 d 被修改为 x
(9)截断列表(LTRIM)
  • ​命令​ ​:LTRIM key start end

  • ​作用​ ​:保留列表 key中索引 startend的元素,超出范围的元素被删除。

  • ​示例​​:

    复制代码
    redis> RPUSH mylist "y" "z"  # 先扩展列表:a→x→y→z
    (integer) 4
    redis> LTRIM mylist 1 2  # 保留索引1到2的元素(x→y)
    OK
    redis> LRANGE mylist 0 -1
    1) "x"
    2) "y"  # 原 a(索引0)和 z(索引3)被删除
(10)阻塞式弹出(BLPOP/BRPOP)
  • ​命令​ ​:BLPOP key [key ...] timeoutBRPOP key [key ...] timeout

  • ​作用​ ​:阻塞等待列表 key头部(BLPOP)或尾部(BRPOP)的元素出现,超时时间 timeout单位为秒(0表示永久阻塞)。

  • ​返回值​ ​:若超时返回 nil;否则返回 [key, element](弹出的列表键和元素)。

  • ​应用场景​​:实现简单的消息队列(生产者 RPUSH,消费者 BRPOP 阻塞等待)。

  • ​示例​​:

    复制代码
    # 消费者端(阻塞等待列表 myqueue 有元素)
    redis> BRPOP myqueue 10  # 等待10秒
    1) "myqueue"  # 弹出的列表键
    2) "task1"     # 弹出的元素(假设此时有其他客户端 RPUSH 了 task1)

2. 列表的典型应用场景

  • ​消息队列​ ​:生产者通过 RPUSH写入消息,消费者通过 LPOPBRPOP读取消息(FIFO 队列)。

  • ​栈结构​ ​:生产者通过 LPUSH写入,消费者通过 LPOP读取(LIFO 栈)。

  • ​历史记录​ ​:存储用户的操作历史(如最近10条搜索记录,通过 LTRIM限制长度)。

  • ​任务池​ ​:存储待处理的任务,多个消费者通过 BRPOP并发获取任务。


三、总结

Redis 的散列(Hash)和列表(List)是两种核心数据结构,分别适用于不同的场景:

  • ​散列​​:适合存储对象的多个属性(如用户信息),支持高效的字段级增删改查。

  • ​列表​​:适合处理有序、可重复的数据序列(如队列、栈、消息缓冲区),支持双向操作和阻塞等待。

熟练掌握这些操作,能帮助开发者在实际项目中高效利用 Redis 优化性能(如减少数据库查询、缓存热点数据)或实现复杂功能(如消息队列、计数器)。