首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 大數據量導入導出方案:繞過 phpMyAdmin 限制的分離式腳本實現

     編輯:MySQL 資料庫相關知識

phpMyAdmin 導入導出受限於 PHP upload_max_filesize/post_max_size(默 2MB)與執行時間,超 6MB 即失敗。本文提供「結構用 phpMyAdmin,數據用腳本」的分離策略,實現 10MB+ 大庫無感遷移。

核心思路

導出腳本:export_table.php

<?php
// 用法:export_table.php?table=tablename
$table = $_GET['table'] ?? exit('Missing table param');

$conn = mysqli_connect('localhost', 'user', 'pass', 'db') or die('Connect failed');
mysqli_set_charset($conn, 'utf8');

$res = mysqli_query($conn, "SELECT * FROM `$table`");
if (mysqli_num_rows($res) === 0) exit('Empty table');

echo "開始導出數據到文本...\n";
$fp = fopen("$table.txt", 'w');
$fieldCount = mysqli_num_fields($res);
fwrite($fp, $fieldCount . "\r\n");  // 首行寫字段數

$placeholder = "&&PHP2000MySQLreturn&&";  // 換行符佔位符

while ($row = mysqli_fetch_row($res)) {
    for ($i = 0; $i < $fieldCount; $i++) {
        // 轉義換行符,防止文本行結構破壞
        $row[$i] = str_replace(["\r\n", "\n"], $placeholder, $row[$i]);
        fwrite($fp, $row[$i] . "\r\n");
    }
    fwrite($fp, "------- PHP2000 dump data program V1.0 for MySQL --------\r\n");  // 行分隔符
}
fclose($fp);
echo "ok";
?>

導入腳本:import_table.php

<?php
$table = $_GET['table'] ?? exit('Missing table param');

$conn = mysqli_connect('localhost', 'user', 'pass', 'db') or die('Connect failed');
mysqli_set_charset($conn, 'utf8');

$lines = file("$table.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if (!$lines) exit('File empty');

$fieldCount = (int)$lines[0];
$placeholder = "&&PHP2000MySQLreturn&&";
$rowDelimiter = "------- PHP2000 dump data program V1.0 for MySQL --------";

$values = [];
$rowData = [];
$lineIdx = 1;

while ($lineIdx < count($lines)) {
    $line = $lines[$lineIdx++];
    if ($line === $rowDelimiter) {
        // 一行數據讀完,構建 INSERT
        $escaped = array_map(fn($v) => "'" . mysqli_real_escape_string($conn, str_replace($placeholder, "\n", $v)) . "'", $rowData);
        $values[] = '(' . implode(',', $escaped) . ')';
        $rowData = [];
        continue;
    }
    $rowData[] = $line;
    if (count($rowData) === $fieldCount) {
        // 正常應在分隔符前湊齊,這裡作為兜底
    }
}

// 批量插入(每 500 行一條 SQL,防止過長)
$batchSize = 500;
for ($i = 0; $i < count($values); $i += $batchSize) {
    $batch = array_slice($values, $i, $batchSize);
    $sql = "INSERT INTO `$table` VALUES " . implode(',', $batch);
    if (!mysqli_query($conn, $sql)) {
        die("Insert failed at batch $i: " . mysqli_error($conn));
    }
}
echo "Import completed: " . count($values) . " rows.\n";
?>

關鍵設計細節

  1. 逐行一字段:避免 CSV 分隔符衝突,天然支持任意文本內容(含逗號、引號、換行)。
  2. 佔位符轉義:\r\n/\n → &&PHP2000MySQLreturn&&,導入時還原。
  3. 行分隔符:固定特征字符串標記行邊界,解析邏輯極簡健壯。
  4. 首行字段數:自適應表結構變更,導入端無需硬編碼。
  5. 批量 INSERT:500 行一批,平衡 SQL 長度與網絡往返開銷。
  6. mysqli_real_escape_string:導入時二次轉義,防注入並處理引號。

擴展建議:生產級遷移工具鏈

  • mysqldump + 管道壓縮:mysqldump -u root -p --single-transaction --quick --hex-blob db | gzip > db.sql.gz,導入 zcat db.sql.gz | mysql -u root -p db,官方標準、支持並行、事務一致性。
  • mydumper/myloader:多線程並行導出導入,大表自動切塊,速度提升 5-10 倍。
  • CDC 同步:Canal/Debezium 捕獲 Binlog 實時同步異構目標,零停機遷移。

總結

phpMyAdmin 適合小表可視化操作;大數據量遷移必須繞過 HTTP/ PHP 限制,採用「結構與數據分離、文本流式處理、批量寫入」的工程化方案。上述腳本為教學級演示,生產環境請優先使用 mysqldump/mydumper 或 CDC 工具,獲得事務一致性、斷點續傳、並行加速等企業級能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
階段工具操作
導出結構phpMyAdmin「導出」→ 選「結構」→ 保存 schema.sql
導出數據PHP 腳本逐行讀取表數據 → 文本文件 table.txt(每行一字段,特殊字符轉義)
導入結構phpMyAdmin「導入」schema.sql 重建表結構
導入數據PHP 腳本讀取 table.txt → 反轉義 → 批量 INSERT