資料庫異構遷移是常見架構演進場景。本文系統整理 MySQL → Oracle 遷移的 7 大核心差異點,並補充 Oracle → MySQL 反向遷移的 5 大兼容性建議,助您平滑落地。
MySQL:id INT AUTO_INCREMENT PRIMARY KEY
Oracle:需建立 Sequence 與 Trigger(或 12c+ 使用 GENERATED AS IDENTITY)。
CREATE SEQUENCE seq_tbl_id INCREMENT BY 1 START WITH 1 MAXVALUE 99999 NOCACHE NOCYCLE; CREATE OR REPLACE TRIGGER trg_tbl_id BEFORE INSERT ON tbl FOR EACH ROW BEGIN SELECT seq_tbl_id.NEXTVAL INTO :NEW.id FROM dual; END;
INSERT 時:INSERT INTO tbl (id, ...) VALUES (seq_tbl_id.NEXTVAL, ...)
MySQL 允許雙引號包裹字串;Oracle **僅支援單引號**。
遷移時:所有單引號 ' 替換為雙單引號 ''。
Oracle VARCHAR2 最大 4000 位元組。超長字串必須用 CLOB,配合 DBMS_LOB 套件讀寫。
ETL 階段需做長度檢查與非空驗證。
MySQL:SELECT * FROM t LIMIT 20, 10
Oracle 兩種經典寫法:
-- 寫法一:雙層子查詢
SELECT * FROM (
SELECT a.*, ROWNUM rn FROM (
SELECT * FROM t WHERE 條件 ORDER BY 排序
) a WHERE ROWNUM <= 30
) WHERE rn > 20;
-- 寫法二:單層子查詢(12c+ 可用 OFFSET/FETCH)
SELECT * FROM t WHERE 條件 ORDER BY 排序
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
MySQL 分 DATE/TIME/DATETIME;Oracle 單一 DATE 含年月日時分秒。
日期運算差異:
| 場景 | MySQL | Oracle |
|---|---|---|
| 當前時間 | NOW() | SYSDATE |
| 7 天前 | DATE_SUB(NOW(), INTERVAL 7 DAY) | SYSDATE - 7 |
| 日期格式化 | DATE_FORMAT(d, '%Y-%m-%d') | TO_CHAR(d, 'YYYY-MM-DD') |
Oracle LIKE '%str%' **無法使用索引**。改用 INSTR(col, 'str') > 0 可走索引(需建立 Function-Based Index),效能大幅提升。
MySQL NOT NULL 欄位可存空字串 '';Oracle NOT NULL **禁止** 空字串(視同 NULL)。
遷移腳本需將 '' 轉為 ' '(單空格)或保留 NULL,視業務邏輯決定。
Oracle 允許保留字作識別符;MySQL 禁止。
→ 避免使用保留字;若必須用,MySQL 用反引號 \`interval\` 或 tbl.interval 包裹。
Oracle Sequence → MySQL AUTO_INCREMENT。
→ 遷移腳本自動轉換;極少數需保留 Sequence 語義時,另建序號表模擬。
| Oracle | MySQL 對應 |
|---|---|
| VARCHAR2 | VARCHAR |
| NUMBER | NUMERIC / DECIMAL |
| DATE | DATETIME |
| CLOB/BLOB | TEXT / LONGBLOB |
| — | TIME(MySQL 特有) |
MySQL (InnoDB/MyISAM) 索引鍵長度上限 **1000 位元組**(UTF-8 約 333 字元)。Oracle 限制寬鬆得多。
→ 遷移前檢查複合索引定義,必要時縮減欄位長度或改用前綴索引。
DUAL、PostgreSQL LIMIT/OFFSET)。_(如 _id, _order)永不衝突。PageHelper / Dialect 層,上層業務碼零感知。Convert MySQL to Oracle 等工具時,注意「名稱轉大寫」選項控制。