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 + 告警防止膨胀

七、结语

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

相关推荐
scofield_gyb2 小时前
Redis简介、常用命令及优化
数据库·redis·缓存
難釋懷2 小时前
Redis搭建分片集群
数据库·redis·缓存
神奇萝卜头4 小时前
Redis 主从复制实现原理深度详解
redis
会编程的土豆4 小时前
【从零学javase 第六天】网络编程(+多线程)
开发语言·网络·php
云云只是个程序马喽4 小时前
海外短剧系统开发:支持多语言多支付海外上架app
php
Yupureki5 小时前
《C++实战项目-高并发内存池》7.大块内存的申请与释放
服务器·c语言·开发语言·c++·算法·哈希算法
yashuk5 小时前
Redis的安装教程(Windows+Linux)【超详细】
linux·数据库·redis
灰阳阳5 小时前
Redis的缓存机制
数据库·redis·缓存
wenlonglanying5 小时前
【Redis】设置Redis访问密码
数据库·redis·缓存