当前位置: 首页 > news >正文

Redis 数据类型 Hash 哈希

在 Redis 中,哈希类型是指值本⾝⼜是⼀个键值对结构,形如 key = "key",value = { { field1, value1 }, ..., {fieldN, valueN } },Redis String 和 Hash 类型⼆者的关系可以⽤下图来表⽰。

Hash 数据类型的特点

  1. 键值对集合:Hash 类型可以存储多个键值对,每个键(field)都有一个对应的值(value)。

  2. 二进制安全:键和值都是二进制安全的,可以包含任何数据,包括二进制数据。

  3. 高效查找:无论 Hash 中存储了多少数据,查找某个键的速度都非常快。

  4. 节省内存:通过将多个相关数据存储在一个键下,减少了键的数量,节省了内存。

内部编码

Redis 的 Hash 数据类型有两种内部编码方式:

  1. 压缩列表(ziplist):当 Hash 中的元素数量较少(默认小于 512 个),且每个值的大小较小(默认小于 64 字节)时,Redis 使用压缩列表来存储 Hash。

  2. 哈希表(hashtable):当 Hash 的大小超过上述阈值时,Redis 会自动切换到哈希表编码。

命令

设置和获取键值

HSET

设置 hash 中指定的字段(field)的值(value)。
语法:
HSET key field value [field value ...]
时间复杂度:插⼊⼀组 field 为 O(1), 插⼊ N 组 field 为 O(N)
返回值:添加的字段的个数。
⽰例:

HGET

获取 hash 中指定字段的值。
语法:
HGET key field
时间复杂度:O(1)
返回值:字段对应的值或者 nil。
⽰例:

HMGET

⼀次获取 hash 中多个字段的值。
语法:
HMGET key field [field ...]
时间复杂度:只查询⼀个元素为 O(1), 查询多个元素为 O(N), N 为查询元素个数.
返回值:字段对应的值或者 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 的个数.
返回值:字段列表。
⽰例:

HVALS

获取 hash 中的所有的值。
语法:
HVALS key
时间复杂度:O(N), N 为 field 的个数.
返回值:所有的值。
⽰例:

HGETALL

获取 hash 中的所有字段以及对应的值。
语法:
GETALL key
时间复杂度:O(N), N 为 field 的个数.
返回值:字段和对应的值。
⽰例:

HLEN

获取 hash 中的所有字段的个数。
语法:
HLEN key
时间复杂度:O(1)
返回值:字段个数。

计数命令

HINCRBY

将 hash 中字段对应的数值添加指定的值。
语法:
HINCRBY key field increment
时间复杂度:O(1)
返回值:该字段变化之后的值。
示例:

HINCRBYFLOAT

HINCRBY 的浮点数版本。
语法: ​​​​​​​
HINCRBYFLOAT key field increment
时间复杂度:O(1)
返回值:该字段变化之后的值。

使用场景

下图为关系型数据表记录的两条⽤⼾信息,⽤⼾的属性表现为表的列,每条⽤⼾信息表现为⾏。
uidnameage
city
1
James28
Beijing
2
Johnathan
30
Xian
相⽐于使⽤ JSON 格式的字符串缓存⽤⼾信息,哈希类型变得更加直观,并且在更新操作上变得更灵活。可以将每个⽤⼾的 id 定义为键后缀,多对 field-value 对应⽤⼾的各个属性,类似如下伪代码:
UserInfo getUserInfo(long uid) {
 // 根据 uid 得到 Redis 的键
 String key = "user:" + uid;
 // 尝试从 Redis 中获取对应的值
 userInfoMap = Redis 执⾏命令:hgetall key;
 // 如果缓存命中(hit)
 if (value != null) {
 // 将映射关系还原为对象形式
 UserInfo userInfo = 利⽤映射关系构建对象(userInfoMap);
 return userInfo;
 }
 // 如果缓存未命中(miss),从数据库中,根据 uid 获取⽤⼾信息
 UserInfo userInfo = MySQL 执⾏ SQL:select * from user_info where uid = <uid>
 // 如果表中没有 uid 对应的⽤⼾信息
 if (userInfo == null) {
 // 响应 404
 return null;
}
 // 将缓存以哈希类型保存
 Redis 执⾏命令:hmset key name userInfo.name age userInfo.age city userInfo.city
 // 写⼊缓存,为了防⽌数据腐烂(rot),设置过期时间为 1 ⼩时(3600 秒)
 Redis 执⾏命令:expire key 3600
 // 返回⽤⼾信息
 return userInfo;
}
但是需要注意的是哈希类型和关系型数据库有两点不同之处:
  • 哈希类型是稀疏的,⽽关系型数据库是完全结构化的,例如哈希类型每个键可以有不同的 field,⽽关系型数据库⼀旦添加新的列,所有⾏都要为其设置值,即使为 null。
  • 关系数据库可以做复杂的关系查询,⽽ Redis 去模拟关系型复杂查询,例如联表查询、聚合查询等基本不可能,维护成本⾼。

相关文章:

  • 海康威视人脸门禁对接开发准备篇
  • 【第4章:循环神经网络(RNN)与长短时记忆网络(LSTM)— 4.3 RNN与LSTM在自然语言处理中的应用案例】
  • docker快速部署oracle11g
  • Unity3D 移动端 CPU 性能调优详解
  • Oracle常用导元数据方法
  • cap4:YoloV5的TensorRT部署指南(python版)
  • Unity 卡死排查方法(游戏死循环、打包卡死)
  • 批量查询linux下可执行程序缺少的依赖
  • ollama离线环境部署deepseek及对话网站开发
  • 思科、华为、H3C常用命令对照表
  • 探索RDMA技术:从基础到实践
  • 机器学习 - 数据的特征表示
  • LLaMA-Factory 安装linux部署使用conda笔记
  • 10.2 Git 内部原理 - Git 对象
  • 基于ollama搭建本地deepseek大模型服务
  • Sentinel
  • 数据库报错1045-Access denied for user ‘root‘@‘localhost‘ (using password: YES)解决方式
  • 【MySQL】索引篇
  • 【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十八节】
  • python 获取smpl身高 fbx身高
  • 明天起,沪苏湖高铁、杭温高铁推出13款新型票制产品
  • 新闻分析:电影关税能“让好莱坞再次伟大”?
  • 外交部:中欧关系50年发展最宝贵经验是相互尊重,求同存异
  • 《中国医药指南》就涉宫颈癌等论文出现男性病例致歉:辞退涉事编辑
  • 缅甸国防军继续延长临时停火期限至5月31日
  • 听炮检书:柳诒徵1927年的选择