问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Redis - hash 哈希表

创作时间:
作者:
@小白创作中心

Redis - hash 哈希表

引用
CSDN
1.
https://blog.csdn.net/q322359/article/details/136858513

Redis的哈希表(hash)数据类型是一种非常实用的数据结构,它允许用户存储键值对的集合。本文将详细介绍Redis哈希表的各种命令、内部编码机制以及实际应用场景,帮助读者全面理解这一重要的数据类型。

前言

几乎所有的主流编程语言都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数组、映射。在 Redis 中,哈希类型是指 value 本身又是 一个键值对结构,形如 key = "key",value = { { field1, value1 }, ..., {fieldN, valueN } },是嵌套的哈希表

哈希类型中的映射关系通常称为field-value,用于区分 Redis 整体的键值对(key-value), 注意这里的 value 是指 field 对应的值,不是键(key)对应的值

命令

以下 H 系列的命令必须要保证 key 对应的 value 得是 hash 类型的

HSET 设置哈希中的 field - value

语法


HSET key field value [field value ...]

时间复杂度:插入一组 field 为 O(1), 插入 N 组 field 为 O(N)

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

HGET 获取 hash 中指定字段的值

语法


HGET key field

时间复杂度:O(1)

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

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

语法


HEXISTS key field

时间复杂度:O(1)

返回值:1 表示存在,0 表示不存在。

HDEL 删除 hash 中指定的字段

语法


HDEL key field [field ...]

时间复杂度:删除一个元素为O(1).删除 N 个元素为 O(N).

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

HKEYS 获取 hash 中的所有字段

语法


HKEYS key

时间复杂度:O(N)

N 为 field 的个数.返回值:字段列表。

这个操作,先根据 key 找到对应的 hash ,然后再遍历这个 hash 表,由于会遍历并打印出 hash 表中的全部内容,而我们并不知道 hash 表中有多少内容,所以这个操作是有一定风险的,如果 hash 表中的数据较多,就会导致该命令执行很长的一段时间,而 redis 是单线程的程序,就会造成阻塞,并且后面的 HVALS,HGETALL都存在这样的风险

HVALS 获取 hash 中的所有的值

语法


HVALS key

时间复杂度:O(N), N 为 field 的个数

返回值:所有的 value 值。

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

语法


HGETALL key

时间复杂度:O(N), N 为 field 的个数

返回值:字段和对应的值。

HMGET 一次获取 hash 中多个字段的值

语法


HMGET key field [field ...]

时间复杂度:只查询一个元素为 O(1), 查询多个元素为 O(N), N 为查询元素个数.

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

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

语法


 HLEN key

时间复杂度:O(1),redis 使用变量保存了 hash 表中的字段个数

返回值:字段个数

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

可以理解为 “创建” 只有不存在才能创建,存在就创建失败

语法


HSETNX key field value

时间复杂度:O(1)

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

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

语法


HINCRBY key field increment

时间复杂度:O(1)

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

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

语法


HINCRBYFLOAT key field increment

时间复杂度: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)。

简单总结:当哈希表中的键值对个数较少,每个键值对值 value 的长度较短时,哈希的内部编码采用的就是 ziplist(压缩列表) ,而较少和较短的边界值就要看具体的配置,使用 ziplist (压缩列表)相比于 hashtable 要节省很大的空间,但相对的读取数据的速度较慢,尤其当数据较多或者 value 值较长时会很明显,所以当数据较多或 value 值较长时会将内部编码从 ziplist(压缩列表)改为 hashtable(哈希表)

使用场景

通常采用 hash 类型来保存对象的相关属性信息,比如关系型数据库中保存了以下的用户信息
可以将其保存到 redis 中,value 的类型是 hash

相比较使用 JSON 格式的字符串缓存用户信息,哈希类型变得更加直观,并且在更新操作上变得更灵活。可以将每个用户的 id 定义为键后缀,多对 field-value 对应用户的各个属性

要注意哈希类型和关系型数据库有两点不同之处

• 哈希类型是稀疏的,而关系型数据库是完全结构化的,例如哈希类型每个键可以有不同的 field,而关系型数据库一旦添加新的列,所有行都要为其设置值,即使为 null

• 关系数据库可以做复杂的关系查询,而 Redis 去模拟关系型复杂查询,例如联表查询、聚合查询等基本不可能,维护成本高。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号