Redis HGET 命令详细教程
HGET读取 Hash 中指定字段的值。它是 Hash 最基础的读取命令,一次只读取一个字段,字段或 Key 不存在时返回空值(Null)。
资料合集:https://pan.quark.cn/s/10e98d308913、https://pan.quark.cn/s/f56bc69c5338
一、概览与语法
HGET key field| 项目 | 说明 |
|---|---|
| 数据类型 | Hash |
| 支持版本 | Redis 2.0.0 起 |
| key | Hash 的 Key |
| field | 一个完整字段名,不支持通配符 |
| 返回值 | 字段值的字符串;字段或 Key 不存在时为空值 |
| 时间复杂度 | O(1) |
| ACL | @read、@hash、@fast |
| 命令标记 | readonly |
RESP2 使用空批量字符串(Nil)表示不存在,RESP3 使用 Null;客户端通常转换为None、nil或null。命令本身不区分“Key 不存在”和“字段不存在”,两种情况返回相同的空值。$TRAE_REF
二、基础示例
以下命令在测试实例的 redis-cli 中执行。文中结果是预期说明,未实际连接 Redis 运行。
DEL tutorial:{hget}:user tutorial:{hget}:missing HSET tutorial:{hget}:user name Alice city Shanghai empty "" HGET tutorial:{hget}:user name HGET tutorial:{hget}:user empty HGET tutorial:{hget}:user age HGET tutorial:{hget}:missing name EXISTS tutorial:{hget}:user预期结果:读取 name 返回"Alice";读取 empty 返回空字符串,两者都是成功读取;读取不存在的 age 返回(nil);在缺失 Key 上读取也返回(nil);EXISTS 返回1,说明缺失字段的读取不会影响 Key 的存在性。
三、空字符串与空值的区别
这是 HGET 最容易出错的地方。字段值为空字符串表示字段存在但内容为空;返回空值表示字段或 Key 不存在。两者在 Redis 协议层面不同,但部分客户端解码后都表现为“假值”,容易混淆。
| 状态 | HGET 结果 | HEXISTS | 说明 |
|---|---|---|---|
字段存在,值为"Alice" | "Alice" | 1 | 正常读取 |
字段存在,值为"" | ""(空字符串) | 1 | 字段存在,内容为空 |
| 字段不存在 | 空值 | 0 | 字段缺失 |
| Key 不存在 | 空值 | 0 | 整个 Hash 缺失 |
字段存在,值为"0" | "0" | 1 | 文本"0"也是有效值 |
字段存在,值为"null" | "null" | 1 | Redis 不把该文本当空值 |
HSET tutorial:{hget}:user flag 0 HGET tutorial:{hget}:user flag HEXISTS tutorial:{hget}:user flag HGET tutorial:{hget}:user absent HEXISTS tutorial:{hget}:user absent前两次依次返回"0"和1,后两次依次返回(nil)和0。在业务代码里应显式判断是否为 None(Python)或 null(Java),而不是用if value之类的真值判断,否则值为"0"或""时会被误判。
四、错误类型与边界情况
| 场景 | 行为 |
|---|---|
| Key 是 String、List、Set 等非 Hash 类型 | 报 WRONGTYPE 错误,而不是返回空值 |
| 字段名为空字符串 | 合法,使用HGET key ""读取 |
| 字段名为星号 | 按字面字段名*处理,不是通配匹配 |
| 字段名大小写不同 | 视为不同字段,name 与 Name 互不相通 |
| Key 已到期 | 视作不存在,返回空值 |
| 参数个数不对 | 报语法错误,HGET 只接受 key 与 field 两个参数 |
SET tutorial:{hget}:wrong text HGET tutorial:{hget}:wrong name上述命令会报 WRONGTYPE。需要先确认类型时可执行 TYPE,但要注意 TYPE 与 HGET 是两次独立调用,中间可能有其他客户端改动该 Key。
五、字段过期与 TTL
HGET 是只读命令,不会刷新整个 Key 的 TTL,也不会刷新字段自身的 TTL。在 Redis 7.4 及以后,字段可以单独设置过期时间,此时字段到期后 HGET 会返回空值,而同一 Hash 的其他字段仍可正常读取。
DEL tutorial:{hget}:ttl HSET tutorial:{hget}:ttl stable yes temporary yes HEXPIRE tutorial:{hget}:ttl 2 FIELDS 1 temporary HGET tutorial:{hget}:ttl temporary及时执行时最后一次读取返回"yes"。等待超过 2 秒后再读取 temporary 会返回空值,而 stable 仍为"yes"。因此“刚读到值”不代表后续仍存在,需要长期有效的数据不应依赖临期字段。
六、客户端示例
前提为已安装 redis-py 并准备好本地测试实例。redis-py 的hget(name, key)中第二个参数是 Hash 字段名,不是另一个 Redis Key;无论是否启用解码,字段缺失时都返回 None。
importredis r=redis.Redis(host="localhost",port=6379,decode_responses=True)k="tutorial:{hget}:python"try:r.delete(k)r.hset(k,mapping={"name":"Alice","empty":"","count":"0"})print(r.hget(k,"name"))# Aliceprint(r.hget(k,"empty"))# 空字符串,不是 Noneprint(r.hget(k,"count"))# 0print(r.hget(k,"absent"))# Nonevalue=r.hget(k,"empty")print(valueisNone)# False:字段存在print(value=="")# True:内容为空ifr.hget(k,"absent")isNone:print("字段不存在或 Key 不存在")finally:r.delete(k)r.close()Java 客户端(Jedis)示例,返回 null 表示字段或 Key 不存在:
try(Jedisjedis=newJedis("localhost",6379)){jedis.hset("tutorial:{hget}:java","name","Alice");Stringvalue=jedis.hget("tutorial:{hget}:java","name");System.out.println(value);// AliceSystem.out.println(jedis.hget("tutorial:{hget}:java","x"));// nulljedis.del("tutorial:{hget}:java");}七、与相近命令的区别
| 命令 | 读取范围 | 说明 |
|---|---|---|
| HGET | 单个字段 | O(1),最常用 |
| HMGET | 多个指定字段 | 一次返回多个值,缺失字段对应空值 |
| HGETALL | 全部字段与值 | O(N),大 Hash 慎用 |
| HKEYS / HVALS | 全部字段名 / 全部值 | 只取一侧 |
| HSTRLEN | 单个字段值的长度 | 只返回长度,不返回值 |
| HGETDEL | 读取并删除字段 | Redis 8.0 起,适合一次性消费 |
| HGETEX | 读取并可选设置字段 TTL | Redis 8.0 起,读取同时续期 |
需要多个字段时用 HMGET 一次取回,比循环 HGET 更省往返;但 HMGET 的结果同样不是原子快照,仍可能与其他写入交错。
八、原子性与常见模式
“先 HGET 判断,再决定是否写入”是典型的非原子流程:两次调用之间其他客户端可能已经修改该字段。仅当字段不存在才写入,应使用 HSETNX;需要按旧值条件更新,应使用 Lua 脚本或带 WATCH 的事务设计。单条 HGET 本身是原子的,它返回的是执行瞬间的值。
HGET 常用于读取对象属性、缓存字段、配置项。注意 HGET 返回的是字符串,数值字段需要业务自行解析,解析失败不代表 Redis 出错。不要用 HGET 遍历整个 Hash,也不要为了取一个字段而调用 HGETALL。
九、练习、排错与总结
练习:新建tutorial:{hget}:exercise,写入 a=1、b="";执行 HGET 读取 a 与 b,预期分别得到"1"与空字符串;读取 c,预期为空值;用 HEXISTS 分别验证三者,预期为 1、1、0;最后用 EXISTS 确认 Key 仍然存在。
排错要点:返回空值时用 HEXISTS 区分“字段不存在”还是“Key 不存在”;报 WRONGTYPE 时用 TYPE 检查数据类型;读到"0"却走了“空分支”说明业务用了真值判断;unknown command 的情况不存在于 2.0 以上版本,应检查是否拼写错误或客户端封装方法名不对。清理使用DEL tutorial:{hget}:user tutorial:{hget}:missing tutorial:{hget}:wrong tutorial:{hget}:ttl tutorial:{hget}:exercise。速记:单字段读取、O(1)、只读不续期、空字符串与空值必须区分。