主要功能
- 选购商品时,下单之前,
暂存
用户想要购买的商品。 - 购物车对数据的可靠性要求不高,性能也没有特别的要求。
- 主要功能就三个:把商品加入购物车(
加购
),购物车列表页,发起结算下单。 - 所以只需要一个购物车实体就够了,主要属性有:
SKUID(商品id),数量,加购时间和勾选状态
。 商品价格和总价、商品介绍等等这些信息,都可以实时从其他系统中获取,不需要购物车系统来保存
问题
- 用户未登录,加购,关闭浏览器再打开,刚才加购的商品还在不在?
即便没登录,加购的商品也会被保存在用户电脑里,即使关闭浏览器依然存在。
- 用户未登录,加购,然后登录,刚才加购的商品还在不在?
如果先加购,再登录,加购的商品会自动合并到用户名下,所以登录后购物车中依然有登录前的商品。
- 用户关闭浏览器再打开,第二步加购的商品还在么?
关闭后再打开,这时又变为未登录态,但是之前的商品已经被合入到登录用户名下了,所以此时购物车是空的。
- 再用手机登录该用户,第二步加购的商品还在么?
存在,相同的用户相同的购物车。
原则
- 未登录,暂存购物车商品。
- 登录,把暂存的合并到用户名下,并清空暂存。
- 多端同步。
暂存购物车
- 保存在客户端,可以使用Session,Cookie和LocalStorage。
- Session不太合适,因为保留时间短,且数据依旧占用服务端资源。
- Cookie存储实现简单,服务端可以读写Cookie,加减合并都可以服务端实现。
- LocalStorage稍微复杂,只能客户端访问,客户端服务端都需要实现一些逻辑,优点是存储容量远大于Cookie的4KB,且不用每次请求都带着,节约带宽。
小型用Cookie,大型用LocalStorage。
购物车数据存储
- 某用户的购物车可以用如下json表示,既可以保存在mysql,也可以保存在redis
{
"cart": [
{
"SKUID": 8888,
"timestamp": 1578721136,
"count": 1,
"selected": true
},
{
"SKUID": 6666,
"timestamp": 1578721138,
"count": 2,
"selected": false
}
]
}
- 通过user_id查询,Redis性能远高于Mysql。
- Mysql可靠性较好,Redis是异步刷盘,可能丢数据。但是购物车数据对可靠性要求不是很苛刻,这个缺点可以忍受。
- Mysql支持丰富查询和事务机制,这个特效对于购物车核心功能没什么用,但是统计需求可能会用到(比如统计一下今天加购的商品总数),使用Mysql很容易,Redis很痛苦。
- 如果需求不断变化,建议使用Mysql,如果追求高性能,使用Redis。