## 适用场景与核心问题
当跨境商品数据达到百万级别时,单表查询会变得非常慢,甚至导致数据库连接超时。分库分表的核心思路是把大表按某个规则(例如按商品ID或商户ID)拆成多个小表,分布到不同数据库实例上,让每个分片只承担一小部分数据压力。本文以 MySQL + MyCat 中间件为例,零基础也能照做。
## 前置准备:环境和工具
你需要准备:
- 一台 CentOS 7+ 服务器(已安装 MySQL 5.7+)
- MyCat 1.6 安装包(去官网下载 `Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz`)
- 跨境商品表结构(含 `id`, `sku`, `name`, `price`, `region`, `created_at` 等字段)
解压 MyCat 到 `/usr/local/mycat`,并确保 Java 8 已安装。启动 MyCat 前先配置 `schema.xml` 和 `rule.xml`。
## 分步操作:从设计到配置
### 第一步:确定分片键
对于跨境商品,按 `region`(地区)分片比较合理。例如亚洲商品放 db1,欧洲商品放 db2。同时也可以按 `id` 取模分片,但地区分片能更好匹配跨境业务查询场景。这里我们选择 `region` 字段作为分片键。
### 第二步:创建物理数据库和表
在两台 MySQL 实例(或同一实例的不同库)上分别创建数据库 `db_product_asia` 和 `db_product_europe`,每个库中创建相同结构的表 `product`。
```sql
CREATE DATABASE db_product_asia DEFAULT CHARSET utf8mb4;
USE db_product_asia;
CREATE TABLE `product` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`sku` varchar(64) NOT NULL,
`name` varchar(255) NOT NULL,
`price` decimal(10,2) NOT NULL,
`region` varchar(10) NOT NULL,
`created_at` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
同样在 `db_product_europe` 中执行相同建表语句。
### 第三步:配置 MyCat 的 schema.xml
修改 `/usr/local/mycat/conf/schema.xml`,定义逻辑库和分片规则。
```xml
```
### 第四步:配置 rule.xml 定义分片规则
修改 `/usr/local/mycat/conf/rule.xml`,添加 region 分片函数。
```xml
region
jump-consistent-hash
2
```
这里使用 Jump Consistent Hash 算法,直接将 region 字符串映射到 0 或 1 两个分片。
### 第五步:启动 MyCat 并测试
```bash
cd /usr/local/mycat
./bin/mycat start
```
连接 MyCat 逻辑库(端口 8066):
```bash
mysql -u root -p -h 127.0.0.1 -P 8066
```
插入测试数据:
```sql
INSERT INTO product (sku, name, price, region, created_at) VALUES ('SKU_001', '商品A', 12.50, 'asia', NOW());
INSERT INTO product (sku, name, price, region, created_at) VALUES ('SKU_002', '商品B', 20.00, 'europe', NOW());
```
查询所有数据,自动从两个分片合并返回。
## 避坑指南:这些错误新手容易犯
- **忘记给分片键建索引** – 跨境商品查询常按 region + 时间,建议在 region 和 created_at 上建联合索引。
- **跨分片 JOIN 导致性能下降** – 尽量避免跨库 JOIN,可将关联数据冗余到同一个分片,或者使用 MyCat 的全局表功能。
- **事务问题** – MyCat 默认不支持跨库 XA 事务,如果在一次请求中更新多个分片,要么保证操作顺序,要么使用柔性事务方案。
- **数据迁移不完整** – 从单表迁移到分片时,先导出一部分数据并校验分片规则是否正确,再全量迁移。
## 效果验证:性能对比与检查
插入 10 万条数据(亚洲和欧洲各一半),对比单表查询和分片后查询速度。通过 `EXPLAIN` 查看执行计划,确保只查询了目标分片。
```sql
-- 查询亚洲商品,只应访问 asia 分片
SELECT * FROM product WHERE region='asia' LIMIT 10;
```
在 MyCat 管理端口(9066)执行 `show @@datanode;` 查看每个分片的连接状态和负载。
## 常见问题解答
**Q:分片键选错了怎么办?**
A:需要重新配置规则并重新分布数据,建议先用测试环境验证。
**Q:百万级数据量,分两个库够吗?**
A:取决于单库性能。如果单库能支撑 50 万行正常查询,两个库即可。数据量继续增长时可增加分片数量,MyCat 支持动态扩容。
**Q:跨境商品数据中 region 字段值不规范如何清洗?**
A:写入前先通过统一编码(如 ISO 3166)映射为字符串,避免手动输入。
如果你正在处理百万级跨境商品数据的分库分表,建议先按照本文步骤在测试环境走一遍,再根据实际数据量调整分片数量和中间件参数。遇到异常时优先检查 rule.xml 和 schema.xml 的节点配置。