购物车实现的几种方案对比

简介:购物车实现的几种方案对比,redis方案设计数据库方案设计

购物车实现方案目前来说总共有四种,分别是Cooke存储、session存储、数据库存储及内存缓存(常见的有redis,memcache)。今天就这四种方案来说说他们的优缺点。

1. Cookie存储

1.1 优点

  • Cookie是存储在客户端的,且占用资源少,既可以满足购物车需求,还可以减轻服务器压力
  • Cookie是浏览器内置,只要Cooke定义的有效期内,数据都不会丢失

1.2 缺点

  • 基于cookie开发的购物车要求用户浏览器必须开启并设置为启用cookie,否则购物车将失效
  • 如果用户换一台机器登录,就会丢失购物车信息(或者说购物车数据无法在不同设备间同步)
  • 黑客可以通过脚本攻击获取到cookie,从而获取个人信息,不安全

2. Session存储

2.1 优点

  • session可以与客户端保持同步,不依赖与客户端的设置

2.2 缺点

  • session会占用服务器资源,加大服务器的负载,尤其当并发用户很多时,会生成大量的session,影响服务器的性能
  • 多个设备同时登录一个账号时,无法同步购物车数据。例如:pc端与移动端无法共享购物车数据

3. 数据库存储

3.1 优点

  • 数据库记录购物车数据,会话由其他方式实现,使安全性和服务器性能都得到了提高
  • pc端与移动端购物车数据都可以共享,不会丢失

3.2 缺点

  • 每一个购物的行为都要与数据库进行连接操作,直至对表的操作成功后,连接才释放.当并发用户很多时,会影响数据库的性能,这时对数据库的性能就有更高的要求

数据库方式最为常见,实现方式也简单。建立购物车表,对表进行添加修改删除即可。对于过期自动删除功能,大家可以结合定时任务去操作。设计方案也比较简单,需要的可以参考我下方的设计:

uid 用户id
product_id 商品id
attr_id 规格值id
buy_num 购买数量
price

加入购物车时的单价,如果有需要可提醒用户商品是否降价处理

store_id 所属店铺
source

来源:普通渠道,1元秒杀,9.9包邮,其他活动等

create_time ​加入购物车的数量

4. Redis存储

redis性能好,不影响数据库负载。可在任何地方读取数据,适合集群和分布式系统。

从上面数据库实现购物车功能中表的设计可以看出,我们需要存储用户id、产品id、规格id、购买数量等信息,而且用户会加入多个商品到购物车,那么redis如何实现这样的一个设计呢?

网上有很多设计都是直接将所有字段以json字符串的格式存储到字符串类型中,添加、修改及删除数据时,都需要先将所有数据取出来,再解析json数据并遍历所有数据进行匹配,然后进行增、删、改 操作。个人认为这种方式太麻烦。

最开始我想通过集合来存储,key为【字符串+用户id】,其他字段以json字符串的形式存储到value中,具体如下所示:

sadd cart_1001 '{"product":134,"attr_id":111,"buy_num":2,"price":"12.23","store_id":2,"source":"1秒杀","create_time":"1694054852"}'

只要用户点击加入购物车就往 cart_1001 中添加一个元素,虽然redis的集合不允许出现重复的元素,但是value中的 buy_numbercreate_time 是实时变化的,导致同一个商品加入多次,而且无法排序。毕竟大多数平台都要求新加入的排在前面或者根据库存进行排序等,然而集合是无序的。

于是,改用有序集合来存储数据,有序集合除了元素不重复之外,还可以设置一个double类型的分数,用于排序使用。将加入购物车的时间用作有序集合的分数,其他字段再以json格式存储,具体格式代码如下:

zadd cart_set_1001 1694054852 '{"product":134,"attr_id":111,"buy_num":2,"price":"12.23","store_id":2,"source":"1秒杀"}'

虽然购买数量 buy_num 是变化的,但是我们可以预判当前用户上一次 buy_num 的值,这样一来我们就可以判断,当前用的购物车中是否已经添加了该商品,如果有先删除再把变化后的元素加入到有序集合中,这样就实现了购物车的 增 删 改 查

删除的方式有两种,一种是通过元素删除或者通过分数删除,具体命令如下:

# 通过元素删除
zrem cart_set_1001 '{"product":134,"attr_id":111,"buy_num":2,"price":"12.23","store_id":2,"source":"1秒杀"}'

# 通过分数删除(加入的购物车的数量)
zremrangebyscore cart_set_1001 1694054852 1694054852

 

有遗漏或者不对的可以在我的公众号留言哦

编程经验共享公众号二维码

编程经验共享公众号二维码
更多内容关注公众号
Copyright © 2021 编程经验共享 赣ICP备2021010401号-1