后端存储实战课
李玥
美团高级技术专家
44005 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 30 讲
结束语 (1讲)
后端存储实战课
15
15
1.0x
00:00/00:00
登录|注册

03 | 复杂而又重要的购物车系统,应该如何设计?

数据一致性保证
数据存放
MySQL vs. Redis选择
MySQL数据可靠性优势
Redis性能优势
MySQL vs. Redis
Redis
MySQL
JSON表示
Cookie vs. LocalStorage
LocalStorage
Cookie
Session
MySQL与Redis结合
综合考虑
性能比较
选择存储方式
服务端存储
数据格式
选择存储方式
客户端存储
购物车数据多端同步
合并暂存购物车和用户购物车
未登录用户暂存购物车
购物车小图标
结算下单
购物车列表页
加购
暂存用户想要购买的商品
思考题
用户购物车存储设计
暂存购物车存储设计
存储模型设计原则
功能
主要功能
购物车系统设计

该思维导图由 AI 生成,仅供参考

你好,我是李玥。
今天这节课我们来说一下购物车系统的存储该如何设计。
首先,我们来看购物车系统的主要功能是什么。就是在用户选购商品时,下单之前,暂存用户想要购买的商品。购物车对数据可靠性要求不高,性能也没有特别的要求,在整个电商系统中,看起来是相对比较容易设计和实现的一个子系统。
购物车系统的功能,主要的就三个:把商品加入购物车(后文称“加购”)、购物车列表页、发起结算下单,再加上一个在所有界面都要显示的购物车小图标。
支撑购物车的这几个功能,对应的存储模型应该怎么设计?很简单,只要一个“购物车”实体就够了。它的主要属性有什么?你打开京东的购物车页面,对着抄就设计出来了:SKUID(商品 ID)、数量、加购时间和勾选状态。
备注:图片来源于网络,仅供本文介绍、评论及说明某问题,适当引用。
这个“勾选状态”属性,就是在购物车界面中,每件商品前面的那个小对号,表示在结算下单时,是不是要包含这件商品。至于商品价格和总价、商品介绍等等这些信息,都可以实时从其他系统中获取,不需要购物车系统来保存。
购物车的功能虽然很简单,但是在设计购物车系统的存储时,仍然有一些特殊的问题需要考虑。

设计购物车存储时需要把握什么原则?

比如下面这几个问题:
用户没登录,在浏览器中加购,关闭浏览器再打开,刚才加购的商品还在不在?
用户没登录,在浏览器中加购,然后登录,刚才加购的商品还在不在?
关闭浏览器再打开,上一步加购的商品在不在?
再打开手机,用相同的用户登录,第二步加购的商品还在不在呢?
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

