电商订单系统分库分表设计全记录:反杀你的面试官

266 阅读4分钟

大型电商的订单系统,如何设计分库分表方案?

回答

  • 大型电商的订单系统的分库分表,主要考虑的就是分表数量、分表字段、分表算法这几个方面。
1、 分库 vs 分表,怎么理解?
  • 分库、分表、分库分表,他是三件事儿,不是一件事儿。
    1. 分表,是解决单表数据量太大,查询效率慢的问题。
    2. 分库,是解决并发量太高,数据库连接数不够、数据库的资源性能(内存、CPU、磁盘)不够的问题。
2、分表方式,如何选择?

参考:Java 八股/12-分库分表/分库?分表?分库分表?.md

  1. 垂直分库:就是把不同的业务的库拆分开。

    比如一个电商库,拆分成订单库、库存库、商品库。

  2. 垂直分表:就是把一张大表,拆分成多张小表。

    比如有100个字段,拆分成2张表,每张表各50个字段。

  3. 水平分库(分表):就是把一个库(表)中包含所有数据,水平的分散到不同的库(表)中。

    比如原来单库(表)中有1000万数据,那么我们分成5分,每一份库(表)中就只有200万数据了。

3、分表数量,如何计算?

一个表,拆分成多个表,拆多少张合适呢?

  1. 公式一、:分表数量 = (订单存量总数 + 预计年增长量 * 保留年限)/2000万 => 向上取最接近的2的幂

    比如:存量数据已经有2000万了,预计每年增长500万,我们需要保留10年:

    (2000 + 500 * 10) / 2000 = 3.5 => 4

  2. 公式二、:分库数量 = 分表数量 / 8

    如果,分表数量本身是小于8的,则 分库数量=分表数量

4、分表字段,如何选择?

参考:Java 八股/分表字段如何选择?

建议的两种方案:按照时间分、按照买家 ID 分。

1) 按照时间分表
  • 按照时间分表最大的好处
    1. 就是简单,逻辑是固定的。
    2. 按照时间的查询比较快。
    3. 方便做数据归档以及备份。
  • 一般在订单系统中,按照时间分表会做的。也都是把他用来做历史表或者做数据归档。但是,分表这里还是要配合使用业务单号来分。
2) 按照买家 ID 分表
  • 一个订单系统中最重要的三个字段:买家 id,卖家 id、订单号

  • 选择买家 ID 的主要原因:避免数据倾斜

    如果,按照卖家 id 分表的话,会有很多大卖家的数据量很大。

    那么,他的数据还是会落到单表中,导致这个单表数据量大,查询速度还是很慢。

  • 还有两个问题,要解决:

    1. 按卖家 ID 查询,怎么办?
    2. 按照订单号查询,怎么办?
  • “问题 1:按卖家 ID 查询,怎么办?”。解决方案:再同步一张卖家表

    基于 binlog 监听买家库的变更,把数据同步到另外一个库(也可能是多库)。

    这个库的分表逻辑是按照卖家 id 进行的,在同步的过程中,会基于卖家 id 再重新计算一次分到哪张表中。

    image-20250403122216972

    注意

    卖家库只做数据同步,不做任何的更新操作。

    所有的订单的修改,都基于买家库。即使是卖家的操作也一样。

    因为,操作是带订单号的。按订单号操作就行了。

  • “问题 2:按照订单号查询,怎么办?” 。解决方案:采用基因法

    所谓基因法就是:在生成订单号的时候,把分表结果也给他编码到订单号中。

    按照订单号查询的时候,解析出这段数字,直接去对应分表查询就好了。

    image-20250311000338069

5、分表算法

参考:Java 八股/分表算法都有哪些?

  • 分表算法不需要太精密,太复杂,只需要能实现均分分配就行了。

  • 一般就是取模算法

    使用买家 id ,对分表数量取模。