【redis】哈希类型详解

哈希类型详解

一、哈希类型的介绍

⼏乎所有的主流编程语⾔都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数组、映射。在 Redis 中,哈希类型是指值本⾝⼜是⼀个键值对结构,形如 key = "key",value = { { field1, value1 }, ..., {fieldN, valueN } },Redis 键值对和哈希类型⼆者的关系可以⽤下图表示

字符串和哈希类型对⽐ :

哈希类型中的映射关系通常称为 field-value,⽤于区分 Redis 整体的键值对(key-value),注意这⾥的 value 是指 field 对应的值,不是键(key)对应的值,请注意 value 在不同上下⽂的作⽤

二、哈希类型的常用命令

2.1 HSET

设置 hash 中指定的字段(field)的值(value)

语法:

r 复制代码
HSET key field value [field value ...]

返回值:添加的字段的个数

使用示例:

r 复制代码
127.0.0.1:6379> hset key field 'hello'
(integer) 1
127.0.0.1:6379> hget key field
"hello"

2.2 HGET

获取 hash 中指定字段的值

语法:

r 复制代码
HGET key field

返回值:字段对应的值或者 nil

使用示例:

r 复制代码
127.0.0.1:6379> hset key field 'foo'
(integer) 1
127.0.0.1:6379> hget key field
"foo"
127.0.0.1:6379> hget key field1
(nil)

2.3 HEXISTS

判断 hash 中是否有指定的字段

语法:

r 复制代码
HEXISTS key field

返回值:1 表⽰存在,0 表⽰不存在

使用示例:

r 复制代码
127.0.0.1:6379> hset key field 'foo'
(integer) 1
127.0.0.1:6379> hexists key field
(integer) 1
127.0.0.1:6379> hexists key field1
(integer) 0

2.4 HDEL

删除 hash 中指定的字段

语法:

r 复制代码
HDEL key field [field ...]

返回值:本次操作删除的字段个数

使用示例:

r 复制代码
127.0.0.1:6379> hset key field 'foo'
(integer) 1
127.0.0.1:6379> hdel key field
(integer) 1
127.0.0.1:6379> hdel key field1
(integer) 0

2.5 HKEYS

获取 hash 中的所有字段

语法:

r 复制代码
HKEYS key

返回值:字段列表

使用示例:

r 复制代码
27.0.0.1:6379> hset key field 'hello'
(integer) 1
127.0.0.1:6379> hset key field2 'world'
(integer) 1
127.0.0.1:6379> hkeys key
1) "field"
2) "field2"

2.6 HAVLS

获取 hash 中的所有的值

语法:

r 复制代码
HVALS key

返回值:所有的值

使用示例:

r 复制代码
127.0.0.1:6379> hset key field 'hello'
(integer) 1
127.0.0.1:6379> hset key field2 'world'
(integer) 1
127.0.0.1:6379> hvals key
1) "hello"
2) "world"

2.7 HGETALL

获取 hash 中的所有字段以及对应的值

语法:

r 复制代码
HGETALL key

返回值:字段和对应的值

使用示例:

r 复制代码
127.0.0.1:6379> hset key field 'hello'
(integer) 1
127.0.0.1:6379> hset key field2 'world'
(integer) 1
127.0.0.1:6379> hgetall key
1) "field"
2) "hello"
3) "field2"
4) "world"

在使⽤ HGETALL 时,如果哈希元素个数⽐较多,会存在阻塞 Redis 的可能。如果开发⼈员只需要获取部分 field,可以使⽤ HMGET,如果⼀定要获取全部 field,可以尝试使⽤ HSCAN 命令,该命令采⽤渐进式遍历哈希类型,HSCAN 会在后续介绍

2.8 HMGET

⼀次获取 hash 中多个字段的值

语法:

r 复制代码
HMGET key field [field ...]

返回值:字段对应的值或者 nil

使用示例:

r 复制代码
127.0.0.1:6379> hset key field 'hello'
(integer) 1
127.0.0.1:6379> hset key field2 'world'
(integer) 1
127.0.0.1:6379> hmget key field field2 nofield
1) "hello"
2) "world"
3) (nil)

2.9 HLEN

获取 hash 中的所有字段的个数

语法:

r 复制代码
HLEN key

返回值:字段个数

使用示例:

r 复制代码
127.0.0.1:6379> hset key field 'hello'
(integer) 1
127.0.0.1:6379> hset key field2 'world'
(integer) 1
127.0.0.1:6379> hlen key
(integer) 2

2.10 HSETNX

在字段不存在的情况下,设置 hash 中的字段和值

语法:

r 复制代码
HSETNX key field value

返回值:1 表⽰设置成功,0 表⽰失败

使用示例:

r 复制代码
127.0.0.1:6379> hsetnx key field 'hello'
(integer) 1
127.0.0.1:6379> hsetnx key field 'world'
(integer) 0
127.0.0.1:6379> hget key field
"hello"

2.11 HINCRBY

将 hash 中字段对应的数值添加指定的值

语法:

r 复制代码
HINCRBY key field increment

返回值:该字段变化之后的值

使用示例:

r 复制代码
127.0.0.1:6379> hset key field 5
(integer) 1
127.0.0.1:6379> hincrby key field 1
(integer) 6
127.0.0.1:6379> hincrby key field -1
(integer) 5
127.0.0.1:6379> hincrby key field -10
(integer) -5

