MySQL 遷移到 PostgreSQL:完整注意事項與實務指南

隨著越來越多專案開始採用 PostgreSQL,許多原本使用 MySQL 的系統也開始進行資料庫遷移。雖然兩者同為關聯式資料庫,但在 SQL 語法、資料型別、索引機制與系統管理方式上存在不少差異。

本文整理 MySQL → PostgreSQL 遷移時最重要的注意事項,包括:

  • SQL 語法差異

  • 資料型別轉換

  • 函式差異

  • Laravel 專案調整

  • 系統資源管理

  • 遷移工具推薦

 

一、SQL 語法差異

1. 字串與引號

MySQL 與 PostgreSQL 在引號使用上有明顯不同:

MySQL PostgreSQL
'string'"string" 只能使用 'string'
`column` "column"

 

注意事項:

  • PostgreSQL 雙引號只用於識別符(table 或 column 名稱)

  • MySQL 常用的 反引號 在 PostgreSQL 不合法

建議做法:

  • 遷移時移除所有反引號

  • 表名與欄位名稱統一使用 小寫

 

 

2. LIMIT / OFFSET

MySQL 支援兩種寫法:

SELECT * FROM users LIMIT 10 OFFSET 20;

SELECT * FROM users LIMIT 20,10;

但 PostgreSQL 只支援標準寫法

SELECT * FROM users LIMIT 10 OFFSET 20;

MySQL 的 LIMIT x,y 在 PostgreSQL 無法使用

 

3. GROUP BY 行為

MySQL 在預設情況下對 GROUP BY 比較寬鬆:

SELECT name, COUNT(*) 
FROM users 
GROUP BY name;

但 PostgreSQL 嚴格遵守 SQL 標準

所有 非聚合欄位都必須出現在 GROUP BY 中。

錯誤範例:

SELECT name, email, COUNT(*)
FROM users
GROUP BY name; 

必須改為:

SELECT name, email, COUNT(*)
FROM users
GROUP BY name, email;

 

4. AUTO_INCREMENT

MySQL:

id INT AUTO_INCREMENT PRIMARY KEY

PostgreSQL 傳統寫法:

id SERIAL PRIMARY KEY

現代推薦寫法:

id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY

 

二、資料型別差異

MySQL 與 PostgreSQL 的資料型別並非完全對應。

MySQL PostgreSQL
TINYINT(1) / BOOLEAN BOOLEAN
INT UNSIGNED PostgreSQL 無 unsigned,可用 BIGINT 或 CHECK constraint
DATETIME TIMESTAMP
ENUM('a','b') TEXT + CHECK 或 CREATE TYPE
JSON JSON 或 JSONB
TINYTEXT / MEDIUMTEXT / LONGTEXT TEXT
FLOAT REAL 或 NUMERIC(p,s)

JSON vs JSONB

PostgreSQL 的 JSONB 是更推薦的選擇:

優點:

  • 支援索引

  • 查詢更快

  • 支援更多運算子

 

 

三、大小寫敏感問題

PostgreSQL 會將 未加引號的識別符自動轉為小寫

例如:

CREATE TABLE Users (...)

實際會變成: 

users

如果 MySQL 專案存在 大寫 table 或 column 名稱,遷移後可能造成錯誤。

建議:

  • 全部統一使用 小寫命名

  • 使用 snake_case

 

四、常見函式差異

MySQL 與 PostgreSQL 的函式並不完全一致。

 

MySQL PostgreSQL
NOW() NOW()
IFNULL(a,b) COALESCE(a,b)
IF(cond,a,b) CASE WHEN cond THEN a ELSE b END
GROUP_CONCAT() STRING_AGG(col, ',')
DATE_FORMAT() TO_CHAR(date, 'YYYY-MM-DD')
YEAR(col) EXTRACT(YEAR FROM col)
UNIX_TIMESTAMP() EXTRACT(EPOCH FROM NOW())
RAND() RANDOM()
CONCAT_WS() CONCAT_WS()

 

五、索引與全文搜尋

