单表到了几亿数据,什么时候才应该分库分表?分片键、扩容和跨库查询怎么设计?
我的判断
分库分表是单实例容量与运维边界逼近后的选择,不是行数阈值;决定方案的是主访问路径、扩容方式和跨片需求。
我会先证明单库已接近边界:索引和归档做完后,写入、存储、备份恢复时间或热点仍无法满足未来 6~12 个月增长。几亿行如果按主键点查仍可能很快;反过来,几千万行但写热点和大事务严重,也可能需要拆。
订单用户侧查询占主流时,可以按 user_id 映射到虚拟槽,再路由到物理分片。这样点查单片,但商家按店铺和时间的查询会跨片,所以要通过订单事件构建商家维度的异构索引或查询库,不能在接口里广播所有分片。
扩容会预先设计:
- 全局 ID 不依赖单库自增;
- 虚拟槽减少迁移范围;
- 迁移期间按版本双写或订阅 binlog,并持续核对数量与校验和;
- 切读、回滚和补偿都有明确开关。
跨片事务尽量转成单片本地事务加事件驱动;报表和全局搜索走专门系统。分片后复杂度是永久成本,所以收益必须能被容量数据证明。
容易答偏踩坑误区
- 只按当前最方便字段分片。 要回放用户、商家、客服和财务全部 Top 查询。
- 依赖跨库分页和排序。 分片数增长后成本线性放大。
- 没有扩容与回滚设计就上线。 第一次迁移时才补会非常危险。