全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-12 6 分钟 ✍️ juanwangdev

Redis哈希

哈希(Hash)是一个键值对集合,适合存储对象结构数据,如用户信息、商品属性等。

结构概述

基本特点

Bash
- 键值对集合,一个Hash包含多个field-value
- 适合存储对象结构
- 类似Java的Map、Python的dict
- 单个Hash最多2^32-1个字段

结构示意

Bash
key: user:1000
├── field: name    → value: "Alice"
├── field: age     → value: "25"
├── field: city    → value: "Beijing"
└── field: email   → value: "alice@example.com"

内部编码

ziplist编码

Bash
触发条件:
- 字段数量 ≤ hash-max-ziplist-entries(默认512)
- 所有value长度 ≤ hash-max-ziplist-value(默认64)

特点:
- 紧凑连续内存
- 内存效率高
- 顺序存储field-value
- 适合小规模数据

hashtable编码

Bash
触发条件:
- 字段数量 > 512
- 或value长度 > 64字节

特点:
- 标准哈希表结构
- 字典实现
- O(1)查找效率
- 内存占用较大

查看编码

Bash
HSET user:1000 name "Alice" age 25
OBJECT ENCODING user:1000
# 返回: "ziplist"

HSET big:hash field1 "very long value exceeding 64 bytes..."
OBJECT ENCODING big:hash
# 返回: "hashtable"

编码转换

转换规则

Bash
# 配置阈值
hash-max-ziplist-entries 512
hash-max-ziplist-value 64

# 超过阈值自动转换
ziplist → hashtable
# 转换不可逆

转换示例

Bash
# 添加超过512个字段
for i in {1..513}; do
    HSET large:hash field$i "value$i"
done
OBJECT ENCODING large:hash
# 返回: "hashtable"

应用场景

1. 用户信息存储

Bash
# 存储用户对象
HSET user:1000 name "Alice" age 25 city "Beijing" email "alice@example.com"

# 获取单个字段
HGET user:1000 name

# 获取多个字段
HMGET user:1000 name age city

# 获取全部信息
HGETALL user:1000

# 更新字段
HSET user:1000 age 26

2. 商品属性存储

Bash
# 存储商品属性
HSET product:1001 name "iPhone" price "999" stock "100" category "phone"

# 查询价格
HGET product:1001 price

# 库存增加
HINCRBY product:1001 stock -1

3. 购物车

Bash
# 添加商品到购物车
HSET cart:user:1000 product:1001 2 product:1002 1

# 获取购物车
HGETALL cart:user:1000

# 更新数量
HINCRBY cart:user:1000 product:1001 1

# 移除商品
HDEL cart:user:1000 product:1002

4. 配置信息

text
# 存储系统配置
HSET config:system timeout 30 maxconn 1000 mode "production"

# 获取配置
HGET config:system timeout

# 更新配置
HSET config:system timeout 60

与String对比

存储对象对比

text
# 方式1:String存储JSON
SET user:1000 '{"name":"Alice","age":25,"city":"Beijing"}'
GET user:1000
# 更新需读取-修改-写入

# 方式2:Hash存储对象
HSET user:1000 name "Alice" age 25 city "Beijing"
HGET user:1000 name
HSET user:1000 age 26
# 单字段更新高效

对比表

特性String(JSON)Hash
存储格式JSON字符串field-value
单字段更新低效(全量)高效(单字段)
内存占用较小(紧凑)可能较大
部分获取需解析JSON直接获取
适用场景整体读写多部分读写多

需频繁更新单字段时用Hash,整体读写用String。

内存优化

ziplist优势

text
- 连续内存,无指针开销
- 字段少时内存效率高
- 配置阈值可调整

优化建议

text
# 调整阈值
hash-max-ziplist-entries 1000  # 增大字段上限
hash-max-ziplist-value 128     # 增大value长度上限
# 延迟转换,保持ziplist编码

字段命名

text
- 使用短字段名:n而非name
- 减少字符串长度
- 节省内存空间

操作特点

O(1)操作

text
HSET/HGET:设置/获取单字段
HDEL:删除字段
HINCRBY:数值增减
HEXISTS:检查存在
HLEN:字段数量

O(N)操作

text
HGETALL:获取全部字段
HKEYS/HVALS:获取全部键或值
HMGET/HMSET:批量操作
# N为字段数量

注意事项

内存转换

text
ziplist转hashtable后内存增加
大量字段时考虑内存开销
可调整阈值控制转换时机

字段数量

text
# 大量字段时HGETALL性能下降
# 建议使用HSCAN遍历
HSCAN large:hash 0

哈希冲突

text
hashtable编码下存在哈希冲突
Redis采用链地址法解决
渐进式rehash扩容

编码对比

编码条件内存效率查找效率适用场景
ziplist≤512字段且≤64字节O(N)小对象
hashtable>512字段或>64字节O(1)大对象

要点总结

  • 哈希适合存储对象结构,一个key下多个field-value
  • ziplist编码适合小数据(≤512字段,≤64字节value)
  • hashtable编码适合大数据,O(1)查找
  • 单字段更新用Hash比String(JSON)更高效
  • 应用场景:用户信息、商品属性、购物车、配置信息
  • HINCRBY原子增减数值,适合计数统计
  • 大量字段时使用HSCAN遍历,避免HGETALL阻塞
  • 调整hash-max-ziplist-entries/value可优化内存

📝 发现内容有误?点击此处直接编辑

← 上一篇 Redis列表
下一篇 → Redis字符串
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库