Redis命令-Hash命令

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

在 Redis 中,Hash(哈希) 是一种非常高效的键值对集合类型,特别适合存储对象

例如:

  • 用户信息:user:1001 → {name: "Alice", age: 25, email: "a@example.com"}
  • 商品详情:product:2001 → {title: "手机", price: 2999, stock: 100}

相比将每个字段拆成独立 key(如 user:1001:nameuser:1001:age),Hash 具有:

内存更省 (Redis 对小 Hash 有特殊编码优化)

操作原子性 (单个 Hash 内部操作是原子的)

网络开销更低(一次命令获取多个字段)

本文将系统讲解 Redis Hash 的所有核心命令 ,并附带实战示例与最佳实践


二、Hash 核心命令速查表

命令 作用 时间复杂度
HSET key field value [field value ...] 设置一个或多个字段 O(1) 每个字段
HGET key field 获取指定字段的值 O(1)
HMSET key field value [field value ...] 已废弃 ,用 HSET 替代 ---
HMGET key field [field ...] 获取多个字段的值 O(N),N=字段数
HGETALL key 获取所有字段和值 O(N),N=字段数
HDEL key field [field ...] 删除一个或多个字段 O(N),N=字段数
HEXISTS key field 判断字段是否存在 O(1)
HLEN key 获取 Hash 字段数量 O(1)
HKEYS key 获取所有字段名 O(N)
HVALS key 获取所有字段值 O(N)
HINCRBY key field increment 对整数值字段加减 O(1)
HINCRBYFLOAT key field increment 对浮点值字段加减 O(1)
HSTRLEN key field 获取字段值的字符串长度 O(1)

💡 注意 :从 Redis 4.0 起,HMSET 被标记为 deprecated,统一使用 HSET


三、常用命令详解与示例

3.1 写入数据:HSET

bash 复制代码
# 设置单个字段
127.0.0.1:6379> HSET user:1001 name "Alice"
(integer) 1  # 1=新增,0=更新

# 设置多个字段(推荐!)
127.0.0.1:6379> HSET user:1001 age 25 email "alice@example.com" city "Beijing"
(integer) 3  # 新增了 3 个字段

优势:一次命令完成多字段写入,减少网络往返。


3.2 读取数据:HGET / HMGET / HGETALL

bash 复制代码
# 获取单个字段
127.0.0.1:6379> HGET user:1001 name
"Alice"

# 获取多个字段(按需加载,避免全量)
127.0.0.1:6379> HMGET user:1001 name age city
1) "Alice"
2) "25"
3) "Beijing"

# 获取所有字段(慎用!大数据量会阻塞)
127.0.0.1:6379> HGETALL user:1001
1) "name"
2) "Alice"
3) "age"
4) "25"
5) "email"
6) "alice@example.com"
7) "city"
8) "Beijing"

⚠️ 生产建议

  • 避免在大 Hash 上使用 HGETALL
  • 优先使用 HMGET 按需获取字段

3.3 删除与判断:HDEL / HEXISTS

bash 复制代码
# 删除字段
127.0.0.1:6379> HDEL user:1001 email city
(integer) 2

# 判断字段是否存在
127.0.0.1:6379> HEXISTS user:1001 email
(integer) 0  # 不存在
127.0.0.1:6379> HEXISTS user:1001 name
(integer) 1  # 存在

3.4 计数与遍历:HLEN / HKEYS / HVALS

bash 复制代码
# 字段数量
127.0.0.1:6379> HLEN user:1001
(integer) 2

# 获取所有字段名(调试用)
127.0.0.1:6379> HKEYS user:1001
1) "name"
2) "age"

# 获取所有值
127.0.0.1:6379> HVALS user:1001
1) "Alice"
2) "25"

🔍 注意HKEYS/HVALS/HGETALL 在字段数 > 1000 时可能阻塞主线程!


3.5 数值自增:HINCRBY / HINCRBYFLOAT