MySQL 常見:

FULLTEXT INDEX 

PostgreSQL 不相容

替代方案:

使用全文搜尋:

tsvector
tsquery

範例:

SELECT *
FROM articles
WHERE to_tsvector('english', content)
@@ to_tsquery('database');

如果是 中文搜尋

需要額外處理 分詞系統(例如 jieba)。

 

六、Transaction 行為差異

PostgreSQL 的 transaction 行為比 MySQL 更嚴格。

DDL 支援 rollback

PostgreSQL:

BEGIN;

CREATE TABLE test (...);

ROLLBACK;

MySQL 通常 無法 rollback DDL

 

Error 行為

PostgreSQL:

  • 一旦 transaction 出錯

  • 整個 transaction 會變成 aborted

必須執行:

ROLLBACK;

才能繼續執行 SQL。

 

七、Laravel 專案遷移注意

如果你的專案使用 Laravel,需要注意以下幾點。

1. Raw SQL

所有以下語句需要重新檢查:

DB::raw()
whereRaw()
orderByRaw()

可能包含 MySQL 專屬函式。

 

2. Migration

Laravel 的:

$table->increments('id');

在 PostgreSQL 會自動轉為 SERIAL

但仍建議確認:

  • 欄位型別

  • unsigned 欄位

 

3. JSON 欄位

Laravel:

$table->json('data');

PostgreSQL 建議改為:

jsonb

查詢運算子:

operator 說明
-> JSON object
->> text

 

4. Pagination

Laravel pagination 仍使用:

LIMIT + OFFSET

 但 PostgreSQL 在 大資料量 OFFSET 下效能可能下降。

可以考慮:

  • keyset pagination

  • cursor pagination

 

八、資料庫遷移工具推薦

1. pgloader(最推薦)

功能:

  • 直接從 MySQL 讀取

  • 自動轉換 schema

  • 支援 transform rules

GitHub:

https://github.com/dimitri/pgloader

2. AWS Schema Conversion Tool

適合 AWS 環境:

  • SCT + DMS

  • 可自動轉換 schema

3. mysqldump + 手動轉換

適合小型資料庫:

流程:

  1. mysqldump

  2. 修改 SQL

  3. 匯入 PostgreSQL

 

 

 

九、PostgreSQL 系統資源管理

PostgreSQL 的資源管理模式 與 MySQL 完全不同

尤其是:

  • 記憶體配置

  • 連線管理

  • VACUUM

  • WAL

 

十、記憶體配置

核心設定在:

postgresql.conf

參數 建議
shared_buffers RAM 25%
work_mem 16–64MB
maintenance_work_mem 256MB–1GB
effective_cache_size RAM 75%
wal_buffers 16–64MB

 

work_mem 陷阱

實際記憶體可能是:

work_mem × 連線數 × 查詢操作數

例如: 

work_mem = 64MB
connections = 100
sort operations = 3

可能使用:

64MB × 100 × 3 = 19GB

因此 高流量系統要特別注意

 

十一、連線管理(最重要)

PostgreSQL:

每個連線都是一個 process

而 MySQL:

每個連線是 thread

因此 PostgreSQL 連線成本更高。

每個連線約:

5MB – 10MB

 

建議使用 Connection Pooler

架構:

App → PgBouncer → PostgreSQL

常見工具:

工具 說明
PgBouncer 最輕量
pgpool-II 支援 HA
RDS Proxy AWS 託管

 

十二、VACUUM 與 Autovacuum

PostgreSQL 使用 MVCC(多版本並發控制)

UPDATE / DELETE 不會覆蓋資料,而是留下:

 dead tuple

 

需要 VACUUM 清理。

如果不清理:

  • table bloat

  • transaction id wraparound

  • database shutdown

 

Autovacuum 建議設定

autovacuum = on
autovacuum_max_workers = 3
autovacuum_vacuum_scale_factor = 0.1
autovacuum_analyze_scale_factor = 0.05

 

高寫入表建議:

ALTER TABLE logs SET (
  autovacuum_vacuum_scale_factor = 0.01
);

 

十三、WAL 管理

PostgreSQL 使用 WAL(Write-Ahead Log)

類似 MySQL 的 binlog。

重要設定:

wal_level = replica
max_wal_size = 1GB
min_wal_size = 80MB
checkpoint_completion_target = 0.9

如果沒有設定清理:

pg_wal/

可能會 塞滿磁碟。 

 

十四、磁碟 I/O 建議

建議分離資料與 WAL:

/var/lib/postgresql/data
/var/lib/postgresql/wal

 

監控 table bloat:

SELECT schemaname, tablename,
       n_dead_tup, n_live_tup
FROM pg_stat_user_tables;

 

十五、AWS 環境建議

如果使用 AWS RDS PostgreSQL

建議:

  • 使用 RDS Proxy

  • 設定 failover retry

  • 監控 CloudWatch

監控指標:

  • pg_stat_activity

  • pg_stat_bgwriter

  • pg_stat_user_tables

結論

MySQL 遷移到 PostgreSQL 最重要的三個新習慣是:

使用 connection pooler(PgBouncer / RDS Proxy)
持續監控 dead tuple 與 VACUUM
管理 WAL 空間

只要理解 PostgreSQL 的架構差異,遷移後通常可以獲得:

  • 更強的 SQL 標準支援

  • 更好的 JSON 能力

  • 更強大的索引與全文搜尋

  • 更穩定的 transaction 機制

 

如果您喜歡我們的網站,並且希望支持我們的工作,您可以考慮捐款。我們接受各種形式的捐款,包括一次性捐款和定期捐款。您的捐款將幫助我們維護和改進網站,並為用戶提供更好的體驗。

課程推薦

AI虛擬角色生成實戰班

AI虛擬角色生成實戰班

本課程將帶你從 AI 虛擬角色的概念出發,認識 AI Persona 的生成流程與應用方式,學會打造專屬自己的 AI 分身。課程中會學習 Prompt 提示詞撰寫、真人感人像生成、固定角色模板建立,並延伸出同一角色的多場景、多服裝與多情境照片。

OpenClaw 龍蝦 AI 代理人實作課:零基礎打造 AI 辦公代理人

OpenClaw 龍蝦 AI 代理人實作課:零基礎打造 AI 辦公代理人

本課程從安裝部署、身份設定、技能安裝到實戰應用,帶你從零建立一個專屬的 AI 工作助手-OpenClaw 龍蝦,這個 AI 助手可以替你蒐集情報、摘要文件、整理郵件、生成內容、定時提醒,全部自動完成。

輸入折扣碼 TC1625FR 還可以額外獲得 NT$500 優惠喔。

Google Gemini AI 多媒體生成工具應用實戰:從 Imagen 4、Veo 3、Chirp、Lyria 到 nano-banana

Google Gemini AI 多媒體生成工具應用實戰:從 Imagen 4、Veo 3、Chirp、Lyria 到 nano-banana

如何只用文字說明提示就生成不同的圖像結果?亦或是會議上的語音檔轉文字?這是一堂通盤性、全面性的Google Gemini AI多媒體生成工具應用實戰!

輸入折扣碼 TC1609EW 還可以額外獲得 NT$500 優惠喔。

AI 數據自動化工具實戰班:Google Sheet x Apps Script x NotebookLM 暨資料處理函數

AI 數據自動化工具實戰班:Google Sheet x Apps Script x NotebookLM 暨資料處理函數

本門課將教你如何善用 AI 功能與工具,進行自動分析數據提供有幫助的建議與洞察,以及使用 AI 驅動的公式自動化計算。

輸入折扣碼 TC1615VU 還可以額外獲得 NT$500 優惠喔。

3 小時掌握自動化工作新手應用實作 – n8n AI Agent

3 小時掌握自動化工作新手應用實作 – n8n AI Agent