购物车系统的设计对于电商系统至关重要。本文从购物车系统的存储设计出发,探讨了购物车系统的功能、存储模型设计原则以及暂存购物车的存储方式。购物车系统的主要功能包括商品加入购物车、购物车列表页、发起结算下单以及在所有界面显示购物车小图标。针对购物车的存储设计,需要考虑用户登录状态下的购物车数据存储和同步问题,以及暂存购物车的存储方式选择。在存储设计时,需要遵循原则:未登录时需要临时暂存购物车的商品;用户登录时,需要合并暂存购物车的商品到用户购物车中,并清除暂存购物车;用户登录后,购物车中的商品需要在各终端中保持同步。针对暂存购物车的存储方式,可以选择在客户端使用Cookie或者LocalStorage来保存购物车数据,根据实际情况选择合适的存储方式。 文章还对使用MySQL和Redis两种存储的优劣势进行了比较。Redis在性能方面优势明显,响应时间更短,可以支撑更多的并发请求;而MySQL在数据可靠性和丰富的查询方式上有优势。综合比较下来,考虑到需求变化,更推荐使用MySQL来存储购物车数据,但如果追求性能或者高并发,也可以选择使用Redis。此外,文章还提出了一个思考题:能否将购物车数据存在MySQL中,并用Redis做缓存,以兼顾两者的优势,以及如何保证Redis中的数据和MySQL中的数据是一致的。 总的来说,本文通过深入分析购物车系统的存储设计原则和实际应用,为读者提供了有益的技术指导和思路。购物车系统的存储设计需要综合考虑性能、数据可靠性、系统可用性、可扩展性等多个条件,选择合适的存储方式需要根据实际情况进行权衡和取舍。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《后端存储实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(51)

  • 最新
  • 精选
  • 李玥
    置顶
    hi,我是李玥。 上节课我给你留了一道思考题,是这样的。如果说,用户下单这个时刻,正好赶上商品调价,就有可能出现这样的情况:我明明在商详页看到的价格是10块钱,下单后,怎么变成15块了?你的系统是不是偷偷在坑我?给用户的体验非常不好。你不要以为这是一个小概率事件,当你的系统用户足够多的时候,每时每刻都有人在下单,这几乎是个必然出现的事件。该怎么来解决这个问题? 关于这个问题,我是这样看的。 首先,商品系统需要保存包含价格的商品基本信息的历史数据,对每一次变更记录一个自增的版本号。在下单的请求中,不仅要带上SKUID,还要带上版本号。订单服务以请求中的商品版本对应的价格来创建订单,就可以避免“下单时突然变价”的问题了。 但是,这样改正之后会产生一个很严重的系统漏洞:黑客有可能会利用这个机制,以最便宜的历史价格来下单。所以,我们在下单之前需要增加一个检测逻辑:请求中的版本号只能是当前版本或者上一个版本,并且使用上一个版本要有一个时间限制,比如说调价5秒之后,就不再接受上一个版本的请求。这样就可以避免这个调价漏洞了。
    2020-03-03
    20
    189
  • aoe
    思考题是可行的,但是复杂,例如需要考虑: 1. Redis的容量可能远小于数据库容量,需要缓存策略缓存数据 2. 要处理老师提到的一致性问题 3. 性价比 另外请教老师一个问题: 在电商系统中,订单的“商品快照”(商品名称、数量、详情页所有信息)一般是怎么存储的? 例如:有订单、商品2个子系统,订单的商品快照一般是由哪个系统生成和保存?

    作者回复: 我个人的看法是,商品子系统存储商品快照更合理一些。

    2020-03-03
    2
    9
  • 大秦皇朝
    1、京东的浏览器端,为什么每次加完购物车都要跳转到一个中转界面上呢?这点我疑惑了很多年,从软件设计的逆向思维来考虑,我也想不出所以然来,还请李玥老师是否能给解答下呢?因为按照我们的日常使用习惯(如:阿里,京豆手机端等),都是点击加购物车,直接购物车数量加1提示就好了呀?为什么要多此一举影响用户体验呢? 2、李玥老师文稿中提到,用户的购物车偶发情况下丢失一些数据可以接受,但是站在消费者的角度来说,我感觉也没必要纠结是不是少了几样东西。但是会直接影响我对这个平台的感知度,我会认为这个平台能力不行,不注重用户体验等,会给产品(京东)带来很多负面影响呀,所以牺牲的可靠性的这个比例的平衡点是一定要重视的。 思考题:综上第2点所述,我觉得业务让必然需要这个方案可行把?写数据的时候MySQL写和Redis同时删,读的时候从Redis中读;如果没有读到再从MySQL中读取,同时写到Redis中。(现学现卖不知道对不对) 但是也有个问题,多端同时操作,或者网络不好的时候,么保证数据的准确性呢?完了完了,我又跳回第一讲了。。。

    作者回复: 关于你的第一个问题:“为什么每次加完购物车都要跳转到一个中转界面上呢?”,虽然我也在京东工作,我还真不知道为什么这样设计,不过不知道也好,我们还可以尝试去猜一下它为什么这样设计,如果我知道的话,可能会涉及商业秘密,反而不能回答了。 作为局外人,我的猜测是这样的,加购之后,一般用户就不会想继续看这个商详页了,接下来它可能的二个路径是: 1.去购物车结算; 2.去看其它商品; 所以,增加一个中间页,可以放好多推荐商品,引导用户继续购物,算是商家的小聪明吧。

    2020-03-04
    4
    4
  • 肥low
    我觉得完全可行 而且有时候比如MySQL主从架构下是有数据延迟更新问题的 用Redis我可以尽量避免这一点 不过有对用户加购的维护成本

    作者回复: 我会在下节课的评论区说一下我的理解,请关注。

    2020-03-03
    2
    3
  • “用户没登录,在浏览器中加购,然后登录,刚才加购的商品还在不在?” 关于这一点,怎么判断没登录加车的用户 和 登录的用户是同一个呢?比如我没登录在购物车加了一堆东西,然后我朋友用我的电脑登录他的账户,这该如何解决

    作者回复: 这种情况真的识别不了……

    2020-04-05
    5
    2
  • 王佳山
    老师,这个暂存购物车怎么做还是没太明白! 比如用cookie,当用户没登录,第一次添加购物车的时候,服务端给cookie中添加标识吗,之后这个标识就代表一个未登录用户吗?还是前端给cookie添加标识,或者怎么样? 如果未登录用户加购之后,再也不访问网站,这个暂存购物车就会保存脏数据,是不是还要对数据定时检查维护?删除时间过长的数据,或者暂存就用redis做,设置有效期

    作者回复: 暂存购物车写到Cookie中,是不需要标识的,因为Cookie是存在浏览器中的,每个浏览器本身就是标识。 另外,Cookie也是可以设定有效期的。

    2020-06-08
  • 张学磊
    如果使用redis做购物车存储该如何设置商品过期时间呢?

    作者回复: 如果用Redis做购物车的唯一存储而不是缓存的话,不需要设置过期时间。

    2020-05-17
    3
  • kamida
    老师 文中的购物车表一行只能存一种商品吧 但是一个购物车id应该可以有多种商品 请问这个该怎么解决呢

    作者回复: 我们给出的方案支持多种商品的,你可以自行看一下文中的例子,就是2种商品。

    2020-03-23
    4
  • 京京beaver
    购物车一般建议放到MySQL中。一般电商购物车是不占库存的,但是某些特卖电商购物车是占库存的。在这种情况下,数据是不允许丢失的,不然客户体验会非常差。Redis做缓存没啥用,因为每个用户只访问自己的购物车,每次访问网站也不会打开很多次购物车,缓存数据的命中率太低,没有意义。
    2020-03-03
    7
    71
  • 黄海峰
    感觉购物车是写多于读,也就是经常变,用cache aside的方式保持一致性的话就经常删缓存,db压力减轻不了多少,还要多写一次缓存,没什么必要
    2020-03-03
    6
    36
收起评论
显示
设置
留言
51
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部