Redis:Hash 类型 内部实现、命令及应用场景
Hash(哈希)类型是一种键值对key-value
的集合,其中每个键值对被称为一个字段(field)和值(value),可以将其看作是一个微型的数据库,它以高效的方式存储和操作多个相关的数据项。
内部实现
压缩列表(ziplist)
- 结构:这是一种紧凑的连续内存块结构。它将 Hash 中的键值对依次存储,每个节点包含前一个节点的长度、当前节点的长度和节点值。在内存中键和值交替存放。
- 适用场景:适用于存储元素较少且键值对长度较短的 Hash。当 Hash 对象的键值对数量较少,且键和值的长度都比较小时,使用压缩列表可以节省大量内存。
- 优点:内存利用率高,避免了指针带来的额外开销。
- 缺点:是插入和删除操作可能需要移动大量数据,时间复杂度为 O (n),在元素较多时性能会下降。
在Redis7.0中,压缩列表数据结构已经废弃,交由
listpack
数据结构来实现了。
紧凑列表(Listpack)
- 结构:一种改进型压缩列表。它同样是连续内存块结构,每个节点包含自身长度和数据内容,但去除了压缩列表中记录前一个节点长度的字段,使结构更加紧凑。
- 适用场景:用于替代压缩列表,在存储小数据量的 Hash 时能提供更好的性能和内存使用效率。
- 优点:优点是内存使用更高效,插入和删除操作的性能有所提升。
- 缺点:相较于哈希表,在处理大规模数据时,整体操作性能可能稍逊一筹。

哈希表(hashtable)
- 结构:采用数组和链表(或红黑树)结合的方式。数组中的每个元素是一个桶,当多个键值对的哈希值冲突时,它们会以链表或红黑树的形式存储在同一个桶中。当链表长度超过一定阈值,链表会转换为红黑树。
- 适用场景:适合存储大量元素的 Hash。无论 Hash 中的元素数量多少,哈希表都能提供较为稳定的查找、插入和删除操作性能。
- 优点:优点是查找、插入和删除操作的平均时间复杂度为 O (1),能高效处理大数据量。
- 缺点:需要额外的内存来存储指针和维护哈希表结构,当元素较少时,内存开销相对较大。
常用命令
添加
HSET / HMSET
hset/hmset key field value [field value ...]
- 设置
hash
中指定字段field
和值value
,若字段为新增返回 1,若更新已有字段值则返回 0。
查找
HGET
hget key field
- 获取
key
对应field
的键值,若字段存在则返回其值,不存在则返回nil
。
HMGET
hget key field [field ...]
- 获取
hash
中多个字段的值,若字段存在则返回对应值,不存在则返回nil
,返回值按请求字段顺序排列。
HEXISTS
hexists key field
- 检查指定
hash
键中是否存在指定field
,若存在返回 1,不存在则返回 0。
HVALS
hvals key
- 获取
hash
中的所有value
。
HGETALL
hgetall key
- 获取
hash
中所有的field
和value
。
HLEN
hlen key
- 获取
hash
中所有字段的数量。
删除
HDEL
hdel key field [field ...]
- 删除
hash
中的filed
字段,返回成功删除的字段数量。
修改
HINCRBY
hincrby key field increment
- 把
hash
的指定的field
对应的value
增加指定值。
HINCRBYFLOAT
hincrbyfloat key field increment
- 把
hash
的指定的field
对应的value
增加指定浮点值。
应用场景
缓存数据:在 Web 应用程序中,经常需要缓存用户的相关信息,如用户名、密码、邮箱、头像等。可以使用用户 ID 作为 Hash 的键,将用户的各项信息作为字段和值存储在 Hash 中。这样,在需要获取用户信息时,只需通过一次 Redis 查询即可获取到所有相关信息,大大提高了查询效率。
购物车功能:在电商网站中,购物车是一个常见的功能。需要存储用户添加到购物车中的商品信息,包括商品 ID、数量、价格等。以用户 ID 为键,每个商品的信息作为一个字段值对存储在 Hash 中。可以使用商品 ID 作为字段名,商品的数量和价格等信息作为值。这样,在用户浏览购物车或结算时,可以快速获取到购物车中的商品信息。