這門課程將帶你循序漸進掌握 n8n 的自動化技巧,從基礎認識與操作入門,到進階節點應用與流程控制,再到 Google 服務的整合實作,最後延伸至部署思維與 OpenAI API 的智慧化串接。

輸入折扣碼 TC1600UY 還可以額外獲得 NT$500 優惠喔。

用 AI 生成網站? AI 高效網站設計實戰課:ChatGPT X HTML X SEO

用 AI 生成網站? AI 高效網站設計實戰課:ChatGPT X HTML X SEO

利用 AI 提升網站設計效率與 SEO 排名!了解如何透過 ChatGPT 等工具快速建立 HTML 架構,優化關鍵字與用戶體驗,讓網站更具競爭力。

輸入折扣碼 TC1533SL 還可以額外獲得 NT$500 優惠喔。

AI工作術全面學習實戰營:6 堂精選課程,學會最好用 AI 工具,翻轉你的人生

AI工作術全面學習實戰營:6 堂精選課程,學會最好用 AI 工具,翻轉你的人生

《PChome雜誌》攜手 5 位在 AI 領域的專業講師,打造上述 6 堂實用課程,教你學會時下最好用的 AI 工具,導入生成式 AI 來產製工作內容,改造並升級你的工作流程。

輸入折扣碼 ZERO2024 還可以額外獲得 NT$400 優惠喔。

HTML與SEO實戰應用—並以ChatGPT助力提升網站品質與流量

HTML與SEO實戰應用—並以ChatGPT助力提升網站品質與流量

本課程專為希望深入了解 HTML 並有效結合 SEO 策略的學員設計。我們將重點放在 HTML 的深度學習與應用上,同時穿插介紹如何透過搜索引擎優化提升網站能見度。透過即時互動式的直播教學,加上 ChatGPT 的輔助,您將學習到如何建立一個結構優良、美觀且符合 SEO 標準的網站。這不僅會提升網站的用戶體驗,還會大幅提高網站的搜索引擎排名,進而增加訪客流量和潛在客戶。
用AI強化職場競爭力 ChatGPT、Midjourney從入門到精通

用AI強化職場競爭力 ChatGPT、Midjourney從入門到精通

在快速變遷的職場中,提升競爭力成為關鍵。透過引領潮流的AI技術,ChatGPT和Midjourney將助您勇攀高峰。無論您是AI新手還是專家,這個課程將引導您從入門到精通,解密AI的奧秘,並學習如何運用於職場。
GitHub Copilot AI 程式碼編輯工具應用實務班

GitHub Copilot AI 程式碼編輯工具應用實務班

讓學員瞭解有效地使用該工具來加速開發流程、提高程式碼品質和生產力。課程重點放在以 JavaScript 程式語言為例,介紹 Copilot 的基本原理、使用方法和最佳實踐。

輸入折扣碼 TC1456JA 還可以額外獲得 NT$500 優惠喔。

ChatGPT X Clipchamp AI 生成影片、配音與字幕應用實戰班

ChatGPT X Clipchamp AI 生成影片、配音與字幕應用實戰班

掌握Clipchamp AI的操作技巧,靈活運用Clipchamp AI進行影片編輯和創作,實現創意表達和傳播目的。

輸入折扣碼 TC1451JAN 還可以額外獲得 NT$500 優惠喔。

如何串接多種數位工具資訊?Looker Studio 資料視覺化實戰班|GoogleAds x FB廣告 x GA流量數據

如何串接多種數位工具資訊?Looker Studio 資料視覺化實戰班|GoogleAds x FB廣告 x GA流量數據

Looker Studio除了可協助使用者監控網站流量、廣告成效、選擇匯入資源的管道之外,還可以將數據資料多平台整合、數據報表即時更新、數據範本可重複套用的效益,透過自動化系統,將數據全部匯入同一個報表平台,是企業不可或缺的重要工具。

輸入折扣碼 TC1270JIA 還可以額外獲得 NT$500 優惠喔。

和我們交流

加入我們的社群,裡面會有一些技術的內容、有趣的技術梗,以及職缺的分享,歡迎和我們一起討論。