bash 复制代码
# 整数自增(常用于计数器)
127.0.0.1:6379> HSET product:2001 view_count 100
127.0.0.1:6379> HINCRBY product:2001 view_count 1
(integer) 101

# 浮点自增(慎用,精度问题)
127.0.0.1:6379> HINCRBYFLOAT product:2001 avg_score 0.5
"0.5"

典型场景:商品浏览量、用户积分、评分统计。


四、Hash 的内部编码优化

Redis 对小 Hash 使用 ziplist(压缩列表) 编码,节省内存:

复制代码
# redis.conf 默认配置
hash-max-ziplist-entries 512   # 字段数 ≤ 512
hash-max-ziplist-value 64      # 每个值长度 ≤ 64 字节

当超过阈值,自动转为 hashtable 编码。

💡 建议

  • 小对象(如用户 profile)非常适合 Hash
  • 大对象(如文章内容)建议用 String 或单独 key

五、实战应用场景

场景 1:用户信息缓存

java 复制代码
// Java (Lettuce)
redis.hset("user:" + userId, 
    Map.of("name", "Alice", "age", "25", "email", "a@example.com"));

String name = redis.hget("user:" + userId, "name");
List<String> fields = redis.hmget("user:" + userId, "name", "age");

场景 2:商品库存与价格

python 复制代码
# Python (redis-py)
r.hset("product:1001", mapping={
    "title": "iPhone 15",
    "price": "5999",
    "stock": "50"
})

# 扣减库存(Lua 脚本保证原子性)
script = """
if tonumber(redis.call('HGET', KEYS[1], 'stock')) >= tonumber(ARGV[1]) then
    redis.call('HINCRBY', KEYS[1], 'stock', -ARGV[1])
    return 1
else
    return 0
end
"""
r.eval(script, 1, "product:1001", 1)

场景 3:会话状态管理

bash 复制代码
HSET session:abc123 user_id 1001 login_time 1700000000 ip "192.168.1.1"
HEXPIRE session:abc123 1800  # Redis 7.0+ 支持 Hash 级 TTL

📌 注意 :Redis 7.0+ 支持 HEXPIRE,但早期版本需对整个 key 设 TTL。


六、常见误区与最佳实践

❌ 误区 1:用 Hash 存储超大对象

  • 问题HGETALL 阻塞主线程
  • 建议:大对象拆分为多个 key,或使用 String + JSON

❌ 误区 2:频繁使用 HGETALL

  • 问题:网络带宽浪费 + 性能下降
  • 建议 :明确需要哪些字段,用 HMGET

✅ 最佳实践

  1. 字段命名规范 :如 user_idcreate_time
  2. 避免动态字段爆炸 :如 HSET log:20250101 ip_192.168.1.1 1(IP 无限)
  3. 监控 Hash 大小 :通过 HLEN + 告警防止膨胀

七、结语

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

相关推荐
Xudde.8 小时前
班级作业笔记报告0x04
笔记·学习·安全·web安全·php
難釋懷9 小时前
OpenResty实现Redis查询
数据库·redis·openresty
eastyuxiao9 小时前
如何在不同的机器上运行多个OpenClaw实例?
人工智能·git·架构·github·php
刘~浪地球10 小时前
Redis 从入门到精通(五):哈希操作详解
数据库·redis·哈希算法
dog25010 小时前
对数的大脑应对指数的世界
开发语言·php
取码网12 小时前
最新在线留言板系统PHP源码
开发语言·php
不写八个13 小时前
PHP教程006:ThinkPHP项目入门
开发语言·php
lifewange14 小时前
Redis的测试要点和测试方法
数据库·redis·缓存
刘~浪地球14 小时前
Redis 从入门到精通(六):列表操作详解
数据库·chrome·redis
better_liang14 小时前
每日Java面试场景题知识点之-Redisson核心价值与优化点详解
java·redis·分布式锁·redisson·微服务架构·分布式系统·缓存优化