Redis 哈希 Hash

Hash 是「字段-值」映射,像一张小表或内存版对象。存一个用户的信息,与其把 JSON 塞进 String,不如用 Hash 把 name、age 拆成字段,读改写都只动需要的部分。

写入与读取

HSET 设字段,HGET 取单个字段,HGETALL 取全部:

HSET user:1001 name zhangsan age 18 city beijing
# 输出:(integer) 3        # 新写入 3 个字段
HGET user:1001 name
# 输出:"zhangsan"
HGETALL user:1001
# 输出:1) "name" 2) "zhangsan" 3) "age" 4) "18" 5) "city" 6) "beijing"

HGETALL 是「字段值交替排列」的扁平列表,程序端通常把它转成字典对象。

批量与多字段

HMGET 一次取多字段,HSETNX 字段不存在才写入:

HMGET user:1001 name age
# 输出:1) "zhangsan" 2) "18"
HSETNX user:1001 name wangwu
# 输出:(integer) 0        # name 已存在,写入失败
HLEN user:1001
# 输出:(integer) 3        # 字段总数

字段修改与删除

HINCRBY 对数字字段原子增减,HDEL 删除指定字段:

HINCRBY user:1001 age 1
# 输出:(integer) 19
HINCRBY user:1001 score 95
# 输出:(integer) 95
HDEL user:1001 city
# 输出:(integer) 1

统计型字段(积分、余额)用 Hash 存同样支持原子自增,比整串 JSON 安全得多。

常用命令一览

命令作用
HSET key field value设置字段,可一次多个
HGET key field取单个字段
HMGET key f1 f2批量取字段
HGETALL key取全部字段与值
HDEL key field删除字段
HEXISTS key field字段是否存在
HLEN key字段个数
HKEYS / HVALS取所有字段名 / 所有值
HINCRBY key field n字段值原子加 n
HKEYS user:1001
# 输出:1) "name" 2) "age" 3) "score"
HVALS user:1001
# 输出:1) "zhangsan" 2) "19" 3) "95"

典型场景:购物车与对象缓存

购物车以 user 为 key、商品 ID 为字段、数量为值:

HSET cart:1001 item:88 2
# 输出:(integer) 1
HINCRBY cart:1001 item:88 1     # 再加一件
# 输出:(integer) 3
HGETALL cart:1001
# 输出:1) "item:88" 2) "3"

对象缓存同理:主键字段只读所需列,用户资料页性能远好于 String 整串方案。

易踩坑

  • 字段极多(上万)时 HGETALL 会阻塞主线程,应改用 HSCAN 分批遍历;
  • Hash 整体过期用 EXPIRE 作用于 key,不能单独给某个字段设过期;
  • 字段名要避开冒号等特殊字符,防止与键命名规范混淆。

小结

Hash 适合「一个对象的多个字段」,写少改少、读多改多都占优。HSET/HGET/HGETALL 打底,HINCRBY 处理计数,注意大 Hash 别 HGETALL 全量拉取即可。

笔记加载中…