redis专题三:redis的数据类型之hash
一、基本介绍
前面一个专题我们讲到string去存储明星微博粉丝数,微博数等,大概介绍了两种方式:
- set user:id:012345:fans 12210862 set user:id:012345:blogs 83
- 采用json的方式:set user:id:012345 {id:012345, blogs:83, fans:12210862}
第一种方式,相当于是两个key,分别去存储,第二种方式呢,取数据还可以,修改就显得比较笨重。我们做一下变形,变成下面这种形式:相当于存储空间变成了一个键对应一个值,外部只需要明星的id的key就好了。相当于一个key存储了多组数据,我们简化下图:
hash类型:
- 对一系列存储的数组进行编组,方便管理,典型应用存储对象信息
- 需要的存储结构:一个存储空间保存多个键值对数据
- 底层用hash表结构存储数据
hash存储结构优化
- 如果field数量较少,存储结构优化为类数组结构
- 如果filed数量较多,存储结构优化为HashMap结构
二、基本操作
功能 | 命令 | 其他说明 |
添加修改数据 | hset key field value | |
获取数据 |
hget key field hgetall key |
如果是获取所有的key,field和value都会得到,交叉展示 |
删除数据 | hdel key field | 可以删除多个field |
添加修改多个数据 | hmset key field1 value1 field2 value2 | |
获取多个数据 | hmget key field1 field2 | |
获取哈希表中字段的数量 | hlen key | 返回field个数 |
获取哈希表中是否存在指定字段 | hexists key field | 存在返回1,不存在返回0 |
三、扩展操作
功能 | 命令 | 其他说明 |
获取哈希表中所有字段名 | hkeys key | 得到所有的field |
获取哈希表中所有字段值 | hvals key | 得到所有的value |
设置指定字段的数值数据增加指定范围的值 |
hincrby key field incremet hincrbyfloat key field increment |
四、注意事项
- hash类型下的value只能存储字符串,不允许存储其他数据类型,不存在嵌套对象;如果数据未获取到,对应值为nil
- 每个hash可以存储2^32-1个键值对(存储有上限)
- hash类型十分贴近对象的存储格式,并且可以灵活添加删除对象的属性值。但是hash的设计初衷不是为了存储大量对象设计的,而且更不能将hash作为对象列表使用
- hgetall操作可以获取全部属性,如果内部fields过多,遍历整体数据效率就会很低,有可能成为数据访问瓶颈。
五、业务场景
比方说电商中的购物车,每个用户使用自己的购物车,购物车中购买多个商品,每个商品的数量也不尽相同,这个时候我们就可以考虑hash的存储结构;key 就是用户的ID,field是商品的id,value就是购买对应商品的数量。
存储结构OK了,那么我们购物车的操作是不是也能实现了?当然可以的,比方说要获取购物车中商品的个数可以使用hlen,获取某个商品的购买数量hget,购买数量修改hset/hincrby,
看全部购物车hgetall,删除hdel。因此用hash是没有问题。
六、string存储对象和hash存储对象区别
string存对象讲究整体性,要么一次性更新,要么一次性获取,以读为主;
hash可以用field把属性隔离开来,讲究的是更新操作的灵活性;hash是一个群组概念,把一系列的数据包装起来,对外产生唯一的key。
如果更新比较多,推荐使用hash,如果更加注重对外呈现,推荐string。