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

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

第二种方式
数据整体成了一个数据类型,进行修改的话,受到了限制。
第一种方式虽然过于分散,但是有着唯一的标识,既表:id:id的值,不同的只是后面的字段名与数据,那么就可以通过hash表的存储方式:

hash存储
这样就可以轻便的管理这堆数据。
关于什么是哈希:哈希表
hash类型
- 新的存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息。
- 需要的存储结构,一个存储空间保存多个键值对数据
- hash类型:底层使用hash表实现数据存储
- 存储结构优化:field较少时,是一个类数组的存储结构,较多时,是一个hashmap的存储结构
基础操作
- 添加/修改数据
hset key field value - 获取数据
hget key field
hgetall key - 删除数据
hdel key field1 [field2]

示意
- 添加/修改多条数据
hmset key field1 value1 field2 value2 ... - 获取多条数据
hmget key field1 field2 ... - 获取hash表中field的数量
hlen key - 判断hash表中是否有指定field
hexists key field - 示意

扩展操作
- 获取哈希表内所有的字段名或值
hkeys user
hvals user - 示意
- 设置指定字段的数值增加指定的范围
hincyby key field increment
hincybyfloat key field increment - 示意


注意事项
- 禁止套娃,hash里面不能存hash。
- 每个hash可以存232-1个键值对
- hash的设计初衷不是用来存储大量数据的,不要滥用hash,更不可将hash作为对象列表使用。
- hgenall操作,如果获取的field过多,会有瓶颈。
应用场景1
电商网站购物车设计。

示意
解决方案
- 以用户id作为key,每位用户创建一个hash存储结构存储其购物车信息。
- 以商品编号作为field,商品数量作为value存储
- 添加商品:追加全新的field和value
- 浏览:遍历hash
- 更改数量:自增自减,设置value值
- 删除商品:删除field
- 清空:删除key
- 简单示意

但是这样的存储真的加快了购物车的操作嘛?
我们从redis获取数据后,还需要去数据库进行二次核验,这样显然还不如直接存放数据库。
那么有什么优化方案:
- 每条购物车里的商品信息保存成两条field
- field1用来保存商品购买数量
商品id:nums:购买数量 - field2用来保存保存其他信息,图片地址,商家信息,文字描述等
商品id:info:[...] value使用json的信息保存

示意
也可以在升级一步,将商品信息单独使用一个hash表。
同时还有一个命令:
hsetnx key field value
他的功能类似于hget 但是只能增加,不能修改。他可以用来进行商品的添加。
应用场景2
抢购,秒杀活动。

示意
解决方案
- 以商家id作为key
- 将参与抢购的商品id作为field
- 将参与抢购的商品数量作为value
- 采购时采用降值的方式控制商品数量

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
















