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

Redis:hash类型详解

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

Redis:hash类型详解

引用
CSDN
1.
https://blog.csdn.net/fsdfafsdsd/article/details/142694302

Redis的hash类型是一种非常实用的数据结构,它允许在一个键中存储多个字段和值的映射关系。本文将详细介绍hash类型的命令、应用场景以及其内部编码机制,帮助开发者更好地理解和使用这一功能。

Redis:hash类型

在主流的编程语言中,几乎都提供了哈希表相关的容器,Redis自然也会支持对应的内容,以满足程序员的需求。例如,如果要存储一个用户的姓名和年龄的映射关系,只使用string类型的话,需要为每个用户设置不同的key,如下图所示:

此时Redis的key放对应的名称,value放对应的值。但是要注意的是,为了区分不同用户,要加上一些前缀来对key命名,比如user1:name,user2:name,这会比较麻烦。

如果支持了哈希结构:

此时value内部存储的是哈希表结构,相当于嵌套了两层映射关系。为了不搞混Redis本身的key和哈希表内部的key,所以哈希内部的键称为field。

hash命令

设置与读取

HSET

  • 设置hash中指定字段field和值value
hset key field value [field value ...]

返回值是设置成功的filed-value键值对的个数。

示例:第一次创建了一个哈希表hash1,设置了两个键值对f1-111、f2-222,返回2。第二次设置同一张哈希表,由于f1和f2已经存在了,只设置成功了f3,所以返回1。

HGET

  • 获取hash中指定filed的值
hget key field

返回对应字段的value,如果key或者field不存在,返回nil。

示例:

HMGET

  • 一次获取hash中多个字段的值
hget key field [field ...]

返回所有field对应的value,如果key或者field不存在,返回nil。

示例中,name和age都是存在的字段,返回了对应的值,而address不存在,返回nil。另外的,还有与hmget对应的hmset,可以一次设置多个哈希键值对,但是hset本身就支持设置多个哈希键值对,所以没必要。

HSETNX

  • 在字段不存在的情况下,设置hash中的字段和值
hsetnx key field value

如果field已经存在,那么此次设置失败,返回0表示设置失败,返回1表示设置成功。

第一次设置user name失败,因为name字段已经存在,第二次user friend设置成功,因为原先不存在该field。

哈希操作

HEXISTS

  • 判断hash中是否有指定的field
hexists key field

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

示例:

HDEL

  • 删除hash中的filed字段
hdel key field [field ...]

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

示例:第一次删除了f3,返回1。第二次删除了f1和f2,返回2。如果使用del,而不是hdel,那么删除的是整张哈希表。

HKEYS

  • 获取hash中的所有field
hkeys key

返回所有的field。

示例:

HVALS

  • 获取hash中的所有value
hvals key

返回所有的value。

示例:

HGETALL

  • 获取hash中所有的field和value
hgetall key

返回所有的field以及对应的value。从上往下以field_1、value_1、field_2、value_2、field_3、value_3的顺序输出。

HLEN

  • 获取hash中所有字段的个数
hlen key

返回field个数。要注意的是,这个操作时间复杂度是O(1),Redis不会去遍历哈希表,而是有专门的变量维护哈希表的大小,需要时直接读取变量即可。

HINCRBY

  • 把hash的指定的field对应的value增加指定值
hincrby key field increment

因为hash内部的value还是一个string,而string可以存储整数,也就可以支持算数操作了。与incrby一样,支持正负数,如果不存在那么视为数字0,最后返回变化后的值。

示例:示例中,user包含name、age、email字段,第一次对age自增2。第二次自增一个不存在的键id,此时id默认视为0。

HINCRBYFLOAT

  • 把hash的指定的field对应的value增加指定浮点值
hincrbyfloat key field increment

与incrbyfloat一样,支持正负数,如果不存在那么视为数字0,最后返回变化后的值。

总结:

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

内部编码

hash内部编码格式包含两种:ziplist和hashtable。

ziplist

压缩列表是一种内存紧凑的存储方式,适合存储数量较少且元素较小的哈希。具体来说,当hash类型的元素个数小于hash-max-ziplist-entries(默认 512 个),并且所有值的长度都小于hash-max-ziplist-value(默认 64 字节)时,Redis会使用ziplist作为哈希的内部实现。这些配置在/etc/redis/redis.conf内修改。

优点:

  1. 内存节省:ziplist使用连续的内存块来存储数据,这种紧凑的存储方式可以有效地减少内存碎片和开销。
  2. 结构简单:适合小规模数据,尤其是在内存资源有限的情况下。

缺点:

  1. 操作效率:随着数据量的增加,ziplist的读写效率会下降。尤其是在需要频繁更新的场景中,ziplist的线性查找特性使得操作复杂度较高。
  2. 扩展性差:不适合大规模数据存储。

hashtable

当哈希类型无法满足ziplist的条件时,Redis会自动切换到使用哈希表作为哈希的内部实现。

优点:

  1. 高效的读写:哈希表的读写时间复杂度为O(1),即使在数据量较大时也能保证高效的访问。
  2. 良好的扩展性:适合存储大量数据和需要频繁更新的场景。

缺点:

  1. 内存占用:相较于ziplist,哈希表在内存使用上相对较多,特别是在存储小数据集时,内存开销更为显著。
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号