Hash
一、Hash 类型概述
Redis 的 Hash 是一个 字段值对(field-value pairs)的集合,是一个 string 类型的 field 和 value 的映射表。它特别适合用于存储对象。
类比理解:可以把它看作 PHP 中的关联数组、Python 中的字典、Java 中的 HashMap>。key-field-value
二、基本方法
- 基本操作
bash
127.0.0.1:6379> hset map num 1 num 2 #设置hash字段的值,可以重复设置,但是会被顶掉
(integer) 1
127.0.0.1:6379> hget map num #获取值
"2"
127.0.0.1:6379> hset map count 1 num 3 #可以设置多个
(integer) 1
127.0.0.1:6379> hget map count
"1"
127.0.0.1:6379> hget map num
"3"
127.0.0.1:6379> hdel map num #删除字段
(integer) 1
127.0.0.1:6379> hexists map num #查询字段是否存在
(integer) 0
127.0.0.1:6379> hlen map #查询字段个数
(integer) 1
- 批量操作
bash
127.0.0.1:6379> hset map k1 v1 k2 v2 k3 v3 #批量写入
(integer) 3
127.0.0.1:6379> hmget map k1 k2 k3 #批量查询
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> hgetall map #获取所有的字段及其对应值
1) "k1"
2) "v1"
3) "k2"
4) "v2"
5) "k3"
6) "v3"
127.0.0.1:6379> hkeys map #获取所有的字段
1) "k1"
2) "k2"
3) "k3"
127.0.0.1:6379> hvals map #获取所有的值
1) "v1"
2) "v2"
3) "v3"
- 数字操作
bash
127.0.0.1:6379> hset map num 1
(integer) 1
127.0.0.1:6379> hincrby map num 4 #为哈希字段的整数值加上增量
(integer) 5
127.0.0.1:6379> hincrbyfloat map num 0.1 #为哈希字段的浮点数值加上增量
"5.1"
127.0.0.1:6379> hincrby map num 1 #整数能加浮点数,浮点数不能加整数
(error) ERR hash value is not an integer
三、内部实现
Hash 的底层实现根据字段数量和值的大小自动选择:
-
ziplist
(压缩列表) :- 当哈希类型元素个数小于
hash-max-ziplist-entries
配置(默认 512),同时所有值都小于hash-max-ziplist-value
配置(默认 64 字节)时使用 - 内存紧凑,适合小哈希对象
- 当哈希类型元素个数小于
-
hashtable
(哈希表) :- 当不满足 ziplist 条件时使用
- 查询效率稳定,适合大哈希对象
四、Hash 类型的应用场景
存储对象信息 :最经典的用法。将对象属性存储为哈希字段,可以单独操作对象的某个字段而无需序列化整个对象。例如:HSET user:1001 name "Alice" age 30 email "alice@example.com"
。
购物车系统 :利用 Hash 存储用户的购物车商品信息,字段为商品ID,值为商品数量和规格。通过 HINCRBY
实现商品数量的增减,通过 HDEL
删除商品。
计数器组 :存储多个相关的计数器,如文章的阅读数、点赞数、收藏数、评论数等。通过 HINCRBY
原子性操作保证数据一致性,避免多个独立 key 的管理开销。
配置信息管理 :存储应用的系统配置、用户个性化设置等。可以单独修改某个配置项而不影响其他配置,通过 HGETALL
获取全部配置。
会话存储:存储用户会话信息,可以单独更新会话中的某个属性(如最后活动时间),比整个会话序列化存储更高效灵活。