Redis数据结构之哈希表

news/2024/9/22 14:00:15/

这里的哈希表说的是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/news/1528843.html

相关文章

C++:类型转换(static_cast、reinterpret_cast、const_cast、dynamic_cast)、RTTI

C:类型转换(static_cast、reinterpret_cast、const_cast、dynamic_cast)、RTTI 一、C语言类型转换二、C新增强制类型转换2.1 新增类型转换:static_cast2.2 新增类型转换: reinterpret_cast2.3 新增类型转换&#xff1a…

Spark-广播变量源码分析

一、广播变量使用 源码中给的例子是:org.apache.spark.examples.BroadcastTest 其中我们关心的只有两行代码,即创建广播变量和使用广播变量 //准备测试数据 val arr1 (0 until num).toArray //创建广播变量 val barr1 sc.broadcast(arr1) //使用广播…

python selenium网页操作

一、安装依赖 pip install -U seleniumselenium1.py: from selenium import webdriver from selenium.webdriver.common.by import Bydriver webdriver.Chrome() driver.get("https://www.selenium.dev/selenium/web/web-form.html") title driver.ti…

标准库标头 <bit>(C++20)学习

<bit>头文件是数值库的一部分。定义用于访问、操作和处理各个位和位序列的函数。例如&#xff0c;有函数可以旋转位、查找连续集或已清除位的数量、查看某个数是否为 2 的整数幂、查找表示数字的最小位数等。 类型 endian (C20) 指示标量类型的端序 (枚举) 函数 bit_ca…

微服务注册中⼼2

5.Nacos配置管理 Nacos除了可以做注册中⼼&#xff0c;同样可以做配置管理来使⽤ 5.1 统⼀配置管理 当微服务部署的实例越来越多&#xff0c;达到数⼗、数百时&#xff0c;逐个修改微服务配置就会让⼈抓狂&#xff0c;⽽且很容易出错。我们需要⼀种统⼀配置管理⽅案&#xf…

基于单片机的楼宇门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计程序具体实现截图参考文献设计获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设…

【数据结构】排序算法---计数排序

文章目录 1. 定义2. 算法步骤3. 动图演示4. 性质5. 算法分析6. 代码实现C语言PythonJavaGo 结语 1. 定义 计数排序又称为鸽巢原理&#xff0c;是对哈希直接定址法的变形应用。计数排序不是基于比较的排序算法&#xff0c;其核心在于将输入的数据值转化为键存储在额外开辟的数组…

基于stm32的四旋翼无人机控制系统设计系统设计与实现

文章目录 前言资料获取设计介绍功能介绍设计程序 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业…