首页 > 数据库 >redis hash类型操作

redis hash类型操作

时间:2023-03-27 10:46:32浏览次数:46  
标签:127.0 hash 6379 0.1 redis field 哈希 类型

Redis-Hash

前言

hash在很多编程语言中都有着很广泛的应用,而在Redis中也是如此,在redis中,哈希类型是指Redis键值对中的值本身又是一个键值对结构,形如value=[{field1,value1},…{fieldN,valueN}],其与Redis字符串对象的区别如下图所示:

 

 

一、内部编码

哈希类型的内部编码有两种:ziplist(压缩列表),hashtable(哈希表)。只有当存储的数据量比较小的情况下,Redis 才使用压缩列表来实现字典类型。具体需要满足两个条件:

  1. 当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)

  2. 所有值都小于hash-max-ziplist-value配置(默认64字节)

    ziplist 使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比 hashtable 更加优秀。当哈希类型无法满足 ziplist 的条件时,Redis会使用 hashtable 作为哈希的内部实现,因为此时 ziplist 的读写效率会下降,而 hashtable 的读写时间复杂度为O(1)。

二、常用命令

Redis哈希对象常用命令如下表。

命令说明时间复杂度
HDEL key field [field …] 删除一个或多个Hash的field O(N) N是被删除的字段数量。
HEXISTS key field 判断field是否存在于hash中 O(1)
HGET key field 获取hash中field的值 O(1)
HGETALL key 从hash中读取全部的域和值 O(N) N是Hash的长度
HINCRBY key field increment 将hash中指定域的值增加给定的数字 O(1)
HINCRBYFLOAT key field increment 将hash中指定域的值增加给定的浮点数 O(1)
HKEYS key 获取hash的所有字段 O(N) N是Hash的长度
HLEN key 获取hash里所有字段的数量 O(1)
HMGET key field [field …] 获取hash里面指定字段的值 O(N) N是请求的字段数
HMSET key field value [field value …] 设置hash字段值 O(N) N是设置的字段数
HSET key field value 设置hash里面一个字段的值 O(1)
HSETNX key field value 设置hash的一个字段,只有当这个字段不存在时有效 O(1)
HSTRLEN key field 获取hash里面指定field的长度 O(1)
HVALS key 获得hash的所有值 O(N) N是Hash的长度
HSCAN key cursor [MATCH pattern] [COUNT count] 迭代hash里面的元素  

三、适用场景

3.1 存储对象

​ Redis哈希对象常常用来缓存一些对象信息,如用户信息、商品信息、配置信息等。

我们以用户信息为例,它在关系型数据库中的结构是这样的

uid name age
1 Tom 15
2 Jerry 13
而使用Redis Hash存储其结构如下图:

 

 

相比较于使用Redis字符串存储,其有以下几个优缺点:

1、原生字符串每个属性一个键。

set user:1:name Tom
set user:1:age 15
  • 1
  • 2

优点:简单直观,每个属性都支持更新操作。
缺点:占用过多的键,内存占用量较大,同时用户信息内聚性比较差,所以此种方案一般不会在生产环境使用。

2、序列化字符串后,将用户信息序列化后用一个键保存

set user:1 serialize(userInfo)
  • 1

优点:简化编程,如果合理的使用序列化可以提高内存的使用效率。
缺点:序列化和反序列化有一定的开销,同时每次更新属性都需要把全部数据取出进行反序列化,更新后再序列化到Redis中。

3、序列化字符串后,将用户信息序列化后用一个键保存

hmset user:1 name Tom age 15 
  • 1

优点:简单直观,如果使用合理可以减少内存空间的使用。
缺点:要控制哈希在ziplist和hashtable两种内部编码的转换,hashtable会消耗更多内存。

此外,我们曾经在做配置中心系统的时候,使用Hash来缓存每个应用的配置信息,其在数据库中的数据结构大致如下表

AppIdSettingKeySettingValue
10001 AppName myblog
10001 Version 1.0
10002 AppName admin site

在使用Redis Hash进行存储的时候

新增或更新一个配置项

127.0.0.1:6379> HSET 10001 AppName myblog
(integer) 1
  • 1
  • 2

获取一个配置项

127.0.0.1:6379> HGET 10001 AppName 
"myblog"
  • 1
  • 2

删除一个配置项

127.0.0.1:6379> HDEL 10001 AppName
(integer) 1
  • 1
  • 2

3.2 购物车

很多电商网站都会使用 cookie实现购物车,也就是将整个购物车都存储到 cookie里面。这种做法的一大优点:无须对数据库进行写入就可以实现购物车功能,这种方式大大提高了购物车的性能,而缺点则是程序需要重新解析和验证( validate) cookie,确保cookie的格式正确,并且包含的商品都是真正可购买的商品。cookie购物车还有一个缺点:因为浏览器每次发送请求都会连 cookie一起发送,所以如果购物车cookie的体积比较大,那么请求发送和处理的速度可能会有所降低。

购物车的定义非常简单:我们以每个用户的用户ID(或者CookieId)作为Redis的Key,每个用户的购物车都是一个哈希表,这个哈希表存储了商品ID与商品订购数量之间的映射。在商品的订购数量出现变化时,我们操作Redis哈希对购物车进行更新:

如果用户订购某件商品的数量大于0,那么程序会将这件商品的ID以及用户订购该商品的数量添加到散列里面。

//用户1 商品1 数量1
127.0.0.1:6379> HSET uid:1 pid:1 1
(integer) 1 //返回值0代表改field在哈希表中不存在,为新增的field
  • 1
  • 2
  • 3

如果用户购买的商品已经存在于散列里面,那么新的订购数量会覆盖已有的订购数量;

//用户1 商品1 数量5
127.0.0.1:6379> HSET uid:1 pid:1 5
(integer) 0 //返回值0代表改field在哈希表中已经存在
  • 1
  • 2
  • 3

相反地,如果用户订购某件商品的数量不大于0,那么程序将从散列里面移除该条目。

//用户1 商品1
127.0.0.1:6379> HDEL uid:1 pid:2
(integer) 1
  • 1
  • 2
  • 3

3.3 计数器

Redis 哈希表作为计数器的使用也非常广泛。它常常被用在记录网站每一天、一月、一年的访问数量。每一次访问,我们在对应的field上自增1
  • 1
//记录我的
127.0.0.1:6379> HINCRBY MyBlog  202001 1
(integer) 1
127.0.0.1:6379> HINCRBY MyBlog  202001 1
(integer) 2
127.0.0.1:6379> HINCRBY MyBlog  202002 1
(integer) 1
127.0.0.1:6379> HINCRBY MyBlog  202002 1
(integer) 2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

也经常被用在记录商品的好评数量,差评数量上

127.0.0.1:6379> HINCRBY pid:1  Good 1
(integer) 1
127.0.0.1:6379> HINCRBY pid:1  Good 1
(integer) 2
127.0.0.1:6379> HINCRBY pid:1  bad  1
(integer) 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

也可以实时记录当天的在线的人数。

//有人登陆
127.0.0.1:6379> HINCRBY MySite  20200310 1
(integer) 1
//有人登陆
127.0.0.1:6379> HINCRBY MySite  20200310 1
(integer) 2
//有人登出
127.0.0.1:6379> HINCRBY MySite  20200310 -1
(integer) 1

转 https://blog.csdn.net/weixin_45178729/article/details/123783619

标签:127.0,hash,6379,0.1,redis,field,哈希,类型
From: https://www.cnblogs.com/wl-blog/p/17260721.html

相关文章

  • Redis - 对象结构
    简介Redis使用对象存储数据库中的键和值,每当在Redis中创建一个新的键值对时,都会创建两个对象:一个是键对象,另一个是值对象。其中,Redis的每种对象都由对象结构和对应......
  • python工程里面的类型的思考
    虽然我的工程语言是python语言,在工程搭建过程中非常注意类型提示的问题。关于方法的方法的返回值类型的问题:常用的方式是在函数/方法书写一些尖头+类型,这样调用方能很方......
  • Redis进阶系统学习2——Redis数据操作
    第二部分:Redis数据操作Redis官网全部命令:https://redis.io/commandsRedis命令参考中文网:http://doc.redisfans.com/下面主要介绍一些常用数据操作命令6.键命令查看所有键......
  • HashTable源码分析
    HashTable是一个线程安全的HashMap,是jdk早期版本的产物,但其效率较低1.初始化可以看到,与HashMap不同,HashTable无参构造是默认会构造一个容量为11的数组,而HashMap在无参......
  • Redis面试题-1
    Redis基础面试题1、为什么要使用Redis做缓存缓存的好处使用缓存的目的就是提升读写性能。而实际业务场景下,更多的是为了提升读性能,带来更好的性能,带来更高的并发量。Redis......
  • 我想用gin开发一个使用redis和数据库的系统。 我应该如何进行架构设计?
    在设计使用Redis的系统和使用Gin的数据库时,需要牢记几个架构注意事项。这是一个可能的架构设计:API层:API层处理传入的请求并提供响应。该层负责验证输入、验证用户......
  • windows下通过redis-cli查看中文乱码
    参考:https://zhuanlan.zhihu.com/p/592166597redis数据进制问题的解决redis会将存储的中文数据转成16进制,所以我们在连接控制台的时候将redis-cli改为redis-cli--ra......
  • IDM下载类型
    3GP7ZAACACEAIAIFALZAPKAPPARCARJASFAVIBHBINBRBUNDLEBZBZ2CDACSVDIFDLLDMGDOCDOCXEGGEPSEXEFLVGZGZIPIMGIPAISOISZJARKEXTLHALZ......
  • Redis主从集群切换数据丢失问题如何应对?
    数据丢失的情况异步复制同步丢失集群产生脑裂数据丢失异步复制丢失对于Redis主节点与从节点之间的数据复制,是异步复制的,当客户端发送写请求给master节点的时候,客......
  • 为什么HashMap查找比List快很多?
    做两数之和这道题目时,引发了一个思考:为什么两者运行时间相差如此之大???好残忍,我List比你HashMap到底差在哪****于是我一顿查资料....战犯哈希算法登场哈希算法......