Redis数据结构之哈希表

ops/2024/9/24 20:31:06/

这里的哈希表说的是value的类型是哈希表

一.相关命令

1.hset key field value

一次可以设置多个

返回值是设置成功的个数

注意,哈希表中的键值对,键是唯一的而值可以重复

所以有下面的结果:

key中原来已经有了f1,所以再使用hset时,返回值是0,表示没有设置新的字段,但是根据hget的结果可以知道,f1的value已经修改了

2.hget key field获取指定的字段的值

这里的字段指的是field,而不是key

时间复杂度:O(1)

3.hexists key field 判官是否有指定的字段

这里的字段指的是field

一次只能判断一个字段

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

时间复杂度:O(1)

4.hdel key field

一次可以删除多个

返回值是成功删除掉的个数

时间复杂度:O(1)

5.hkeys key获取hash中的所有列表

时间复杂度:O(N),N表示key中field的个数,所以当field很少时,就可以看成O(1)

与keys一样有一定的风险,如果field很多,就可能造成其他命令无法及时接收,导致请求偏向mySql,造成mySql崩溃

6.hvals获取hash中所有的值

时间复杂度:O(N)

7.hgetall key 获取hash中所有的字段以及值

时间复杂度:O(N),N表示字段的个数

8.hmget key field [field]一次获取多个字段的值

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

10.hsetnx 在字段不存在的情况下才设置

注意,不存在hsetex

11.hincrby key field increment

返回值是增加后的结果

12.hincrbyfloat key field increment

可以对整数进行加浮点数的操作,也可以对浮点数进行加整数的操作

二.内部编码

redis中hash表的内部编码有两种:ziplist和hashtable

ziplist:压缩列表。

我们常说的rar、zip、gzip、7z……都是一些常见的压缩算法。

压缩的本质:针对数据进行重新编码。不同的数据有不同的特点。结合这些特点,进行精妙的设计,重新编码后就能缩小体积。

例如:abbcccdee,重新编码为1a2b3c1d2e

事实上,上述压缩算法都是精妙设计的,ziplist也同理,内部的数据结构也是精心设计的,节省内存空间。

但是ziplist进行压缩会有代价:读取速度慢。如果元素个数少,则慢的不明显,多了则雪上加霜。

而hashtable的读写时间复杂度是O(1)。

所以只有当hash表中字段个数较少并且每个字段的值也很短时才会使用ziplist,如果元素个数多或者某些字段的值很长就会使用hashtable

三.使用场景

当作缓存,存储结构化数据

前面说过,String也可以作为缓存使用,但是针对于存储结构化数据,使用哈希表类型会更合适

如下是一张关系型数据表保存用户信息:

将它映射到redis中存储,其中value是hash类型,如下:

这里的user1和user2就是键,后面的哈希表就是值。

但是要是使用string字符串存储,就需要用到json这样的数据格式。

就比如某个场景下只需要获取其中的一个field或者修改其中的一个field,那就得把整个json格式的数据全部读取出来,然后解析成对象,再去操作field。操作完毕后再将对象转化成json格式字符串再重新存储。这样真的很麻烦。但要是使用hash来表示userinfo,就可以使用field表示对象的每一个属性,获取时也可以单个field获取,这样的话,读取field更高效。

但是,虽然读取field更高效,却付出了空间的代价!!!因为要控制hash在ziplist和hashtable这两种存储方式的转换中,可能造成内存的大量消耗

哈希类型和关系型数据库的区别

1.哈希类型是稀疏的,而关系型数据库是完全结构化的。就是说哈希类型的每个键可以有不同的value,比如其中一个键设置了地址信息,而另一个键就可以不设置。但要是关系型数据库,一旦添加了新的列,就必须设置值,要么就设置成NULL

缓存方式对比

截至目前,我们已经能够使用三种方式来作为缓存,下面给出三种方式的优缺点

1.原生字符串类型

set user:1:name John

set user:1:age 23

set user:1:address Beijing

