(七)Redis 命令及数据类型 -- Hash

摘要

Hash 核心详解

  • Redis Hash 是一种 key → field → value 的数据结构,本质上是
bash 复制代码
key -> Map<String, String>
# 说明
key:Redis 的键(只能是 String)
field:Hash 内的字段名(String)
value:字段值(String,二进制安全)
  • Hash 的核心特性

    适合存储对象型数据
    支持 字段级别读写
    所有操作均为 原子性
    内存效率优于「String + JSON」
    单个 Hash 理论最大 512 MB

  • Hash 的使用场景

bash 复制代码
# 对象缓存
HSET user:1 name zhangsan age 20
# 电商购物车:1)以用户id为key 2)商品id为field 3)商品数量为value
HSET cart:userId commodity:1001 1 commodity:1002 5
# 分布式锁,一个命令搞不定,需要结合Lua脚本
HINCRBY lock uuid:threadId 1 # 创建锁 或 重入+1
EXPIRE lock 30 # 30 秒后自动释放锁
  • Hash结构优缺点
bash 复制代码
• 优点
1)同类数据聚合存储,适合表达对象模型,便于管理与维护
2)相比 string 操作消耗内存与 CPU 更小
    a.当多个小字段被组织在同一个 Hash 中时,整体内存与 CPU 开销通常小于使用多个 String Key,因为Redis 对 小 Hash 使用 ziplist / listpack(紧凑结构),减少了 Key 元数据、过期字典、指针等开销
    b.Hash 过大时(BigHash)优势消失
