电商实战
1.1 数据库表设计
品类表 t_spec_group
id spg_id name
1 10001 手机
2 10002 手机线
3 10003 手机电池
4 11001 液晶电视
5 11002 投影电视
spg_id 品类编号 唯一索引,普通索引.比id更直观表示品类.比如10000-10009代表手机相关
name 品类名称 唯一索引
参数表 t_spec_param
spg_id spp_id name numeric unit generic searching segements
1 10001 1 CPU 0 1 0 0
2 10001 2 运存 1 GB 1 1 0
3 11001 5 分辨率 0 像素 1 1 720P\1080P\4K\8K
spg_id 品类编号,品类表中的spg_id字段.普通索引
spp_id 参数编号,代表这个品类下的参数排序.普通索引
generic 是否是通用参数
segements 参数值,就是规定参数可选范围
品牌表 t_brand
name image letter
1 联想 L
2 华为 H
name 唯一索引
letter 普通索引
分类表 t_category
name parent_id if_parent sort
1 手机/数码/配件 1 1 0
2 手机通讯 1 1 1
3 手机 2 0 1
parent_id 普通索引
sort 普通索引
分类品牌关联表 t_category_brand
一个分类下可以有多个品牌.一个品牌也可由多个分类.多对多的关系.所以需要一张关联表
category_id brand_id
3 1
3 2
category_id,brand_id 联合主键
产品表 SPU
title sub_title category_id brand_id spg_id saleable valid create_time update_time
小米9 xxxxx 3 3 10001 1 1
brand_id,category_id,spg_id,saleable,valid 普通索引
商品表 SKU
spu_id title images price param saleable valid
1
小米9 8GB+128GB 幻彩紫 移动联通电信全网通4G手机
{"desc": ["127.0.0.1/3.jpg", "127.0.0.1/4.jpg"], "facade":["http://127.0.0.1/1.jpg"]}
3299
{"CPU": "骁龙855", "内存": 128, "电池": 4000, "运存": 8, "屏幕尺寸": 6.39}
1
1
spu_id,saleable,valid 普通索引
title 全文索引
1.2 缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id 为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大.
解决方案:
1.接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
2.从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为 key-0。这样可以防止攻击用户反复用同一个id暴力攻击
public int findPrice(Long id) {
//从缓存中查询
Integer sku_price = (Integer)redisTemplate.boundHashOps("sku_price").get(id);
if(sku_price==null){
//缓存中没有,从数据库查询
Sku sku = skuMapper.selectByPrimaryKey(id);
if(sku!=null){ //如果数据库有此对象
sku_price = sku.getPrice();
redisTemplate.boundHashOps("sku_price").put(id,sku_price);
}else{
redisTemplate.boundHashOps("sku_price").put(id,0);
}
}
return sku_price;
}
- 使用缓存预热 缓存预热就是将数据提前加入到缓存中,当数据发生变更,再将最新的数据更新到缓 存。
1.3 缓存击穿
缓存击穿是指缓存中没有但数据库中有的数据。这时由于并发用户特别多,同时读 缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
解决方案:
1.设置热点数据永远不过期。
2.缓存预热
1.4 缓存雪崩
缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
解决方案:
1.缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
2.设置热点数据永远不过期。
3.使用缓存预热
1.5 商品详细页价格缓存
我们已经将商品的信息生成为静态页面,但是商品价格经常变动,如果每次价格变动后都对静态页重新生成会影响服务器性能。所以,对于商品价格,我们采用异步调用 的方式来进行客户端渲染。
实现思路
1.商品服务启动后加载全部价格数据到缓存。使用hash存储,skuID作为小KEY
2.从缓存从查询商品价格,封装为controller,并设置可跨域调用
来源:https://blog.csdn.net/wdfgd/article/details/98883841