优点:实现简单,针对个别属性的变更也很灵活

缺点:占用过多的键,内存占用量较大,同时用户信息再redis中比较分散,缺少内聚性,所以这种方案基本上没有实用性,是低内聚的表现。但是程序设计助球队是高内聚低耦合(高内聚就是把所有相关联的东西放在一起;耦合指的是两个代码/模块之间的关联关系,关联关系越大,相互的影响就越大,耦合度就越高)

2.序列化字符串类型——例如JSON格式的字符串

set user:1 经过序列化后的用户对象字符串

优点:针对总是以整体作为操作的信息比较合适编程成也比较简单,同时。如果序列化方案选择合适,内存使用的效率也很高

缺点:本身序列化和反序列化需要一定的开销,同时如果总是操作个别属性则不是很灵活

3.哈希类型

hmset user:1 name John age 23 address Beijing

优点:简单直观灵活。尤其是针对信息的局部变更和获取

缺点


http://www.ppmy.cn/ops/115447.html

相关文章

J Transl Med结肠癌分子分型+简单实验

目录 技术路线 实验设计(药物敏感性) 亮点 方法 从 TCGA 和 GEO 数据库下载大量和单细胞 RNA 测序以及 CRC 的临床数据。HRGs 和 LMRGs 来自分子特征数据库。使用 R 软件包 DESeq2 进行差异表达分析。使用无监督聚类进行分子亚型。使用单变量 Cox 回…

Laravel邮件发送:从配置到发邮件的指南!

Laravel邮件发送功能如何实现?怎么使用Laravel发信? Laravel作为一款流行的PHP框架,提供了强大且易用的邮件发送功能。AokSend将详细介绍如何从配置到实际发送邮件的全过程,帮助你快速掌握Laravel邮件发送的技巧。 Laravel邮件发…

【MySQL】表的操作

目录 一、增加表 二、查看表 2.1 查看当前数据库中的表 2.2 查看指定表的结构 2.3 查看创建表时的详细信息 2.4 查看表中所有数据 三、修改表 3.1 修改表名 3.2 插入数据 3.3 添加列 3.4 修改列类型 3.5 删除列 3.6 修改列名 四、删除表 一、增加表 增加表的语法…

sqli-lab靶场学习(四)——Less11-14(post方法)

前言 第1-10关都是get方法,本关开始进入post方法。其实post也好get也好,本质都差不多,使用的技巧也基本相同。 Less11 第11关打开是一个输入用户名密码的界面 显然登陆对话框会使用post方式提交,这里我们尝试在Username一栏通过…

Android轻量级RTSP服务使用场景分析和设计探讨

技术背景 好多开发者,对我们Android平台轻量级RTSP服务模块有些陌生,不知道这个模块具体适用于怎样的场景,有什么优缺点,实际上,我们的Android平台轻量级RTSP服务模块更适用于内网环境下、对并发要求不高的场景&#…

Redis - 深入理解Redis事务

目录 Redis是如何实现事务的?事务中执行的命令出现错误,会回滚事务吗?同一个连接可以重复开启事务吗?多个客户端同时开启事务会怎样?使用Redis事务只用MULTI和EXEC吗?Redis中的WATCH机制是怎么实现的&#…

YOLOv5的训练技巧汇总

文章目录 前言训练技巧1.训练预热 Warmup1.1 什么是训练预热 Warmup?1.2 常见的训练预热类型1.3 yolov5里面的warmup 2.余弦退火调整学习率 CosineAnnealingLR2.1 解释2.2 yolov5中的余弦退火 3.自适应锚框 Autoanchor3.1 什么是anchor?3.1 yolov5中的默认锚框3.3 …

安卓LiveData与MutableLiveData的使用

简介   LiveData 是 Android 架构组件的一部分,用于持有和管理可观察的数据生命周期感知的数据容器。它的设计目的是在应用的 UI 和数据之间提供响应式的双向绑定,并在数据变化时通知观察者。LiveData还能知晓它绑定的Activity或者Fragment的生命周期&…