# 海量跨境商品数据库分表分库优化实操教程
跨境商品数据量一旦膨胀到千万甚至亿级,单表查询和写入都会遇到严重瓶颈。本文面向零基础用户,用真实场景讲清楚什么时候该做分表分库、怎么设计分片规则、如何平滑迁移数据,以及迁移后如何验证效果。读完就能直接在自己的服务器上落地。
## 第一步:判断你的数据库是否需要分表分库
不是所有跨境商品库都需要分片。先做几个检查:
- 单表数据量是否超过 **500 万行**,且持续增长;
- 慢查询日志中是否有大量全表扫描(例如 `SELECT * FROM products WHERE seller_id = ?`);
- 写入并发是否导致锁竞争(`SHOW PROCESSLIST` 看到很多 `Waiting for table level lock`)。
如果满足任意两条,就该考虑分表或分库。简单场景先用 **MySQL 原生分区表**(分表不跨库),压力很大再用 **MyCat 或 ShardingSphere** 实现分库。
## 第二步:设计分片键与分片规则
分片键(Sharding Key)要选**查询最频繁的字段**,跨境商品库通常按 `seller_id`(卖家ID)或 `region`(地区)分片。
**示例场景**:假设我们用 `seller_id` 做分片键,按 `seller_id % 4` 分成 4 张表。
```sql
-- 创建分表模板(以 seller_0 为例)
CREATE TABLE products_seller_0 (
id INT AUTO_INCREMENT PRIMARY KEY,
seller_id INT NOT NULL,
product_name VARCHAR(200),
price DECIMAL(10,2),
region VARCHAR(10),
created_at DATETIME
) ENGINE=InnoDB;
-- 创建其他分表 products_seller_1, products_seller_2, products_seller_3
```
如果使用中间件(如 MyCat),在 `schema.xml` 中配置逻辑库和分片规则:
```xml
```
## 第三步:数据迁移与同步(零停机方案)
迁移时不能停机,建议用 **双写 + 增量同步** 方式:
1. 先建立分表结构(如上面的 4 张表);
2. 开启业务端双写:新写入同时写入原表和分片表(可以用消息队列解耦);
3. 历史数据用 `INSERT ... SELECT` 分批迁移:
```sql
-- 按 seller_id 范围分批,避免锁表
INSERT INTO products_seller_0 SELECT * FROM products WHERE seller_id % 4 = 0 AND id BETWEEN 1 AND 10000;
INSERT INTO products_seller_1 SELECT * FROM products WHERE seller_id % 4 = 1 AND id BETWEEN 1 AND 10000;
-- ... 重复,直到迁移完所有数据
```
4. 迁移完成后,对比总数(`SELECT COUNT(*)`)确保一致;
5. 切换读写入口到分片表,停掉原表写入。
## 第四步:常见踩坑与避坑方法
- **分片键选择不当**:如果按 `id` 取模,会导致跨卖家查询变成全表扫描。优先按 `seller_id` 或 `region`。
- **跨分片查询性能差**:避免 `ORDER BY` 或 `JOIN` 跨分片,可以在应用层合并结果。
- **数据倾斜**:某些卖家数据量特别大,导致一个分片比其他大很多。建议改用一致性哈希或按 `region + seller_id` 复合分片。
- **事务问题**:分库后无法支持跨库事务,业务层需要做补偿或改用柔性事务(如 TCC)。
## 第五步:效果验证与监控
迁移完成后,用以下方法验证优化效果:
- **查询响应时间**:`SELECT * FROM products_seller_0 WHERE seller_id=123` 之前可能 2 秒,现在应小于 50 毫秒;
- **写入吞吐量**:使用 `sysbench` 或简单压测脚本,对比分片前后的 TPS;
- **监控慢查询**:开启 `slow_query_log`,观察是否还有全表扫描;
- **检查数据完整性**:`SELECT COUNT(*)` 对比原表和所有分片表的总和。
如果遇到性能不升反降,先检查分片键是否命中、索引是否重建、连接池配置是否合理。
## 高频问题解答
**Q:分表后还能用 `JOIN` 吗?**
A:避免跨分片 JOIN。如果必须关联,可以在应用层先查分片,再合并结果。或使用全局表(如商品分类表)在每个分片冗余一份。
**Q:数据迁移过程中写错了怎么办?**
A:保留原库至少 7 天,双写阶段一旦发现异常立即回滚读指回原库。
**Q:分片数量以后还能扩展吗?**
A:建议一开始分片数取 2 的 N 次幂(如 4、8、16),方便后续扩容时只需做数据重分布,不需要调整取模算法。
如果你正在处理海量跨境商品数据库的分表分库优化,建议先按本文步骤小范围尝试,再逐步推广。遇到异常时优先回看避坑部分和常见问题,可以少走很多弯路。