分库分表
分库分表分为垂直和水平两个方式,一般来说拆分的顺序是先垂直后水平。
垂直分库
基于现在的微服务拆分来说,都是已经做到了垂直分库了。
将订单,用户,商品,支付,库存,预算等不同业务数据存放在不同的数据库中。
垂直分表
将字段比较多的表,将不常用的,数据较大的字段进行拆分。
一般拆分为主表和扩展表。
比如:订单表——>基础信息,订单扩展,收货地址。
水平分表
首先根据业务场景决定使用什么字段作为分表字段(sharding_key)。
比如我们现在日订单 1000 万,我们大部分的场景来源于 C 端,我们可以用 user_id 作为 sharding_key,数据查询支持到最近 3 个月的订单,超多 3 个月的做归档处理,那么 3 个月的数量就是 9 亿,可以分为 1024 张表,那么每张表的数据大概就在 100 万左右。
比如用户 id 是 100,那么我们经过 hash(100),然后对 1024 取模,就可以落到对应的表上了。
分表后 ID 如何保证唯一?
- 设定步长,1024 张表设定 1024 的基础步长,这样主键落到不同的表就不会冲突了。
- 分布式 ID,自己实现一套分布式 ID 生成算法,或者使用开源的比如雪花算法。
- 分表后不适用主键作为查询依据,而是每张表单独新增一个字段作为唯一主键使用。
分表后非 sharding_key 的查询怎么处理?
- 可以做一个 mapping 表,比如商家查询订单的时候,可以做一个映射表,保存商家与用户的关系,查询时先通过商家查询到用户,再通过 user_id 去查询。
- 打宽表,一般而言,客户端对数据实时性要求并不是很高,比如查询订单列表,可以把订单表同步到离线数仓,在基于数仓做成一张宽表。
- 数据量不是很大的情况,比如后台的一些查询服务,可以通过多线程扫表,然后再聚合结果的方式来做,或者异步的形式也是可以的,