admin管理员组

文章数量:1037775

【redis】hash 类型应用场景

作为缓存

使用 string 也是可以作为缓存使用的。存储结构化数据,使用 hash 类型更适合一些

关系型数据表保存用户信息

image.png

映射关系表示用户信息

image.png

上述场景使用 string 类型也能做到,就是需要使用 JSON 这样的数据格式

伪代码实现

代码语言:javascript代码运行次数:0运行复制
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 whiere uid = <uid>
	
	// 如果列表中没有 uid 对应的用户信息
	if(userInfo == null) {
		响应404
		return null;
	}
}

缓存方式对比

如果使用 stringJSON )的格式来表示 UserInfo。万一只想获取其中的某个 field,或者修改某个 field 的时候,就需要把整个 JSON 都读出来,解析成对象,操作 field,再重新转成 JSON 字符,再写回去

如果使用 hash 的方式来表示 UserInfo,就可以使用 field 表示对象的每个属性(数据表的每个列),此时就可以非常方便的修改/获取任何一个属性的值了


使用 hash 的方式,确实读写 field 更直观高效,但是付出的是空间的代价

  • 需要控制哈希在 ziplisthashtable 两种内部编码的转换,可能会造成内存的较大消耗
  • 具体操作还是看需求,是更关注速度,时间上的(hash);还是内存,空间上的(string

到目前位置,我们能够使用三种方法缓存用户信息,还有一种原生字符串类型——使用字符串类型,每个属性一个键

代码语言:javascript代码运行次数:0运行复制
set user:1:name James
set user:1:age 23
set user:1:city BJ
  • 这种方式,一般不推荐使用。相当于把同一个数据的各个属性,给分散开了,低内聚

我们在写代码/管理数据,更追求的是高内聚

  • 内聚:把有关联的东西放在一起,最好能放在指定的地方(好找)
  • 耦合:两个模块/代码之间的关联关系,关联关系越大,越容易相互影响,认为耦合越大。
    • 追求的是“低耦合”,避免“牵一发而动全身”,这边一改出 bug,就影响到了其他地方

  • 哈希类型是稀疏的,而关系型数据库是完全结构化的,例如哈希类型每个键可以有不同的 field,而关系型数据库一旦添加新的列,所有行都要为期设置值,即使为 null
  • 关系数据库可以做复杂的关系查询,而 Redis 去模拟关系型复杂查询,例如联表查询、聚合查询等基本不可能,维护成本高
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-03-12,如有侵权请联系 cloudcommunity@tencent 删除内存缓存hashredis对象

【redis】hash 类型应用场景

作为缓存

使用 string 也是可以作为缓存使用的。存储结构化数据,使用 hash 类型更适合一些

关系型数据表保存用户信息

image.png

映射关系表示用户信息

image.png

上述场景使用 string 类型也能做到,就是需要使用 JSON 这样的数据格式

伪代码实现

代码语言:javascript代码运行次数:0运行复制
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 whiere uid = <uid>
	
	// 如果列表中没有 uid 对应的用户信息
	if(userInfo == null) {
		响应404
		return null;
	}
}

缓存方式对比

如果使用 stringJSON )的格式来表示 UserInfo。万一只想获取其中的某个 field,或者修改某个 field 的时候,就需要把整个 JSON 都读出来,解析成对象,操作 field,再重新转成 JSON 字符,再写回去

如果使用 hash 的方式来表示 UserInfo,就可以使用 field 表示对象的每个属性(数据表的每个列),此时就可以非常方便的修改/获取任何一个属性的值了


使用 hash 的方式,确实读写 field 更直观高效,但是付出的是空间的代价

  • 需要控制哈希在 ziplisthashtable 两种内部编码的转换,可能会造成内存的较大消耗
  • 具体操作还是看需求,是更关注速度,时间上的(hash);还是内存,空间上的(string

到目前位置,我们能够使用三种方法缓存用户信息,还有一种原生字符串类型——使用字符串类型,每个属性一个键

代码语言:javascript代码运行次数:0运行复制
set user:1:name James
set user:1:age 23
set user:1:city BJ
  • 这种方式,一般不推荐使用。相当于把同一个数据的各个属性,给分散开了,低内聚

我们在写代码/管理数据,更追求的是高内聚

  • 内聚:把有关联的东西放在一起,最好能放在指定的地方(好找)
  • 耦合:两个模块/代码之间的关联关系,关联关系越大,越容易相互影响,认为耦合越大。
    • 追求的是“低耦合”,避免“牵一发而动全身”,这边一改出 bug,就影响到了其他地方

  • 哈希类型是稀疏的,而关系型数据库是完全结构化的,例如哈希类型每个键可以有不同的 field,而关系型数据库一旦添加新的列,所有行都要为期设置值,即使为 null
  • 关系数据库可以做复杂的关系查询,而 Redis 去模拟关系型复杂查询,例如联表查询、聚合查询等基本不可能,维护成本高
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-03-12,如有侵权请联系 cloudcommunity@tencent 删除内存缓存hashredis对象

本文标签: redishash 类型应用场景