Redis命令-Hash命令

一、前言:为什么用 Hash 存储对象更高效?

在 Redis 中,如果你需要存储一个用户、商品或订单等结构化对象,你会怎么选?

  • ❌ 方案 A:用 SET user:1001 '{"name":"张三","age":28}'(JSON 字符串)
  • ✅ 方案 B:用 HSET user:1001 name "张三" age 28(Hash 结构)

方案 B 更优 !因为 Hash 支持字段级操作,无需反序列化整个对象,内存占用更低,更新更高效。

本文将带你:

✅ 全面掌握 Hash 类型的核心命令

✅ 理解其底层编码机制

✅ 结合真实场景(用户资料、商品属性)

✅ 避开常见使用误区


二、Hash 类型基本特性

  • 结构 :一个 Key 对应多个 field-value 对(类似 Map)
  • 适用场景:存储对象、配置项、属性集合
  • 底层编码
    • ziplist:当字段少、值小时(默认 ≤ 512 个 field,每个 value ≤ 64 字节)
    • hashtable:超出阈值后自动转为哈希表
  • 内存效率高:相比 String 存 JSON,可节省 20%~50% 内存

三、核心命令详解(附实战示例)

1. HSET key field value [field value ...]

设置一个或多个字段的值(覆盖写入)。

bash 复制代码
# 设置单个字段
HSET user:1001 name "张三"

# 批量设置(推荐!减少网络往返)
HSET user:1001 age 28 city "北京" gender "男"

⚡ 返回值:新增字段数量(若字段已存在,不计入)


2. HGET key field

获取指定字段的值。

bash 复制代码
HGET user:1001 name
# 返回 "张三"

HGET user:1001 non_existent
# 返回 (nil)

3. HMGET key field [field ...]

批量获取多个字段(强烈推荐替代多次 HGET)。

bash 复制代码
HMGET user:1001 name age city
# 返回 1) "张三" 2) "28" 3) "北京"

✅ 性能优势:1 次 HMGET ≈ 3 次 HGET 的 1/3 延迟


4. HGETALL key

获取所有字段和值。

bash 复制代码
HGETALL user:1001
# 返回 1) "name" 2) "张三" 3) "age" 4) "28" ...

⚠️ 慎用 :当 Hash 包含成千上万个字段时,会阻塞 Redis!

✅ 替代方案:用 HSCAN 分批遍历


5. HDEL key field [field ...]

删除一个或多个字段。

bash 复制代码
# 删除用户城市信息
HDEL user:1001 city

# 删除多个字段
HDEL user:1001 gender hobby

💡 不会删除整个 Key,除非所有字段都被删光


6. HEXISTS key field

判断字段是否存在。

bash 复制代码
HEXISTS user:1001 email
# 返回 1(存在)或 0(不存在)

✅ 典型用途:避免对不存在的字段执行操作


7. HINCRBY / HINCRBYFLOAT

对数值型字段进行原子自增。

bash 复制代码
# 登录次数 +1
HINCRBY user:1001 login_count 1

# 余额增加 99.9
HINCRBYFLOAT user:1001 balance 99.9

🔒 原子性保证:并发安全,无需额外锁


8. HKEYS / HVALS

  • HKEYS key:获取所有字段名
  • HVALS key:获取所有字段值

⚠️ 同 HGETALL,大数据量时慎用!


四、Hash 的典型应用场景

场景 1:用户资料存储

bash 复制代码
HSET user:profile:1001 \
  name "李四" \
  avatar "https://xxx.jpg" \
  bio "热爱编程" \
  followers 1200 \
  created_at "2023-01-01"

✅ 优势:

  • 更新头像只需 HSET user:profile:1001 avatar "new.jpg"
  • 无需读取整个对象再写回

场景 2:商品属性管理

bash 复制代码
HSET product:8888 \
  title "iPhone 16 Pro" \
  price 9999 \
  stock 500 \
  color "深空黑" \
  category "手机"

💡 电商系统中,商品 SKU 信息天然适合用 Hash


场景 3:配置中心

bash 复制代码
HSET app:config:homepage \
  banner_url "https://..." \
  ad_enabled "true" \
  version "2.1.0"

✅ 动态更新某个配置项,不影响其他字段


五、Hash vs String(存 JSON)对比

维度 Hash String(JSON)
内存占用 更低(尤其小对象) 较高(含 JSON 语法字符)
更新粒度 字段级(高效) 全量覆盖(低效)
读取性能 HMGET 批量快 需反序列化整个字符串
适用对象大小 中小型对象(< 1KB) 任意大小(但大对象不推荐)

📌 建议

  • 对象字段 ≤ 100 个 → 优先用 Hash
  • 对象嵌套复杂或需跨语言共享 → 可考虑 String + JSON

六、常见误区与最佳实践

❌ 误区 1:用 Hash 存超大对象(如 10MB 的日志)

问题 :导致 Redis 主线程阻塞,影响其他请求
建议:大对象拆分或存数据库,Redis 只存 ID

❌ 误区 2:频繁调用 HGETALL 获取全量数据

风险 :O(N) 操作,大数据量卡顿
替代 :按需 HMGET,或用 HSCAN 分页

✅ 最佳实践:

  • Key 命名规范业务:实体:id(如 user:profile:1001
  • 避免 Big Hash:单个 Hash 字段数 ≤ 5000
  • 批量操作优先HSET/HMGET 一次传多字段
  • 数值字段用 HINCRBY :避免先 HGET 再计算再 HSET

七、底层编码切换阈值(拓展知识)

Redis 默认在以下条件同时满足 时使用 ziplist 编码:

  • 字段数量 ≤ hash-max-ziplist-entries(默认 512)
  • 每个 field/value 长度 ≤ hash-max-ziplist-value(默认 64 字节)

可通过 redis.conf 调整:

复制代码
hash-max-ziplist-entries 1024
hash-max-ziplist-value 128

💡 调大可节省更多内存,但可能增加 CPU 开销(压缩/解压 ziplist)


八、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
難釋懷2 小时前
Redis命令-List命令
数据库·redis·list
zqmattack2 小时前
SQL sever根据身份证判断性别函数
java·数据库·sql
hanqunfeng2 小时前
(七)Redis 命令及数据类型 -- Hash
数据库·redis·哈希算法
惊讶的猫2 小时前
redis总结
redis
符哥20082 小时前
基于mysql如何设置一个商城的数据库结构
数据库·mysql·oracle
chuxinweihui2 小时前
MySQL库数据类型
数据库·mysql
工业HMI实战笔记2 小时前
HMI权限分级设计:兼顾安全与操作效率的平衡术
运维·数据库·安全·ui·自动化·人机交互·交互
为自己_带盐2 小时前
架构演进:从数据库“裸奔”到多级防护
数据库·架构
深蓝电商API2 小时前
Scrapy与MongoDB管道集成:异步存储方案
数据库·scrapy·mongodb