mysqldump不适用于直接导入,因其仅导出sql语句,无法处理表结构差异、外键约束、自增id冲突、字段类型转换及业务逻辑映射等问题;真正可控同步需用cli脚本分批读写并做数据转换。

为什么不能直接用 mysqldump + mysql 导入
因为表结构可能不一致、外键约束会报错、自增 ID 冲突、时间戳字段被覆盖、部分表需要过滤或转换数据。CLI 脚本的核心价值不是“复制”,而是“可控同步”——比如只同步 users 和 orders 表,跳过日志表,把旧库的 status 字段映射为新库的 state,且保留新库已有的管理员用户。
用 PDO 分批读写避免内存溢出和超时
一次性 SELECT * 几百万行会吃光 PHP 内存,INSERT INTO ... VALUES (...),(...) 一条语句塞太多值又容易触发 max_allowed_packet。必须分页+批量插入:
// 每次取 5000 行,按主键递增拉取
$stmt = $source->prepare("SELECT * FROM users WHERE id > ? ORDER BY id LIMIT 5000");
$stmt->execute([$lastId]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
<p>// 批量插入,每 500 行一组
foreach (array_chunk($rows, 500) as $chunk) {
$placeholders = str_repeat('(?, ?, ?),', count($chunk) - 1) . '(?, ?, ?)';
$sql = "INSERT INTO users (id, name, email) VALUES $placeholders
ON DUPLICATE KEY UPDATE name=VALUES(name), email=VALUES(email)";
$target->prepare($sql)->execute(array_merge(...array_map(fn($r) => [$r['id'], $r['name'], $r['email']], $chunk)));
}
</p>
- 一定要用
ORDER BY id+WHERE id > ?分页,别用LIMIT offset, size,大数据量下性能断崖式下降 -
ON DUPLICATE KEY UPDATE比先DELETE再INSERT更安全,避免中间状态丢失 - 目标库必须有主键或唯一索引,否则
ON DUPLICATE KEY UPDATE不生效
处理字段类型与默认值差异
旧库 created_at 是 INT 时间戳,新库是 DATETIME;旧库 is_active 是 TINYINT(1),新库是 ENUM('active','inactive')。硬拷贝会失败,得在 PHP 层做转换:
$row['created_at'] = date('Y-m-d H:i:s', (int)$row['created_at']);
$row['is_active'] = $row['is_active'] ? 'active' : 'inactive';
- 别依赖 MySQL 的自动类型转换,PHP 里显式转更可控
- 注意
NULL值:如果目标字段不允许NULL,但源数据有空值,脚本得提供默认值(如$row['updated_at'] ?? date('Y-m-d H:i:s')) - 对
TEXT/MEDIUMTEXT字段,PDO 默认可能截断,需在 PDO 构造时加PDO::ATTR_STRINGIFY_FETCHES => false
CLI 脚本必须带 --dry-run 和进度反馈
没人敢让脚本直接跑在生产库上。至少要有模拟执行模式和实时计数:
php migrate.php --source=localhost:3306/db_old --target=localhost:3307/db_new --tables=users,orders --dry-run
-
--dry-run下只打印将要执行的 SQL,不真正写入 - 每次处理完一批,输出类似
[users] synced 5000/248922 rows (2.01%),用\r覆盖同一行,避免刷屏 - 记录最后同步的
id到本地.sync_state.json,断点续传用,别每次从头开始
最麻烦的永远不是代码怎么写,而是确认哪些字段真要同步、哪些业务逻辑要补、谁来核对同步后两边的数据一致性——脚本只是工具,别让它替你做决策。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











