Redis Hash(哈希) · 1. 定位:解决什么问题至2. 命令速查与示例
本文按 Redis 8.2.10 核对编码与配置默认值;命令的引入版本另行标注。生产配置可能不同,可通过 CONFIG GET 查询。示例面向独立实验服务,运行结果和内存数字未在本次实测。
Redis Hash(哈希)
本文按 Redis 8.2.10 核对编码与配置默认值;命令的引入版本另行标注。生产配置可能不同,可通过 CONFIG GET 查询。示例面向独立实验服务,运行结果和内存数字未在本次实测。
1. 定位:解决什么问题
Hash 是一个键下的字段—值集合,适合资料、背包数量和按卡池组织的保底计数。只整体读写对象时可选 String;需要去重成员时可选 Set。Hash 字段无排名语义,也不能当成嵌套 JSON 数据库。
基本操作示例
HSET learn:types:user name Ada level 3
HGET learn:types:user name
HINCRBY learn:types:user level 1预期姓名为 Ada,等级更新到 4。读取少数字段时优先指定字段;对很大的 Hash 使用 HGETALL 会读取全部内容。整个键的过期与字段过期是不同能力,字段过期需要核对 Redis 版本及命令支持。
参考:Hash。
游戏与后端场景
| 场景 | 建模与操作 | 需要补齐的业务规则 |
|---|---|---|
| 玩家资料 | player:1001 的 name、level 等字段 | 高频变化与大字段可按访问模式拆开 |
| 背包堆叠 | HINCRBY inv:1001 potion 5 | 扣除前检查库存与扣除须一起执行;单独减数不保证非负 |
| 抽卡保底 | HINCRBY pity:1001 banner42 1 | 命中后重置与奖励发放需要统一事务或状态机,不能只靠计数 |
| 日任务进度 | quest:1001:2026-10-20 下分字段存进度 | 明确业务日和过期时刻,领奖需要幂等记录 |
2. 命令速查与示例
按用途分组,共 28 项,覆盖 Redis 8.2.10 的本类型命令及子命令。点击命令名查看官方参数。示例在 redis-cli 中逐行输入,每次换例子前重置下面的教学数据。
准备与重置示例数据
在独立实验实例的 redis-cli 交互模式逐行输入,避免 shell 对引号、>、*、括号等符号进行解释。每个例子独立使用;换例子前重新执行下面的准备段,否则删除、弹出、过期和修改操作会影响后续结果。准备段仅重置列出的教学键,确认这些键不承载业务数据。
UNLINK learn:{hash}:obj
HSET learn:{hash}:obj name Ada level 3 coins 100 ratio 1.5示例的返回说明以刚完成准备段为前提,随机结果与剩余 TTL 不固定。带同一 {...} 的教学键便于在 Cluster 中满足相关多键操作的同槽要求。
写入与数值修改
| 命令与用途 | 示例与结果 | 复杂度 |
|---|---|---|
| HSET 写入一个或多个字段 | HSET learn:{hash}:obj name Bob score 100覆盖 name 并新增 score,返回新增字段数 1。 | O(F) |
| HSETNX 字段不存在时写入 | HSETNX learn:{hash}:obj title rookie返回 1;已有字段时返回 0。 | O(1) |
| HSETEX 设置字段及字段过期 | HSETEX learn:{hash}:obj EX 60 FIELDS 1 status online返回 1;status 字段有效期 60 秒。 | O(F) |
| HINCRBY 字段整数加减 | HINCRBY learn:{hash}:obj coins -5100 变成 95;不自动保证余额非负。 | O(1) |
| HINCRBYFLOAT 字段浮点数增加 | HINCRBYFLOAT learn:{hash}:obj ratio 0.25返回 1.75。 | O(1) |
| HDEL 删除字段 | HDEL learn:{hash}:obj name level返回删除数 2。 | O(F) |
读取与遍历
| 命令与用途 | 示例与结果 | 复杂度 |
|---|---|---|
| HGET 读取单字段 | HGET learn:{hash}:obj name返回 Ada。 | O(1) |
| HMGET 读取多个字段 | HMGET learn:{hash}:obj name level missing返回 Ada、3 和空值。 | O(F) |
| HGETALL 读取全部字段和值 | HGETALL learn:{hash}:obj返回所有字段和值,顺序不保证。 | O(N) |
| HGETDEL 读取并删除指定字段 | HGETDEL learn:{hash}:obj FIELDS 1 name返回 Ada 并删除 name。 | O(F) |
| HGETEX 读取并更改字段过期 | HGETEX learn:{hash}:obj EX 60 FIELDS 1 name返回 Ada 并设置 name 的有效期。 | O(F) |
| HEXISTS 判断字段存在 | HEXISTS learn:{hash}:obj name返回 1。 | O(1) |
| HLEN 统计字段数量 | HLEN learn:{hash}:obj准备数据包含 4 个字段,返回 4。 | O(1) |
| HSTRLEN 字段值字节长度 | HSTRLEN learn:{hash}:obj nameAda 为 3 字节。 | O(1) |
| HKEYS 列出全部字段名 | HKEYS learn:{hash}:obj返回 name、level、coins、ratio,顺序不保证。 | O(N) |
| HVALS 列出全部字段值 | HVALS learn:{hash}:obj返回所有值,顺序不保证。 | O(N) |
| HRANDFIELD 随机取字段 | HRANDFIELD learn:{hash}:obj 2 WITHVALUES返回随机两个不同字段及其值,不修改数据。 | O(M) |
| HSCAN 游标遍历字段 | HSCAN learn:{hash}:obj 0 MATCH "*" COUNT 10使用返回游标继续,直到为 0;COUNT 不是严格上限。 | 单次 O(1) 完整 O(N) |
字段过期
| 命令与用途 | 示例与结果 | 复杂度 |
|---|---|---|
| HEXPIRE 字段相对秒过期 | HEXPIRE learn:{hash}:obj 60 FIELDS 1 name返回每个字段的状态码;本例成功为 1。 | O(F) |
| HPEXPIRE 字段相对毫秒过期 | HPEXPIRE learn:{hash}:obj 60000 FIELDS 1 name成功为 1。 | O(F) |
| HEXPIREAT 字段绝对秒时间过期 | HEXPIREAT learn:{hash}:obj 4102444800 FIELDS 1 name示例设到 2100-01-01 UTC,实际应计算业务期限。 | O(F) |
| HPEXPIREAT 字段绝对毫秒时间过期 | HPEXPIREAT learn:{hash}:obj 4102444800000 FIELDS 1 name毫秒 Unix 时间戳,不要与秒混用。 | O(F) |
| HTTL 字段剩余秒数 | HEXPIRE learn:{hash}:obj 60 FIELDS 1 nameHTTL learn:{hash}:obj FIELDS 1 name及时读取约为 0–60;-1 无过期,-2 字段不存在。 | O(F) |
| HPTTL 字段剩余毫秒数 | HPEXPIRE learn:{hash}:obj 60000 FIELDS 1 nameHPTTL learn:{hash}:obj FIELDS 1 name及时读取约为 0–60000。 | O(F) |
| HEXPIRETIME 字段绝对过期秒时间 | HEXPIREAT learn:{hash}:obj 4102444800 FIELDS 1 nameHEXPIRETIME learn:{hash}:obj FIELDS 1 name返回 4102444800。 | O(F) |
| HPEXPIRETIME 字段绝对过期毫秒时间 | HPEXPIREAT learn:{hash}:obj 4102444800000 FIELDS 1 nameHPEXPIRETIME learn:{hash}:obj FIELDS 1 name返回 4102444800000。 | O(F) |
| HPERSIST 移除字段过期 | HEXPIRE learn:{hash}:obj 60 FIELDS 1 nameHPERSIST learn:{hash}:obj FIELDS 1 name本例返回成功状态 1;键级 TTL 不因此改变。 | O(F) |
旧版兼容命令
| 命令与用途 | 示例与结果 | 复杂度 |
|---|---|---|
| HMSET 旧式批量字段写入 | HMSET learn:{hash}:obj name Bob level 4返回 OK;新代码用支持多字段的 HSET。 | O(F) |
版本与复杂度补充
下表保留每条命令的引入版本、兼容状态及复杂度符号含义;复杂度不包含全部网络传输、内存分配和等待成本。
| 命令 | 引入版本与状态 | 复杂度说明 |
|---|---|---|
| HSET | 2.0.0 | O(F),F 为本次指定字段数。 |
| HSETNX | 2.0.0 | O(1)。大值复制、扩容、网络输出和等待时间需另外考虑。 |
| HSETEX | 8.0.0 | O(F),F 为本次指定字段数。 |
| HINCRBY | 2.0.0 | O(1)。大值复制、扩容、网络输出和等待时间需另外考虑。 |
| HINCRBYFLOAT | 2.6.0 | O(1)。大值复制、扩容、网络输出和等待时间需另外考虑。 |
| HDEL | 2.0.0 | O(F),F 为本次指定字段数。 |
| HGET | 2.0.0 | O(1)。大值复制、扩容、网络输出和等待时间需另外考虑。 |
| HMGET | 2.0.0 | O(F),F 为本次指定字段数。 |
| HGETALL | 2.0.0 | O(N),N 为 Hash 中的字段数。 |
| HGETDEL | 8.0.0 | O(F),F 为本次指定字段数。 |
| HGETEX | 8.0.0 | O(F),F 为本次指定字段数。 |
| HEXISTS | 2.0.0 | O(1)。大值复制、扩容、网络输出和等待时间需另外考虑。 |
| HLEN | 2.0.0 | O(1)。大值复制、扩容、网络输出和等待时间需另外考虑。 |
| HSTRLEN | 3.2.0 | O(1)。大值复制、扩容、网络输出和等待时间需另外考虑。 |
| HKEYS | 2.0.0 | O(N),N 为 Hash 中的字段数。 |
| HVALS | 2.0.0 | O(N),N 为 Hash 中的字段数。 |
| HRANDFIELD | 6.2.0 | O(M),M 为返回字段数。 |
| HSCAN | 2.8.0 | 官方渐进遍历口径:单次 O(1),完整迭代 O(N);COUNT 只是提示,编码和结果数量影响耗时。 |
| HEXPIRE | 7.4.0 | O(F),F 为本次指定字段数。 |
| HPEXPIRE | 7.4.0 | O(F),F 为本次指定字段数。 |
| HEXPIREAT | 7.4.0 | O(F),F 为本次指定字段数。 |
| HPEXPIREAT | 7.4.0 | O(F),F 为本次指定字段数。 |
| HTTL | 7.4.0 | O(F),F 为本次指定字段数。 |
| HPTTL | 7.4.0 | O(F),F 为本次指定字段数。 |
| HEXPIRETIME | 7.4.0 | O(F),F 为本次指定字段数。 |
| HPEXPIRETIME | 7.4.0 | O(F),F 为本次指定字段数。 |
| HPERSIST | 7.4.0 | O(F),F 为本次指定字段数。 |
| HMSET | 2.0.0;从 4.0.0 起弃用(兼容保留) | O(F),F 为本次指定字段数。 |
通用键操作见键与过期时间,这里集中列出类型自身的命令。
继续阅读
- 数据与原子性
- 数据与原子性
- 完整实践