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

從 SQL Server 遷移資料到 MySQL 完整實戰指南:兩種方案深度比較與最佳實踐

     編輯:MySQL 資料庫相關知識

遷移背景與挑戰

專案需將 SQL Server 資料庫完整遷移至 MySQL。經調研發現兩種主流方案:ODBC 直接匯出與腳本程式化遷移。實測後發現前者雖簡便但陷阱眾多,後者雖需編碼但掌控度高、適應性強。本文詳細記錄踩坑經驗與解決方案,供同類需求參考。

方案一:ODBC 直接匯出 —— 看似美好,實則暗坑

操作流程

  1. 安裝 MySQL ODBC Driver
  2. SQL Server Management Studio → 任務 → 匯出資料
  3. 資料來源選擇 MySQL ODBC DSN
  4. 勾選資料表,一鍵完成

致命缺陷

結論:僅適合結構簡單、無特殊型別、型別映射無要求的測試環境。生產環境強烈不推薦。

方案二:程式化遷移(PHP / ASP) —— 掌控每一行資料

核心優勢

  • 型別轉換完全可控(如 DATETIME → Unix Timestamp)
  • 可針對特殊欄位自訂處理邏輯
  • 支援分批、斷點續傳、錯誤重試
  • 大物件欄位可轉檔案存儲,資料庫只存路徑

前置準備

  1. MySQL 環境就緒
  2. 目標資料庫、表結構已建立(含索引、外鍵)
  3. SQL Server 建立 System DSN(範例名 web)

PHP 遷移腳本範例

<?php
// 連接 SQL Server (via ODBC)
$cnx = odbc_connect('web', 'admin', '123456');
$cur = odbc_exec($cnx, 'SELECT * FROM user');

// 連接 MySQL
$conn = mysql_pconnect('localhost', 'root', '123456');
mysql_select_db('mydb', $conn) or die('無法連接資料庫');

$num_row = 0;
while (odbc_fetch_row($cur)) {
    $num_row++;
    
    // 逐欄讀取(索引從 1 開始)
    $field1 = odbc_result($cur, 1);  // id
    $field2 = odbc_result($cur, 2);  // name
    $field3 = odbc_result($cur, 3);  // username
    $field4 = odbc_result($cur, 4);  // password
    $field5 = odbc_result($cur, 5);  // recdate (DATETIME)
    
    // 關鍵轉換:DATETIME → Unix Timestamp (INT)
    $field5 = datetime_to_timestamp($field5);
    
    // 參數化查詢防注入(生產環境建議用 PDO + prepared statements)
    $sql = sprintf(
        "INSERT INTO user (id, name, username, password, recdate) VALUES ('%s','%s','%s','%s',%d)",
        mysql_real_escape_string($field1),
        mysql_real_escape_string($field2),
        mysql_real_escape_string($field3),
        mysql_real_escape_string($field4),
        $field5
    );
    mysql_query($sql, $conn);
}

function datetime_to_timestamp($str) {
    // 格式:YYYY-MM-DD HH:MM:SS
    list($date, $time) = explode(' ', $str);
    list($y, $m, $d) = explode('-', $date);
    list($h, $i, $s) = explode(':', $time);
    return mktime($h, $i, $s, $m, $d, $y);
}
?>

ASP 遷移腳本範例(含 SQL Server 端轉換)

<%
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "web", "admin", "123456"

' SQL Server 端直接用 DATEDIFF 轉 Unix Timestamp (扣除 8 小時時區)
sql = "SELECT ID, name, username, password, " & _
      "DATEDIFF(s, '1970-01-01 00:00:00', recdate) - 8*3600 AS rects, " & _
      "reid, filename, fileContentType, filevalue FROM senddate"

Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open sql, conn, 1, 3

Set conn1 = Server.CreateObject("ADODB.Connection")
conn1.Open "myoa", "root", "q1-d6=7?"

Do While Not rs.EOF
    f1 = rs(0): f2 = rs(1): f3 = rs(2): f4 = rs(3): f5 = rs(4)
    sql1 = "INSERT INTO user (ID, name, username, password, recdate) " & _
           "VALUES (" & f1 & ",'" & f2 & "','" & f3 & "','" & f4 & "'," & f5 & ")"
    conn1.Execute sql1
    rs.MoveNext
Loop

rs.Close: conn.Close: conn1.Close
%>

特殊型別處理:大物件欄位的檔案化策略

針對 ntext、image 無法直接遷移的問題,採用「落地為檔、庫存路徑」方案:

ntext → nvarchar(4000) + 截斷風險評估

  • 實測原始資料長度均 < 4000 字元,改型別無資料遺失
  • 若超長需分段存儲或改用 LONGTEXT

image → 檔案系統 + ASP 處理函數

Function makeattach(contentType, binaryData, idx)
    ' 依 MIME 判斷副檔名
    Select Case contentType
        Case "application/msword": ext = "doc"
        Case "application/vnd.ms-excel": ext = "xls"
        Case "image/jpeg": ext = "jpg"
        ' ... 其餘略
        Case Else: ext = "bin"
    End Select
    
    If ext <> "bin" Then
        Dim fso, fName, Dir, strm
        Set fso = Server.CreateObject("Scripting.FileSystemObject")
        fName = "attach" & idx & "." & ext
        Dir = "D:\attach\"
        
        ' 寫入二進位檔案
        Set strm = Server.CreateObject("ADODB.Stream")
        strm.Type = 1  ' adTypeBinary
        strm.Open
        strm.Write binaryData
        strm.SaveToFile Dir & fName, 2  ' adSaveCreateOverWrite
        strm.Close
        Set strm = Nothing
        
        makeattach = fName  ' 回傳檔名存入資料庫
    Else
        makeattach = ""
    End If
End Function

遷移檢查清單與最佳實踐

問題表現影響
大物件型別不支援ntext、image 欄位無法寫入資料遺失,需手工處理
時間型別衝突目標表用 INT 存 Unix 時間戳,來源為 DATETIME匯入失敗或資料錯誤
欄位型別映射不準自動生成的 MySQL 表結構往往不符預期後續查詢效能差、應用報錯
階段關鍵動作
前置目標表結構先行建立、索引優化、字符集統一 (utf8mb4)
過程分批提交 (每 500-1000 筆 COMMIT)、記錄失敗 PK 供重跑、監控磁碟/記憶體
驗證行數比對、關鍵欄位抽樣比對、MD5 校驗大欄位、應用端冒煙測試
事後更新統計資訊 (ANALYZE TABLE)、重建索引、監控慢查詢

現代化替代工具推薦

  • pt-archiver (Percona Toolkit):高效分頁遷移、支援條件過濾、可暫停恢復
  • MySQL Workbench Migration Wizard:圖形化、支援異構遷移、型別映射可視化調整
  • DataX / Canal + Kafka:企業級同步平台、支援增量同步、斷點續傳
  • Python + SQLAlchemy + Pandas:靈活腳本化、資料清洗轉換強、單元測試友善

總結

SQL Server 遷移 MySQL 的核心難點在於型別系統差異與大物件處理。ODBC 直接匯出雖省時但不可控,程式化遷移雖需開發成本,卻能精準處理每個轉換細節,確保資料完整性與業務連續性。建議採用「腳本遷移 + 校驗腳本 + 回滾預案」的標準化流程,並優先評估現代化遷移工具降低維護負擔。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved