You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅用PHP备份MariaDB单个数据集?删除前备份待删数据的最优方案

嘿,我来帮你搞定这两个PHP+MariaDB的问题,都是日常开发里很实用的场景:

一、仅用PHP备份MariaDB单个数据集

这里分两种常见场景,你可以根据需求选择:

1. 备份单个完整数据表

如果要备份某张表的全部数据(结构+内容),用PHP结合PDO导出SQL是最稳妥的方式,恢复时直接执行SQL就能还原。给你写个完整的可复用示例:

<?php
// 数据库连接信息
$dsn = 'mysql:host=localhost;dbname=your_database;charset=utf8mb4';
$username = 'your_username';
$password = 'your_password';

try {
    $pdo = new PDO($dsn, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $targetTable = 'your_target_table';
    $backupFilename = "{$targetTable}-backup-" . date('Y-m-d-His') . '.sql';

    // 先导出表结构(恢复时需要重建表)
    $createStmt = $pdo->query("SHOW CREATE TABLE `{$targetTable}`");
    $createSql = $createStmt->fetch(PDO::FETCH_ASSOC)['Create Table'] . ";\n\n";

    // 导出表数据为INSERT语句
    $dataStmt = $pdo->query("SELECT * FROM `{$targetTable}`");
    $allRows = $dataStmt->fetchAll(PDO::FETCH_ASSOC);

    $insertSql = '';
    if (!empty($allRows)) {
        $columns = implode('`, `', array_keys($allRows[0]));
        $insertSql .= "INSERT INTO `{$targetTable}` (`{$columns}`) VALUES\n";
        
        $valueRows = [];
        foreach ($allRows as $row) {
            // 用PDO的quote方法自动转义,避免SQL注入
            $escapedVals = array_map(fn($val) => $pdo->quote($val), $row);
            $valueRows[] = '(' . implode(', ', $escapedVals) . ')';
        }
        $insertSql .= implode(",\n", $valueRows) . ";";
    }

    // 写入备份文件
    file_put_contents($backupFilename, $createSql . $insertSql);
    echo "备份完成,文件:{$backupFilename}";
} catch (PDOException $e) {
    die("备份失败:" . $e->getMessage());
}
?>

2. 备份即将删除的特定数据集

如果只是要备份清理脚本里要删除的那批记录,不用导出整个表,先查询目标数据备份,再执行删除:

<?php
// 数据库连接部分同上...

// 你的删除条件,比如过期的记录
$deleteCondition = "expire_time < NOW()";

// 第一步:查询要删除的数据并备份
$selectStmt = $pdo->prepare("SELECT * FROM `your_target_table` WHERE {$deleteCondition}");
$selectStmt->execute();
$rowsToBackup = $selectStmt->fetchAll(PDO::FETCH_ASSOC);

// 先选JSON格式备份,后面会说为什么比序列化好
$backupJson = json_encode($rowsToBackup, JSON_PRETTY_PRINT);
file_put_contents("deleted-records-backup-" . date('Y-m-d-His') . '.json', $backupJson);

// 第二步:执行删除
$deleteStmt = $pdo->prepare("DELETE FROM `your_target_table` WHERE {$deleteCondition}");
$deleteStmt->execute();

echo "已备份" . count($rowsToBackup) . "条记录并完成删除!";
?>
二、替代序列化写入的更优方案

你说的序列化方案确实能工作,但有几个硬伤:序列化内容完全不可读,没法手动检查数据;而且PHP版本更新可能导致序列化格式不兼容,跨版本恢复容易出问题。给你推荐几个更实用的方案:

1. JSON格式(首推)

优点太多了:人类可读,用普通文本编辑器就能查看内容;跨语言兼容,就算以后用其他语言恢复也没问题;PHP的json_encode/json_decode处理起来超级方便。恢复时的代码示例:

<?php
// 连接数据库同上...

$backupData = json_decode(file_get_contents('deleted-records-backup-xxxxxx.json'), true);
foreach ($backupData as $row) {
    $columns = implode('`, `', array_keys($row));
    $placeholders = ':' . implode(', :', array_keys($row));
    $insertStmt = $pdo->prepare("INSERT INTO `your_target_table` (`{$columns}`) VALUES ({$placeholders})");
    $insertStmt->execute($row);
}
echo "恢复完成!";
?>

2. CSV格式(适合大数据量)

如果要备份的记录特别多,CSV文件体积比JSON小,而且可以直接用Excel、Numbers打开查看,适合需要做数据核对的场景:

// 备份时
$fp = fopen('deleted-records-backup-' . date('Y-m-d-His') . '.csv', 'w');
// 先写入表头(字段名)
fputcsv($fp, array_keys($rowsToBackup[0]));
// 逐行写入数据
foreach ($rowsToBackup as $row) {
    fputcsv($fp, $row);
}
fclose($fp);

// 恢复时
$fp = fopen('deleted-records-backup-xxxxxx.csv', 'r');
$headers = fgetcsv($fp); // 读取表头
while ($rowData = fgetcsv($fp)) {
    $row = array_combine($headers, $rowData);
    // 插入数据库的代码和JSON恢复时一致
    $columns = implode('`, `', $headers);
    $placeholders = ':' . implode(', :', $headers);
    $insertStmt = $pdo->prepare("INSERT INTO `your_target_table` (`{$columns}`) VALUES ({$placeholders})");
    $insertStmt->execute($row);
}
fclose($fp);

3. SQL INSERT语句

如果备份的目的就是为了以后快速恢复到数据库,直接导出成INSERT语句最方便,恢复时不用写PHP代码,直接把SQL文件导入MariaDB就行(比如用phpMyAdmin或者mysql命令行)。具体代码参考第一个场景里生成INSERT语句的部分。

4. 调用mysqldump(高效但需权限)

如果你的服务器允许PHP执行系统命令,用mysqldump备份单个表效率更高,尤其是数据量极大的时候。注意一定要做好参数过滤,防止命令注入:

<?php
$dbName = 'your_database';
$tableName = 'your_target_table';
$backupFile = "{$tableName}-backup-" . date('Y-m-d-His') . '.sql';
// 用escapeshellarg处理参数,避免命令注入
$command = sprintf(
    "mysqldump -u %s -p%s %s %s > %s",
    escapeshellarg('your_username'),
    escapeshellarg('your_password'),
    escapeshellarg($dbName),
    escapeshellarg($tableName),
    escapeshellarg($backupFile)
);
exec($command, $output, $returnCode);

if ($returnCode === 0) {
    echo "备份成功:{$backupFile}";
} else {
    echo "备份失败,错误信息:" . implode("\n", $output);
}
?>
总结一下
  • 备份单个数据集:整表备份优先选SQL导出或mysqldump;特定记录备份用JSON或CSV更灵活。
  • 替代序列化:首推JSON(兼顾易用性和可读性),大数据量选CSV,要直接恢复选SQL。

内容的提问来源于stack exchange,提问作者Steven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:01:01