哈希与字符串存对象怎么选
存一个业务对象有两条路:拆成哈希字段,或整体序列化成字符串。哈希支持按字段读写与增量更新,字段数量不多时内存更省;字符串适合整体读写、跨语言处理简单,过期也只能是整键级别。选型看访问模式:是否频繁改单个字段、是否需要精细过期。
基本信息
| 哈希写入 | HSET 单字段或批量,字段不存在即新增 |
|---|---|
| 哈希增量 | HINCRBY 与 HINCRBYFLOAT 在字段上做原子加减 |
| 字符串写入 | SET 整体覆盖,读写都是整个对象 |
| 过期粒度 | 两者都是键级过期;字段级过期需要较新版本支持 |
| 编码影响 | 字段与体积较小时哈希使用紧凑编码,超出后转为哈希表编码 |
典型使用场景
- 高频改单个字段:状态、计数、在线标记等用哈希最合适
- 整体读写的配置对象:一次读入内存即用,字符串更省心
- 跨语言共享:字符串加通用序列化格式最容易被各语言处理
- 需要整体过期:会话类数据整体失效时字符串写法更直接
- 字段较多但只取部分:哈希能按需读取,避免整体反序列化
两种写法
两种写法
# 哈希:按字段读写与增量
HSET user:1001 name 张三 age 30
HINCRBY user:1001 age 1
HGET user:1001 name
HMGET user:1001 name age
# 字符串:整体读写,适合直接序列化
SET user:1001:json '{"name":"张三","age":31}' EX 3600
GET user:1001:json
# 对比体积与编码方式
MEMORY USAGE user:1001
OBJECT ENCODING user:1001两种结构对比
| 维度 | 哈希 | 字符串 |
|---|---|---|
| 部分更新 | 支持,只写改动字段 | 不支持,需整体重写 |
| 内存占用 | 小哈希更紧凑 | 整体序列化含冗余字段名 |
| 过期粒度 | 键级,字段级需较新版本 | 键级 |
| 跨语言 | 需要支持字段操作 | 任意语言都能处理 |
| 原子计数 | 支持字段级加减 | 需要整体读改写 |
并发下用字符串存对象很容易出现「读改写」覆盖:两个请求同时更新不同字段,后写的一方会覆盖前者的修改。
把超大对象塞进单个字段:编码退化后每个字段都有额外开销,也会变成大键隐患。