电商

半腔热情 提交于 2019-11-26 14:07:39

电商实战

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. 使用缓存预热 缓存预热就是将数据提前加入到缓存中,当数据发生变更,再将最新的数据更新到缓 存。

1.3 缓存击穿

缓存击穿是指缓存中没有但数据库中有的数据。这时由于并发用户特别多,同时读 缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。

解决方案:

​ 1.设置热点数据永远不过期。

​ 2.缓存预热

1.4 缓存雪崩

缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案:

​ 1.缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。

​ 2.设置热点数据永远不过期。

​ 3.使用缓存预热

1.5 商品详细页价格缓存

我们已经将商品的信息生成为静态页面,但是商品价格经常变动,如果每次价格变动后都对静态页重新生成会影响服务器性能。所以,对于商品价格,我们采用异步调用 的方式来进行客户端渲染。

实现思路

​ 1.商品服务启动后加载全部价格数据到缓存。使用hash存储,skuID作为小KEY

​ 2.从缓存从查询商品价格,封装为controller,并设置可跨域调用

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!