Redis哈希数详解

Redis 中哈希结构就如同 Java 的 map 一样,一个对象里面有许多键值对,它是特别适合存储对象的,如果内存足够大,那么一个 Redis 的 hash 结构可以存储 2 的 32 次方减 1 个键值对(40 多亿)。

一般而言,不会使用到那么大的一个键值对,所以我们认为 Redis 可以存储很多的键值对。在 Redis 中,hash 是一个 String 类型的 field 和 value 的映射表,因此我们存储的数据实际在 Redis 内存中都是一个个字符串而已。

假设角色有 3 个字段:编号(id)、角色名称(roleName)和备注(note),这样就可以使用一个 hash 结构保存它,它的内存结果如下表所示。

在这里插入图片描述

在 Redis 中它就是一个这样的结构,其中 role_1 代表的是这个 hash 结构在 Redis 内存的 key,通过它就可以找到这个 hash 结构,而 hash 结构由一系列的 field 和 value 组成,下面用 Redis 的命令来保存角色对象,如下图所示。
在这里插入图片描述

上面的命令保存了一个角色对象。在 Redis 中,角色对象是通过键 role_1 来索引的,而角色本身是一个 hash 结构。hash 的键值对在内存中是一种无序的状态,我们可以通过键找到对应的值。

Redis hash结构命令

在这里插入图片描述

从表中可以看出,在 Redis 中的哈希结构和字符串有着比较明显的不同。

首先,命令都是以 h 开头,代表操作的是 hash 结构。其次,大多数命令多了一个层级 field,这是 hash 结构的一个内部键,也就是说 Redis 需要通过 key 索引到对应的 hash 结构,再通过 field 来确定使用 hash 结构的哪个键值对。

下面通过 Redis 的这些操作命令来展示如何使用它们。
在这里插入图片描述

从图中可以看到,Redis 关于哈希结构的相关命令。这里需要注意的是:

哈希结构的大小,如果哈希结构是个很大的键值对,那么使用它要十分注意,尤其是关于 hkeys、hgetall、hvals 等返回所有哈希结构数据的命令,会造成大量数据的读取。这需要考虑性能和读取数据大小对 JVM 内存的影响。

对于数字的操作命令 hincrby 而言,要求存储的也是整数型的字符串,对于 hincrbyfloat 而言,则要求使用浮点数或者整数,否则命令会失败。

有了上面的描述,读者应该对 hash 结构有了一定的认识,也知道如何使用命令去操作它,现在讨论如何使用 Spring 去操作 Redis 的 hash 结构,由于 Spring 对 Redis 进行了封装,所以有必要对 RedisTemplate 的配置项进行修改。下面先修改 RedisTemplate 的配置,代码如下所示。

<bean id="jdkSerializationRedisSerializer"class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
......
<bean id="stringRedisSerializer"class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"><property name="connectionFactory" ref="connectionFactory" /><property name="defaultSerializer" ref="stringRedisSerializer"/><property name="keySerializer" ref="stringRedisSerializer" /><property name="valueSerializer" ref="jdkSerializationRedisSerializer" />
</bean>

这里把 Spring 提供的 RedisTemplate 的默认序列化器(defaultSerializer)修改为了字符串序列化器。因为在 Spring 对 hash 结构的操作中会涉及 map 等其他类的操作,所以需要明确它的规则。

这里只是指定默认的序列化器,如果想为 hash 结构指定序列化器,可以使用 RedisTemplate 提供的两个属性 hashKeySerializer 和 hashValueSerializer,来为 hash 结构的 field 和 value 指定序列化器。做了这样的修改我们用 Spring 来完成功能,代码如下所示。

public static void testRedisHash()  {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");RedisTemplate redisTemplate =  applicationcontext.getBean(RedisTemplate.class);String key = "hash";Map<String, String> map = new HashMap<String,String>();map.put("f1", "val1");map.put("f2", "val2");// 相当于hmset命令redisTemplate.opsForHash().putAll(key, map);// 相当于hset命令redisTemplate.opsForHash().put(key, "f3", "6");printValueForhash (redisTemplate, key, "f3");// 相当于 hexists key filed 命令boolean exists = redisTemplate.opsForHash().hasKey(key, "f3");System.out.println(exists);// 相当于hgetall命令Map keyValMap = redisTemplate.opsForHash().entries(key);//相当于hincrby命令redisTemplate.opsForHash().increment(key, "f3",2);printValueForhash (redisTemplate, key, "f3");//相当于hincrbyfloat命令redisTemplate.opsForHash().increment (key, "f3", 0.88);printValueForhash(redisTemplate, key, "f3");//相当于hvals命令List valueList = redisTemplate.opsForHash().values(key);//相当于hkeys命令Set keyList = redisTemplate.opsForHash().keys(key);List<String> fieldList = new ArrayList<String>();fieldList.add("f1");fieldList.add("f2");//相当于hmget命令List valueList2 = redisTemplate.opsForHash().multiGet(key, keyList);//相当于hsetnx命令boolean success = redisTemplate.opsForHash () .putlfAbsent(key, "f4", "val4");System.out.println(success);//相当于hdel命令Long result = redisTemplate.opsForHash().delete(key, "fl", "f2");System.out.println(result);   
}
private static void printValueForhash(RedisTemplate redisTemplate,String key,String field) {//相当于hget命令Object value = redisTemplate.opsForHash().get(key,field);System.out.println(value);
}

