业务实战场景(十六)电商平台通用取货码设计

目录

  • 系列总目录
  • 背景
  • 简单系统设计
  • 复杂系统设计
    • 门店唯一
    • 全局唯一
      • 利用额外存储介质
      • 直接查分库分表的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方案

参考文章

  • vivo 全球商城:电商平台通用取货码设计

你可能感兴趣的:(业务实战场景(十六)电商平台通用取货码设计)