
Redis HSET 命令详细教程HSET设置 Hash 中一个或多个字段的值Key 不存在时自动创建。返回值是新增字段的数量这是它最容易被误读的地方。资料合集https://pan.quark.cn/s/10e98d308913、https://pan.quark.cn/s/f56bc69c5338一、概览与语法HSET key field value [field value ...]项目说明数据类型Hash支持版本Redis 2.0.0 起4.0.0 起支持多组字段值keyHash 的 Key不存在时自动创建field value一组或多组字段与值必须成对出现返回值整数新增字段的数量不含被更新的字段时间复杂度每对字段值 O(1)N 对即 O(N)ACLwrite、hash、fast命令标记write、denyoom、fast官方历史记录显示 4.0.0 起开始接受多个 field 与 value 参数在此之前只能写一组。$TRAE_REF二、基础示例以下命令在测试实例的 redis-cli 中执行。文中结果是预期说明未实际连接 Redis 运行。示例沿用官方示例的数据。DEL tutorial:{hset}:myhash HSET tutorial:{hset}:myhash field1 Hello HGET tutorial:{hset}:myhash field1 HSET tutorial:{hset}:myhash field2 Hi field3 World HGET tutorial:{hset}:myhash field2 HGET tutorial:{hset}:myhash field3 HGETALL tutorial:{hset}:myhash预期结果第一次 HSET 返回1HGET 返回Hello第二条 HSET 一次写入两组返回2两次 HGET 分别返回Hi与WorldHGETALL 返回 6 个元素顺序不确定。三、返回值语义返回值是“新增字段的数量”不是字段总数也不是写入是否成功。场景返回值写入 3 个全新字段3写入 3 个已存在字段0写入 1 个新字段 2 个已有字段1Key 不存在并写入 2 个字段2DEL tutorial:{hset}:ret HSET tutorial:{hset}:ret a 1 b 2 HSET tutorial:{hset}:ret a 99 HSET tutorial:{hset}:ret a 100 c 3 HLEN tutorial:{hset}:ret预期结果第一次返回2第二次全部是更新返回0第三次只有 c 是新增返回1HLEN 返回3说明总数需要另外查询。要判断字段是否存在应使用 HEXISTS要判断字段总数应使用 HLEN。四、覆盖语义与 TTL 影响HSET 是赋值操作会直接覆盖已有字段的值。这一语义带来一个常被忽略的后果覆盖字段会清除该字段已有的 TTL。操作是否覆盖值对字段 TTL 的影响HSET是清除该字段的 TTLHSETNX仅在字段不存在时不涉及已存在字段HINCRBY、HINCRBYFLOAT否在原值上运算保留 TTLHEXPIRE 系列否只改 TTL设置或更新 TTLDEL tutorial:{hset}:ttl HSET tutorial:{hset}:ttl a 1 HEXPIRE tutorial:{hset}:ttl 300 FIELDS 1 a HTTL tutorial:{hset}:ttl FIELDS 1 a HSET tutorial:{hset}:ttl a 2 HTTL tutorial:{hset}:ttl FIELDS 1 a预期结果设置 TTL 后 HTTL 返回正数HSET 覆盖 a 之后 HTTL 变为-1TTL 被清除。字段级 TTL 需要 Redis 7.4 或更高版本。若要写入新值并保留原 TTL可使用 HSETEX 的 KEEPTTL 选项Redis 8.0 起。五、错误与边界情况场景行为Key 不存在自动创建 Hash字段已存在覆盖其值并返回 0 计入Key 是 String、List 等非 Hash报 WRONGTYPE 错误字段与值未成对报语法错误未提供任何字段值对报语法错误字段名或值为空字符串合法正常写入内存达到上限且策略禁止写入命令带 denyoom 标记整条命令被拒绝值会被按字符串存储数字、布尔值、对象序列化后的文本都只是字符串Redis 不做类型解释。需要数值运算时应使用 HINCRBY 或 HINCRBYFLOAT而不是先 HSET 再自行计算写回。六、原子性与并发单条 HSET 是一条命令多组字段值在服务端原子写入不会出现“写了一半”的中间状态。但“先读取、再决定写什么”的流程不是原子的两次调用之间其他客户端可能已修改数据。需要基于旧值做条件写入时应使用 HSETNX、Lua 脚本或带 WATCH 的事务。需要注意多字段 HSET 虽然原子但如果内存不足而被拒绝整条命令失败不会部分成功也不会返回部分写入的计数。七、客户端示例前提为已安装 redis-py 并准备好本地测试实例。importredis rredis.Redis(hostlocalhost,port6379,decode_responsesTrue)ktutorial:{hset}:pythontry:r.delete(k)print(r.hset(k,name,Alice))# 1新增print(r.hset(k,mapping{name:Bob,age:30}))# 1只有 age 是新增print(r.hset(k,name,Carol))# 0纯更新print(r.hgetall(k))# {name: Carol, age: 30}finally:r.delete(k)r.close()JavaJedis示例try(JedisjedisnewJedis(localhost,6379)){System.out.println(jedis.hset(tutorial:{hset}:java,name,Alice));// 1MapString,StringdatanewHashMap();data.put(name,Bob);data.put(age,30);System.out.println(jedis.hset(tutorial:{hset}:java,data));// 1jedis.del(tutorial:{hset}:java);}八、与相近命令的区别命令写入范围返回值状态HSET多组字段值新增字段数推荐HMSET多组字段值OK4.0.0 起弃用HSETNX单字段0 或 1仅字段不存在时写入HSETEX多组字段值 TTL0 或 18.0 起可设置过期HINCRBY单字段整数运算后结果原子计数HSET 与 HMSET 参数结构一致迁移只需替换命令名但依赖OK判断成功的代码需要同步调整。九、练习、排错与总结练习新建tutorial:{hset}:exercise用 HSET 一次写入 a1、b2确认返回2再用 HSET 写入 a9、c3确认返回1只有 c 新增用 HLEN 确认字段总数为 3给 a 设置 TTL 后用 HSET 覆盖 a观察 HTTL 变为 -1。排错要点返回 0 说明是纯更新而非失败需要字段总数时用 HLEN 而不是累加 HSET 返回值报 WRONGTYPE 时用 TYPE 检查类型报参数错误时检查字段与值是否成对写入后 TTL 消失属正常需要保留时改用 HSETEX 的 KEEPTTL内存不足时整条命令失败应检查 maxmemory 与淘汰策略。清理使用DEL tutorial:{hset}:myhash tutorial:{hset}:ret tutorial:{hset}:ttl tutorial:{hset}:exercise。速记返回新增字段数、多字段写入原子、覆盖会清除字段 TTL、4.0 起支持多组参数、HMSET 的推荐替代。