解说

1 hmset 命令,在 Java 的 API 中,是使用 map 保存多个键值对在先的。

2 hgetall 命令会返回所有的键值对,并保存到一个 map 对象中,如果 hash 结构很大,那么要考虑它对 JVM 的内存影响。

3 hincrby 和 hincrbyFloat 命令都采用 increment 方法,Spring 会识别它具体使用何种方法。

4 redisTemplate.opsForHash().values(key) 方法相当于 hvals 命令,它会返回所有的值,并保存到一个 List 对象中;而 redisTemplate.opsForHash().keys(key) 方法相当于 hkeys 命令,它会获取所有的键,保存到一个 Set 对象中。

5 在 Spring 中使用 redisTemplate.opsForHash().putAll(key,map) 方法相当于执行了 hmset 命令,使用了 map,由于配置了默认的序列化器为字符串,所以它也只会用字符串进行转化,这样才能执行对应的数值加法,如果使用其他序列化器,则后面的命令可能会抛出异常。

6 在使用大的 hash 结构时,需要考虑返回数据的大小,以避免返回太多的数据,引发 JVM 内存溢出或者 Redis 的性能问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/564099.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机专业英语第三章在线测试,《计算机专业英语》第03章在线测试

《计算机专业英语》第03章在线测试 剩余时间&#xff1a; 57:06 答题须知&#xff1a;1、本卷满分20分。 2、答完题后&#xff0c;请一定要单击下面的“交卷”按钮交卷&#xff0c;否则无法记录本试卷的成绩。 3、在交卷之前&#xff0c;不要刷新本网页&#xff0c;否则你的答题…

Redis链表结构深入

链表结构是 Redis 中一个常用的结构&#xff0c;它可以存储多个字符串&#xff0c;而且它是有序的&#xff0c;能够存储 2 的 32 次方减 1 个节点&#xff08;超过 40 亿个节点&#xff09;。 Redis 链表是双向的&#xff0c;因此即可以从左到右&#xff0c;也可以从右到左遍历…

家用使用计算机组装,不能再简单了!家用电脑DIY组装实操

【天极网DIY硬件频道】【天极网硬件频道】近期有网友对DIY组装电脑比较感兴趣&#xff0c;因为自从智能手机和平板电脑横行霸道之后&#xff0c;家中的PC电脑被使用的时间变少了许多&#xff0c;可是偶尔有工作需求或是别有任务等&#xff0c;所以大家依然是不会让电脑远离的。…

Redis集合深入

Redis 的集合不是一个线性结构&#xff0c;而是一个哈希表结构&#xff0c;它的内部会根据 hash 分子来存储和查找数据&#xff0c;理论上一个集合可以存储 2 的 32 次方减 1 个节点&#xff08;大约 42 亿&#xff09;个元素&#xff0c;因为采用哈希表结构&#xff0c;所以对…

达尔豪西大学 计算机科学,达尔豪西大学计算机科学硕士专业.pdf

达尔豪西大学计算机科学硕士专业.pdf留学监理服务网达尔豪西大学计算机科学 - Computer Science基本信息所 达尔豪西大 所属 学 - 在计算机科学学院学 Dalhousie 院校 University 系专 学计算机科学业 历- Computer 硕士名 层Science称 次授 专予 计算机科学 业计算机与信息科学…

Redis有序集合详解

有序集合和集合类似&#xff0c;只是说它是有序的&#xff0c;和无序集合的主要区别在于每一个元素除了值之外&#xff0c;它还会多一个分数。分数是一个浮点数&#xff0c;在 Java 中是使用双精度表示的&#xff0c;根据分数&#xff0c;Redis 就可以支持对分数从小到大或者从…

如何为你的网站启用HTTPS

步骤一&#xff1a;获取SSL/TLS证书 选择SSL证书提供商&#xff1a; 选择一家可信赖的SSL证书提供商。对于小型网站&#xff0c;JoySSL提供的免费证书是一个不错的选择。购买或申请证书&#xff1a; 根据你的网站需求&#xff0c;购买相应类型的SSL证书。证书的类型包括单域、…

紫金计算机网络,南京理工大学紫金学院《计算机网络技术》考试复习题集试题(卷)(含答案解析)2.doc...

一、选择题&#xff1a;(每题2分&#xff0c;共40分)1&#xff0e;在TCP/IP参考模型中&#xff0c;TCP协议工作在( )。A、应用层 B、传输层 C、互联网层 D、网络接口层2&#xff0e;下列( )是合法的E-mail地址。A、mnetwork B、mnetworkC、mnetwork.ecjtu.jxonline D、3&#x…

