业务实战场景(十六)电商平台通用取货码设计
2023-01-05 本文已影响0人
后来丶_a24d
目录
- 系列总目录
- 背景
- 简单系统设计
- 复杂系统设计
- 门店唯一
- 全局唯一
- 利用额外存储介质
- 直接查分库分表的mysql
- 不同租户不同需求
- 参考文章
系列总目录
背景
- 业务方为进一步提升用户的使用体验,规划了取货码生成及订单核销相关逻辑,目的是让线上的用户在付完款之后能够到店取货或者安排导购派送。比如线上美团买喜茶,让送到公司楼下美团柜,这时候需要取货码取喜茶,再比如看电影前取票、吃饭后出示券码、快递柜取包裹
- 这类业务特点是取货码长度相对较短,比起动辄十几二十位订单号,几位的数字码更方便记忆和输入。除了数字取货码,还提供二维码,方便终端进行扫描并核销
简单系统设计
-
量小,个体化经营,表结构不需要分库分表,那简单设计跟订单共享一张宽表即可
宽表设计.png - 需要注意取货码要防止重复
step1 获取随机码
step2 分布式锁
step3 执行SQL:SELECT COUNT(1) FROM order_main WHERE code = ${code} AND write_off_status = 0;
step4 判断是否可以插入:if ( count > 0) { continue; }
step5 执行数据写入
step6 解锁
复杂系统设计
- 业务特点,比如像美团平台saas化,量大,分库分表,saas化的电商平台会比简单的单表业务复杂很多
- 总体设计和订单表一样,需要做分库分表,saas化产品有两种方案,门店唯一和全局唯一
门店唯一
-
方案相对简单,只要保证每个租户下取货码唯一就好
门店唯一.png -
不过很容易串单,原本属于用户A的订单被用户B核销了。这种问题出现的本质原因在于纯粹的数字码无法带有用户的标识,虽然可以在核销前做人为的核验身份来避免,但依然属于高风险的系统设计
串单.png
全局唯一
- 全局唯一方案风险小,但实现难度稍高一点。核心问题在于如何判定随机生成的取货码是全局唯一的
利用额外存储介质
- 比如将取货码写入ES,查询先查ES是否存在,这种方案需要维护mysql和ES一致性,没有直接查库表来得直接
直接查分库分表的mysql
-
假设现在分了4库4表,取货码8位,遍历查所有表肯定不可取
4库4表.png -
将8位的取货码分成两个区域,随机码区域 + 库表位置, 库表位置是(0库, 0表) → 00, (0库, 1表) → 01... , (3库, 3表) → 15这样的映射
随机码区域 + 库表位置.png - 这样全局唯一方案就变成6位随机码单表里面数据唯一,理论上支持000000 ~ 999999,足够了,已核销的回收,只要判断还没核销的就好
- 库表位置可以和订单号保持一致,用订单号的基因去生成库表位置
不同租户不同需求
- 货码的长度,取货码编排的方式,取货码映射库表位置的策略等等做成可配,只要把主干逻辑进一步抽象,并使用策略模式进行个性化编码,主干思路还是可以用直接查分库分表的mysql方案