最稳妥方案是导入前用mysqldump做物理备份;需校验表名路径、存于Web目录外、命名含时间戳;事务仅对INSERT类有效,须确认InnoDB引擎;大文件要分批;备份应聚焦目标表并自动清理过期文件。
mysqldump 命令做全库或单表备份最稳妥PHP 脚本执行数据导入时,一旦出错(比如字段类型不匹配、主键冲突、事务未回滚),很可能直接污染线上数据。靠 PHP 自己“先查后删再插”不是真备份,只是覆盖逻辑。真正可逆的方案,是调用系统级数据库导出工具,在导入前生成一份物理快照。
实操建议:
mysqldump,且 PHP 进程有权限执行 shell 命令(exec 或 shell_exec 未被禁用)mysqldump -h localhost -u root -p'123456' school_db student_table > /backup/student_table_20250520.sql
/backup/),避免被直接下载mysqli 或 PDO 开启事务 + 手动回滚只能应对部分错误事务能防止“导入中途失败导致数据残缺”,但它不能解决误删、误更新、结构变更等操作。如果导入脚本里混用了 DROP TABLE 或 TRUNCATE,事务也无能为力。
适用场景和限制:
INSERT 或带条件的 REPLACE/INSERT ... ON DUPLICATE KEY UPDATE 场景mysqli_begin_transaction($conn) 或 $pdo->beginTransaction()
rollback(),否则 commit()
通信录通常只涉及一两张表(如 class_student、contact_info),全库备份既慢又占空间。更合理的做法是精准备份目标表,再配合字段映射校验。
关键控制点:
SHOW CREATE TABLE class_student,记录建表语句,连同当前数据一起备份,便于快速重建PhpSpreadsheet 的 getHighestRow() 预估数据量;若超过 5000 行,建议分批导入并分批备份(或改用 CSV + LOAD DATA INFILE)SELECT COUNT(*) FROM class_student WHERE stu_id = ?),避免因重复导
md5(file_get_contents($excel_path))),可辅助判断本次导入是否与上次备份对应没人手动删备份,几天后 /backup/ 就堆满几十个 SQL 文件,磁盘爆掉比数据丢更快。
简单但有效的清理方式:
unlink() 删除上一次的临时备份(前提是本次备份已确认写入完成)find /backup -name "student_table_*.sql" -mtime +7 -delete