Redis HyperLogLog常用命令

基数并不是存储元素&#xff0c;存储元素消耗内存空间比较大&#xff0c;而是给某一个有重复元素的数据集合&#xff08;一般是很大的数据集合&#xff09;评估需要的空间单元数&#xff0c;所以它没有办法进行存储&#xff0c;加上在工作中用得不多&#xff0c;我们要介绍一下…

大学计算机课程第六章答案,大学计算机网络课程第六章.ppt

大学计算机网络课程第六章.ppt第6章 文件管理 6.1 文件的概念 6.1 文件的概念 6.1 文件的概念 6.1 文件的概念 6.1 文件的概念 6.1 文件的概念 6.1 文件的概念 6.1 文件的概念 6.1 文件的概念 6.1 文件的概念 6.1 文件的概念 6.2 目录结构 6.2 目录结构 6.2 目录结构 6.2 目录结…

德州计算机速成班培训,德州办公软件培训速成班

德州办公软件培训速成班&#xff1f;公文管理主要负责公文的发送与接收工作&#xff0c;发送流程按照流程定制来完成&#xff0c;所以还包括流程定制功能。这三大块是OA的核心部分&#xff0c;实现也为复杂&#xff0c;特别是流程定制功能&#xff0c;是一个非常灵活的模块&…

Redis的基础事务

Redis 存在事务&#xff0c;尽管它没有数据库那么强大&#xff0c;但是它还是很有用的&#xff0c;尤其是在那些需要高并发的网站当中。 使用 Redis 读/写数据要比数据库快得多&#xff0c;如果使用 Redis 事务在某种场合下去替代数据库事务&#xff0c;则可以在保证数据一致性…

音乐美术计算机在中考,2022年音乐、美术进中考?教育部最新回应...

原标题&#xff1a;2022年音乐、美术进中考&#xff1f;教育部最新回应...国务院日前印发《关于全面加强和改进新时代学校体育工作的意见》和《关于全面加强和改进新时代学校美育工作的意见》。10月16日&#xff0c;在教育部新闻发布会上&#xff0c;教育部体育卫生与艺术教育司…

Redis事务回滚深入

对于 Redis 而言&#xff0c;不单单需要注意其事务处理的过程&#xff0c;其回滚的能力也和数据库不太一样&#xff0c;这也是需要特别注意的一个问题——Redis 事务遇到的命令格式正确而数据类型不符合&#xff0c;如图所示。 从图中可知&#xff0c;我们将 key1 设置为字符串…

计算机辅助设计的发展及应用,计算机辅助设计的发展与应用

计算机维普资讯 http://doc.xuehai.net第 1卷第 34 2、期19 98年 9月株洲工学院学报V 11 o34 o 2N .、 .J OURNAL OF HUZ Z HOU NS TUTE OF TEC I TI HNOL OGY S p 1 9 e .98⑦计算机辅助设计的发展与应用7摘要廖建勇(洲工学院株株洲 420) 1 0 87讨论计算机辅助设计( AD) c技术…

Java 画圆

Java控制台画圆 画空心圆 完整代码&#xff1a; //空心圆 import java.util.Scanner; class circle2 { public static void main(String[] args) { new circle2().print();} //画圆函数void print() {System.out.println("输入半径&#xff1a;"); Sca…

智能控制和计算机控制的区别,解析智能控制技术是什么及与传统控制的区别

描述智能控制是什么智能控制(intelligent controls)在无人干预的情况下能自主地驱动智能机器实现控制目标的自动控制技术。对许多复杂的系统&#xff0c;难以建立有效的数学模型和用常规的控制理论去进行定量计算和分析&#xff0c;而必须采用定量方法与定性方法相结合的控制方…

C++ 画直线

使用C画直线 完整代码 #include "graphics.h" int main() {int driver,mode,i;float x0,y0,y1,x1;float j12,k;driverVGA;modeVGAHI;initgraph(&driver,&mode,"");setbkcolor(GREEN);x0263;y0263;y1275;x1275;for(i0;i<18;i){setcolor(5);lin…

计算机系统性错误,《深入理解计算机系统-异常》

现代操作系统通过使控制流发生突变来对某些意外情况(磁盘读写数据准备就绪、硬件定时器产生信号等)做出反应。一般而言&#xff0c;我们把这些突变命名为异常控制流(Exceptional Contral Flow ECF)。异常控制流发生在计算机系统的各个层次。比如&#xff0c;在硬件层&#xff0…

C 画矩形

使用C画矩形 使用C语言的相关知识在控制台输出一个矩形。 完整代码 #include "graphics.h" int main() {int x0,y0,y1,x1,driver,mode,i;driverVGA;modeVGAHI;initgraph(&driver,&mode,"");setbkcolor(YELLOW);x0263;y0263;y1275;x1275;for(i0;…