卑微小吴励志写博客第20天。
昨天学习了一下redis数据结构中的string,学习了一些基础的命令,以及用法。最主要的是使用场景。
思考:
用string存储用户的粉丝,博客,关注等信息时,有什么问题?
set user: id:10086 {fans:1000,blogs:200,focus:60}
或者
set user: id:10086:fans 1000
set user: id:10086:fans 200
set user: id:10086:fans 60
这样有什么问题。
拿数据特别是修改数据的时候太笨重了,所以需要另一种更好的数据结构来存储。
hash
存储对象类数据。
hash数据类型的基本操作
添加修改数据
- hset key field value
获取数据
- hget key field
- hgetall key
删除数据
- hdel key field1 [field2]
添加修改多个数据
- hmset key field1 value1 field2 value2 …
获取多个值
-hmget key field1 field2 …
获取hash表中字段的数量
- hlen key
获取hash表中是否存在指定的字段
- hexists key field
hash数据类型的扩展操作
获取所有的字段名和值
- hkeys key
- hvals key
设置指定字段的数值类型的值自增指定范围
- hincrby key field incrment
- hincrbyfloat key field incrment
hash数据类型的操作注意事项
- hash类型filed对应的值只能是字符串,不能嵌套。如果数据未找到,则返回对应的值为(nil)
- 每个hash存储的键值对是有限的,最多只能存储2^32-1个键值对。
- hash的存储格式十分贴近对象的存储形式,并且可以灵活的操作对象属性。但是hash的设计初衷不是为了存储对象,所以不要随便存储对象。
- hgetall操作可以获取全部属性,但是如果内部的field字段较多,遍历整体数据的效率就会低,有可能成为数据访问的瓶颈。所以还是用什么就拿什么。
业务场景
-
电商网站购物车实现
-
以客户的id作为key,每一个用户创建一个hash存储结构。
-
将商品编号作为field,数量作为value。
-
添加商品:追加全新的field和value。
-
删除商品:删除对应的field。
-
增加商品数量:用hincrby,设置value的值。
-
清空商品:删除key。
这样做有什么问题?这样做是否加速了购物车的实现?
肯定不是的,商品的信息还得去数据库查,这里只有商品的编号和数量。
整改:把每条购物车中的商品纪录保存为两条。
比如之前是: hset 001 g01 100;
改为: hmset 001 g01:nums 100 g01:info {…} ;
field1专门存储数量,field2专门存储商品信息,用json保存。 这样所有的数据都可以从redis中读取了。
还可以优化
如果用户001和用户002都买了一样的商品,都会存储相同的商品信息info{…},可以把用户商品信息独立出来。可以用类别作为key,分成诺干个hash,这样会更快一些。
扩展
hsetnx key field value
如果有值,加不进去,没值才能加进来。避免用于购买相同的产品,重复在redis中加入商品信息。
业务场景二
双十一活动,销售手机充值卡的商家推出了30,50,100元的商品推出抢购活动,每种商品抢购上限1000张。
- 商家id作为key
- 参与抢购的商品作为field
- 产品数量作为value
- 抢购时用降值的方法设置value
使用场景:
redis可用于抢购,限购,发放优惠券等等业务的数据存储设计。