萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

PHP MySQL 資料庫備份腳本:完整結構與資料匯出實作

功能特性

  • 自動遍歷資料庫所有資料表
  • 匯出 CREATE TABLE 結構定義
  • 匯出所有資料為 INSERT 語句
  • 自動命名備份檔:YYYYMMDD.sql
  • UTF-8 編碼支援

完整程式碼(mysqli 重構版)

<?php
/**
 * MySQL 資料庫完整備份腳本
 * 輸出:YYYYMMDD.sql 包含結構與資料
 */

// ===== 設定區 =====
$host = 'localhost';
$user = 'root';
$pass = '';
$dbname = 'your_database';
$charset = 'utf8mb4';
// ===================

$mysqli = new mysqli($host, $user, $pass, $dbname);
if ($mysqli->connect_errno) {
    die('連線失敗: ' . $mysqli->connect_error);
}
$mysqli->set_charset($charset);

$sql = "SET NAMES $charset;\r\n\r\n";

// 取得所有資料表
$tablesResult = $mysqli->query("SHOW TABLES");
if (!$tablesResult) {
    die('SHOW TABLES 失敗: ' . $mysqli->error);
}

while ($tableRow = $tablesResult->fetch_array(MYSQLI_NUM)) {
    $table = $tableRow[0];
    
    // 1. 匯出表結構
    $createResult = $mysqli->query("SHOW CREATE TABLE `$table`");
    if ($createResult) {
        $createRow = $createResult->fetch_assoc();
        $sql .= $createRow['Create Table'] . ";\r\n\r\n";
        $createResult->free();
    }
    
    // 2. 匯出資料
    $dataResult = $mysqli->query("SELECT * FROM `$table`");
    if ($dataResult && $dataResult->num_rows > 0) {
        $fields = [];
        while ($field = $dataResult->fetch_field()) {
            $fields[] = '`' . $field->name . '`';
        }
        $fieldList = implode(', ', $fields);
        
        while ($row = $dataResult->fetch_assoc()) {
            $values = [];
            foreach ($row as $val) {
                if ($val === null) {
                    $values[] = 'NULL';
                } else {
                    $values[] = "'" . $mysqli->real_escape_string($val) . "'";
                }
            }
            $sql .= "INSERT INTO `$table` ($fieldList) VALUES (" . implode(', ', $values) . ");\r\n";
        }
        $dataResult->free();
    }
    $sql .= "\r\n";
}

$tablesResult->free();

// 寫入檔案
$filename = date('Ymd') . '.sql';
$fp = fopen($filename, 'w');
fwrite($fp, $sql);
fclose($fp);

$mysqli->close();

echo "備份成功!檔案:$filename (" . number_format(strlen($sql) / 1024, 2) . " KB)";
?>

關鍵改進說明

原版問題改進方案
使用已棄用 mysql_* 函數全面改用 mysqli 物件導向介面
無字元集設定,中文易亂碼明確 SET NAMES utf8mb4 + set_charset
手動組合欄位名,易出錯使用 fetch_field() 取得標準欄位名
NULL 值處理不當明確判斷 null 輸出 NULL 而非空字串
無錯誤處理與資源釋放完整錯誤檢查、free() 釋放結果集
單一巨大字串佔記憶體大型資料庫建議改用檔案流式寫入

生產環境強化建議

  1. 分檔備份:每表一個 .sql 檔,壓縮打包
  2. 單一事務一致性備份:加入 --single-transaction 邏輯(需 InnoDB)
  3. 排除不需備份的表:如 log、cache、session 表
  4. 上傳至異地儲存:S3、FTP、NAS 等
  5. 定時任務:crontab -e → 0 2 * * * /usr/bin/php /path/backup.php
  6. 驗證機制:定期測試還原,確保備份可用性

還原方式

# 命令列還原
mysql -u root -p dbname < 20240115.sql

# 或 PHP 執行
$mysqli->multi_query(file_get_contents('20240115.sql'));
copyright © 萬盛學電腦網 all rights reserved