3)相比 string,减少了 Key 数量,降低元数据与过期字典的额外开销
• 缺点
1) 默认过期只能作用在 key 级别,Hash field 级别过期需 Redis 7.4+ 才支持
```bash
# user:1 这个 Hash 不会过期
HSET user:1 name "Tom" age 18
# HEXPIRE key seconds [NX|XX|GT|LT] FIELDS numfields field [field ...]
# 只有 name field 60 秒后自动删除
HEXPIRE user:1 60 FIELDS 1 name
# 同时给多个 field 设置过期时间
HEXPIRE user:1 60 FIELDS 2 name age
# 使用毫秒级过期(HPEXPIRE)
# HPEXPIRE key milliseconds [NX|XX|GT|LT] FIELDS numfields field [field ...]
HPEXPIRE user:1 60 FIELDS 2 name age
# 查看 field 剩余秒数(HTTL),-1 表示 field 永不过期,-2 表示 field 已过期
# HTTL key FIELDS numfields field [field ...]
HTTL user:1 FIELDS 1 name
# 查看毫秒级 TTL(HPTTL),-1 表示 field 永不过期,-2 表示 field 已过期
# HPTTL key FIELDS numfields field [field ...]
HPTTL user:1 FIELDS 1 name
# 移除过期时间
# HPERSIST key FIELDS numfields field [field ...]
HPERSIST user:1 FIELDS 1 name
  1. 在 Redis Cluster 中,不应设计超大的 Hash Key(BigHash),否则会影响迁移、扩缩容和主从复制性能。
  • 生产环境建议

    一个 Hash = 一个对象
    field 数量建议 < 100
    单 field value 建议 < 1 KB
    大对象拆分为多个 Hash
    避免在大 Hash 上使用 HGETALL

Hash 命令

  • SpringBoot 的 RedisTemplate<K,V>.opsForHash() 中 Hash 数据类型 的操作方法与 Redis 原生命令的对应关系如下:

写入 / 更新

方法功能 方法 Redis 原始命令 备注
设置单个 field-value put(H key, HK hashKey, HV value) HSET key field value 新增或覆盖
批量设置 field-value putAll(H key, Map<HK,HV> m) HSET key field value [field value ...] HMSET 已废弃
field 不存在时设置 putIfAbsent(H key, HK hashKey, HV value) HSETNX key field value 原子操作

读取

方法功能 方法 Redis 原始命令 备注
获取指定 field 的值 get(H key, Object hashKey) HGET key field 不存在返回 null
批量获取多个 field multiGet(H key, Collection<HK> hashKeys) HMGET key field [field ...] 不存在返回 null
获取所有 value values(H key) HVALS key O(N)
获取所有 field-value entries(H key) HGETALL key 生产环境慎用

删除 / 存在性判断

方法功能 方法 Redis 原始命令 备注
删除一个或多个 field delete(H key, Object... hashKeys) HDEL key field [field ...] 返回删除数量
判断 field 是否存在 hasKey(H key, Object hashKey) HEXISTS key field ---

计数与数值运算

方法功能 方法 Redis 原始命令 备注
field 整数自增 increment(H key, HK hashKey, long delta) HINCRBY key field increment value 必须是整数
field 浮点数自增 increment(H key, HK hashKey, double delta) HINCRBYFLOAT key field increment Redis ≥ 2.6
获取 field 对应 value 长度 lengthOfValue(H key, HK hashKey) HSTRLEN key field 不存在返回 0
获取 hash 中 field 数量 size(H key) HLEN key ---

随机访问(Random Access)

  • ⚠️ 随机访问常用于抽样、降级策略,不适合强一致业务
方法功能 方法 Redis 原始命令 备注
随机返回一个 field randomKey(H key) HRANDFIELD key Redis ≥ 6.2
随机返回一个 field-value randomEntry(H key) HRANDFIELD key WITHVALUES Redis ≥ 6.2
随机返回多个 field randomKeys(H key, long count) HRANDFIELD key count count < 0 可重复
随机返回多个 field-value randomEntries(H key, long count) HRANDFIELD key count WITHVALUES ---

遍历与扫描(推荐方式)

方法功能 方法 Redis 原始命令 备注
获取所有 field keys(H key) HKEYS key O(N),大 hash 慎用
游标扫描 hash scan(H key, ScanOptions options) HSCAN key cursor [MATCH] [COUNT] 推荐替代 HGETALL
  • 📌 最佳实践
    • 小 hash:HGETALL
    • 大 hash / 线上系统:HSCAN

Hash Field 级别过期(Redis 7.4+)

  • Redis 7.4 引入 field 级 TTL,这是 Hash 的重大能力增强
  • 设置过期
方法功能 方法 Redis 原始命令 备注
为指定 field 设置过期时间 expire(H key, Duration timeout, Collection<HK> hashKeys) HEXPIRE key seconds FIELDS n field [...] Redis ≥ 7.4
为指定 field 设置过期时间点 expireAt(H key, Instant expireAt, Collection<HK> hashKeys) HEXPIREAT key timestamp FIELDS n field [...] Redis ≥ 7.4
高级过期策略 expire(H key, Expiration expiration, ExpirationOptions options, Collection<HK> hashKeys) HEXPIRE / HEXPIREAT Spring 抽象封装
  • 移除过期时间
方法功能 方法 Redis 原始命令 备注
移除指定 field 的过期时间 persist(H key, Collection<HK> hashKeys) HPERSIST key FIELDS n field [...] Redis ≥ 7.4
相关推荐
惊讶的猫2 小时前
redis总结
redis
符哥20082 小时前
基于mysql如何设置一个商城的数据库结构
数据库·mysql·oracle
chuxinweihui2 小时前
MySQL库数据类型
数据库·mysql
工业HMI实战笔记2 小时前
HMI权限分级设计:兼顾安全与操作效率的平衡术
运维·数据库·安全·ui·自动化·人机交互·交互
为自己_带盐2 小时前
架构演进:从数据库“裸奔”到多级防护
数据库·架构
深蓝电商API2 小时前
Scrapy与MongoDB管道集成:异步存储方案
数据库·scrapy·mongodb
松涛和鸣2 小时前
DAY56 ARM Cortex-A Bare Metal
linux·服务器·c语言·开发语言·arm开发·数据库
lllsure2 小时前
PostgreSQL
数据库·postgresql
XerCis3 小时前
PostgreSQL与MySQL的超全对比(含迁移步骤)
数据库·mysql·postgresql