2.12 HINCRBYFLOAT

HINCRBY 的浮点数版本

语法:

r 复制代码
HINCRBYFLOAT key field increment

返回值:该字段变化之后的值

使用示例:

r 复制代码
127.0.0.1:6379> hset key field 10.00
(integer) 1
127.0.0.1:6379> hincrbyfloat key field 0.1
"10.1"
127.0.0.1:6379> hincrbyfloat key field -5
"5.1"
127.0.0.1:6379> hset key field 5.0e3
(integer) 0
127.0.0.1:6379> hincrbyfloat key field 2.0e2
"5200"

三、哈希类型命令小结

命令 执⾏效果 时间复杂度
hset key field value 设置值 O(1)
hget key field 获取值 O(1)
hdel key field [field ...] 删除 field O(k), k 是 field 个数
hlen key 计算 field 个数 O(1)
hgetall key 获取所有的 field-value O(k), k 是 field 个数
hmget field [field ...] 批量获取 field-value O(k), k 是 field 个数
hmset field value [field value ...] 批量获取 field-value O(k), k 是 field 个数
hexists key field 判断 field 是否存在 O(1)
hkeys key 获取所有的 field O(k), k 是 field 个数
hvals key 获取所有的 value O(k), k 是 field 个数
hsetnx key field value 设置值,但必须在 field 不存在时才能设置成功 O(1)
hincrby key field n 对应 field-value +n O(1)
hincrbyfloat key field n 对应 field-value +n O(1)
hstrlen key field 计算 value 的字符串⻓度 O(1)

四、哈希类型内部编码

哈希的内部编码有两种:

  • ziplist(压缩列表):当哈希类型元素个数⼩于 hash-max-ziplist-entries 配置(默认 512 个),同时所有值都⼩于 hash-max-ziplist-value 配置(默认 64 字节)时,Redis 会使⽤ ziplist 作为哈希的内部实现,ziplist 使⽤更加紧凑的结构实现多个元素的连续存储,所以在节省内存⽅⾯⽐ hashtable 更加优秀
  • hashtable(哈希表):当哈希类型⽆法满⾜ ziplist 的条件时,Redis 会使⽤ hashtable 作为哈希的内部实现,因为此时 ziplist 的读写效率会下降,⽽ hashtable 的读写时间复杂度为 O(1)

hash-max-ziplist-entries :这个参数用于设置压缩列表可以存储的最大节点数量。如果一个 Hash 类型的元素数量超过这个值,那么就会从压缩列表切换到散列表。默认值为 512

hash-max-ziplist-value:这个参数用于设置压缩列表中每个节点的最大值大小(以字节为单位)。如果一个 Hash 类型的任何元素的大小超过这个值,那么就会从压缩列表切换到哈希表。默认值为 64

从压缩列表转换到哈希表的条件:当 Hash 类型存储的字段和值的数量超过 hash-max-ziplist-entries 的值,或者任何字段或值的大小超过 hash-max-ziplist-value 的值时,Redis 会将底层结构从压缩列表转换为哈希表。这个过程是自动进行的,对用户来说是透明的,压缩列表转换为哈希表是单向的,不可逆

下面演示这两种类型:

①当 field 个数⽐较少且没有⼤的 value 时,内部编码为 ziplist:

r 复制代码
127.0.0.1:6379> hmset hashkey f1 v1 f2 v2
OK
//查看哈希内部编码类型
127.0.0.1:6379> object encoding hashkey
"ziplist"

②当有 value ⼤于 64 字节时,内部编码会转换为 hashtable:

r 复制代码
127.0.0.1:6379> hset hashkey f3 "one string is bigger than 64 bytes ... "
OK
127.0.0.1:6379> object encoding hashkey
"hashtable"

③当 field 个数超过 512 时,内部编码也会转换为 hashtable:

r 复制代码
127.0.0.1:6379> hmset hashkey f1 v1 h2 v2 f3 v3 ... 省略 ... f513 v513
OK
127.0.0.1:6379> object encoding hashkey
"hashtable"

五、哈希类型应用场景

Redis 的 Hash 类型是一种键值对集合,适合用于存储对象,因此在很多场景下都有着广泛的应用。以下是一些常见的应用场景:

  1. 存储对象:Hash 类型可以存储多个键值对,非常适合用于存储对象。例如,你可以使用 Hash 类型存储用户的信息,如用户名、密码、邮箱等;
  2. 数据分析:你可以使用 Hash 类型存储各种统计数据,例如用户的行为数据,然后进行数据分析;
  3. 社交网络:在社交网络应用中,你可以使用 Hash 类型存储用户的朋友列表、粉丝列表等
相关推荐
IvorySQL3 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·3 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
IT邦德4 小时前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫4 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i4 小时前
完全卸载MariaDB
数据库·mariadb
期待のcode4 小时前
Redis的主从复制与集群
运维·服务器·redis
纤纡.4 小时前
Linux中SQL 从基础到进阶:五大分类详解与表结构操作(ALTER/DROP)全攻略
linux·数据库·sql
jiunian_cn4 小时前
【Redis】渐进式遍历
数据库·redis·缓存
橙露5 小时前
Spring Boot 核心原理:自动配置机制与自定义 Starter 开发
java·数据库·spring boot
冰暮流星5 小时前
sql语言之分组语句group by
java·数据库·sql