hash

我们说回上一节中存储大V信息的例子,如果使用第一种方式:

 


 




java操作redis获取hash中所有的数据_hash表


第一种方式


 

 

存储过于分散,不易管理。
如果使用第二种方式:

 

 


 


java操作redis获取hash中所有的数据_数据_02


第二种方式


数据整体成了一个数据类型,进行修改的话,受到了限制。

 

第一种方式虽然过于分散,但是有着唯一的标识,既表:id:id的值,不同的只是后面的字段名与数据,那么就可以通过hash表的存储方式:

 


 


java操作redis获取hash中所有的数据_数据库_03


hash存储


 

这样就可以轻便的管理这堆数据。
关于什么是哈希:哈希表

hash类型

  • 新的存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息。
  • 需要的存储结构,一个存储空间保存多个键值对数据
  • hash类型:底层使用hash表实现数据存储
  • 存储结构优化:field较少时,是一个类数组的存储结构,较多时,是一个hashmap的存储结构

基础操作

  • 添加/修改数据
    hset key field value
  • 获取数据
    hget key field
    hgetall key
  • 删除数据
    hdel key field1 [field2]

 


java操作redis获取hash中所有的数据_存储结构_04


示意


  • 添加/修改多条数据
    hmset key field1 value1 field2 value2 ...
  • 获取多条数据
    hmget key field1 field2 ...
  • 获取hash表中field的数量
    hlen key
  • 判断hash表中是否有指定field
    hexists key field  
  •  
  • java操作redis获取hash中所有的数据_数据_05

  • 示意

扩展操作

  • 获取哈希表内所有的字段名或值
    hkeys user
    hvals user  
  •  
  • java操作redis获取hash中所有的数据_redis_06

  • 示意
  • 设置指定字段的数值增加指定的范围
    hincyby key field increment
    hincybyfloat key field increment  
  •  
  • java操作redis获取hash中所有的数据_数据库_07

  • 示意

注意事项

  • 禁止套娃,hash里面不能存hash。
  • 每个hash可以存232-1个键值对
  • hash的设计初衷不是用来存储大量数据的,不要滥用hash,更不可将hash作为对象列表使用。
  • hgenall操作,如果获取的field过多,会有瓶颈。

应用场景1

电商网站购物车设计。

 


 


java操作redis获取hash中所有的数据_数据库_08


示意


 

解决方案

  • 以用户id作为key,每位用户创建一个hash存储结构存储其购物车信息。
  • 以商品编号作为field,商品数量作为value存储
  • 添加商品:追加全新的field和value
  • 浏览:遍历hash
  • 更改数量:自增自减,设置value值
  • 删除商品:删除field
  • 清空:删除key  
  •  
  • java操作redis获取hash中所有的数据_hash表_09

  • 简单示意

但是这样的存储真的加快了购物车的操作嘛?
我们从redis获取数据后,还需要去数据库进行二次核验,这样显然还不如直接存放数据库。
那么有什么优化方案:

  • 每条购物车里的商品信息保存成两条field
  • field1用来保存商品购买数量
    商品id:nums:购买数量
  • field2用来保存保存其他信息,图片地址,商家信息,文字描述等
    商品id:info:[...] value使用json的信息保存

 


java操作redis获取hash中所有的数据_数据_10


示意


也可以在升级一步,将商品信息单独使用一个hash表。

同时还有一个命令:
hsetnx key field value
他的功能类似于hget 但是只能增加,不能修改。他可以用来进行商品的添加。

应用场景2

抢购,秒杀活动。

 


 


java操作redis获取hash中所有的数据_hash表_11


示意


 

解决方案

  • 以商家id作为key
  • 将参与抢购的商品id作为field
  • 将参与抢购的商品数量作为value
  • 采购时采用降值的方式控制商品数量

 


java操作redis获取hash中所有的数据_redis_12


示意


hash类型和string类型(存储json)来比较,hash更适合存放动态数据,用来频繁的进行交互;string类型更适合存放一些静态数据。