MySQLからPostgreSQLへ移行する前の診断項目
「pgvectorを使いたいのでPostgreSQLに移行したい」「Oracleのライセンス費用が重いのでオープンソースに寄せたい」——最近こういう相談が増えています。ただ話を聞くと、移行のモチベーションはあっても「何がどう変わって、どこにリスクがあるか」を具体的に把握しないまま計画が進んでいるケースが少なくありません。
DB移行はアプリケーションの書き換えとは違い、失敗すると本番データそのものに影響が及びます。この記事では、MySQLからPostgreSQLへの移行を検討する際に、着手前に必ず確認すべき診断項目と、そもそも移行すべきかどうかの判断軸を整理します。
なぜ今MySQL→PostgreSQLの相談が増えているか
移行を検討する理由は、多くの場合この3つのどれかです。
- pgvectorなどAI関連機能を使いたい: 類似検索・embedding保存をアプリケーション側の外部サービスに頼らず、DB内で完結させたい
- ライセンス・運用コストの見直し: マネージドMySQL(Aurora MySQL等)からの移行や、将来的な商用RDBMSからの脱却
- 開発チームの技術選好: 新規メンバーがPostgreSQL前提の経験を持ち、複雑なクエリやJSONBの扱いやすさを評価している
理由自体は妥当ですが、「やりたい理由」と「今のDBがそれに耐えられない理由」は分けて検討する必要があります。pgvector目当てなら、実は既存のMySQL構成に手を入れずに外部のベクトルDBを併用するだけで済むケースもあります。移行ありきで話を進める前に、次の診断を済ませてください。
診断項目1: データ型の差分
MySQLとPostgreSQLは似ているようで、データ型の挙動が異なります。移行前に必ず洗い出すべき差分です。
- 文字列型の暗黙の切り詰め: MySQLは
VARCHARの上限を超える値を(設定によっては)警告付きで切り詰めて保存することがある。PostgreSQLはエラーで弾く。移行時に「実は上限を超えたデータが本番に眠っている」ことが発覚するのはよくあるパターン - 真偽値の表現: MySQLは
TINYINT(1)を真偽値代わりに使うことが多く、PostgreSQLのネイティブなBOOLEANとは別物。ORMのマッピング設定を含めて確認する - 日時型のタイムゾーン挙動: MySQLの
DATETIMEはタイムゾーン情報を持たないが、TIMESTAMPは接続のタイムゾーン設定に依存して変換される。PostgreSQLのtimestamp with time zoneと単純に対応させると、過去データの時刻がずれることがある - AUTO_INCREMENTとSERIAL/IDENTITY: 採番の再開値や欠番の扱いが異なる。移行後に採番がリセットされ、既存IDと衝突するリスクがある
- 文字コード・照合順序(collation): MySQLの
utf8mb4とPostgreSQLのUTF8は基本的に対応するが、ソート順(照合順序)は別物。ORDER BYの結果が移行前後で変わることがあり、五十音順や絵文字を含む文字列で顕在化しやすい
これらは「移行スクリプトを流せば終わり」ではなく、実際のデータを抽出して型ごとに境界値を確認する作業が要ります。
診断項目2: SQL方言と機能依存
アプリケーションコードやSQLがMySQL固有の書き方に依存している範囲を洗い出します。
- ON DUPLICATE KEY UPDATE: PostgreSQLでは
INSERT ... ON CONFLICT DO UPDATEに書き換えが必要。構文が違うだけでなく、複合ユニーク制約がある場合は制約名の指定方法も変わる - LIMIT句のoffset構文や、GROUP BYの緩さ: MySQLは
GROUP BYに含まれない列をSELECTしても(設定次第で)エラーにならないことがあるが、PostgreSQLは厳密にチェックする。「動いていたが実は結果が不定だったクエリ」が移行時にエラーとして表面化する - 大文字小文字の扱い: MySQL(多くの環境)はテーブル名・カラム名の大文字小文字を区別しないが、PostgreSQLはダブルクォートなしの識別子を自動的に小文字化する。ORMが生成するSQLやマイグレーション履歴に混在があると事故る
- ストアドプロシージャ・トリガー・ビュー: MySQL固有の構文で書かれていれば、PL/pgSQLへの書き換えが必要。地味に見落とされがちだが、業務ロジックがDB側に埋まっている場合は移行コストの大部分をここが占める
- 全文検索: MySQLの
FULLTEXTインデックスを使っていれば、PostgreSQLのtsvector/GINインデックスへの設計変更が必要。挙動(トークナイズ・言語対応)も異なるため、検索結果の再現性を検証する工程が要る - JSON関数: 両者ともJSON型を持つが、関数名・演算子が異なる(
JSON_EXTRACTと->/->>など)。JSON型カラムに依存したクエリがあれば全数洗い出しが必要
このあたりはORM(ActiveRecord等)を使っていても、生SQLやDB固有関数呼び出しが紛れ込んでいることが多いので、grepだけでなく実際にステージング環境で全クエリを流して検証するのが確実です。
診断項目3: データ量と移行時間の見積もり
「移行できるか」の次に問題になるのは「どれくらい止まるか」です。
- 総データ量とテーブルごとの行数: 数百万行を超えるテーブルがあれば、単純なダンプ&リストアで数時間〜が現実的な所要時間になる
- インデックス再構築の時間: PostgreSQL側でインデックスを作り直す時間はデータ量に比例する。特に全文検索用のGINインデックスは構築コストが高い
- ピークトラフィックとの兼ね合い: 深夜バッチや月末処理など、止められない時間帯がどれだけあるか
- 許容できるダウンタイム: 事業側が許容できる停止時間を先に確認する。「止めてはいけない」なら後述の無停止移行が前提になり、コストと期間が変わる
この見積もりは本番相当のデータ量でリハーサルしないと精度が出ません。開発環境の小さいデータでは一瞬で終わる処理が、本番では数時間かかることも珍しくありません。
移行方式の選び方
停止移行(一括切り替え)
メンテナンスウィンドウを設けてサービスを止め、その間にダンプ&リストアして切り替える方式です。
- 向いているケース: 深夜帯や休日にダウンタイムを許容できる、データ量が比較的小さい(数十万行〜数百万行程度)、社内向けシステムなど
- リスク: 想定より移行時間が伸びると、ダウンタイムが長引く。事前のリハーサルで所要時間を実測しておくことが必須
無停止移行(二重書き込み)
アプリケーションから新旧両方のDBに書き込みつつ、データ突合を経て段階的に読み取りを切り替える方式です。既存プロダクトのDB設計を安全に見直す進め方で扱った「新旧テーブルの並存」と同じ考え方を、DBエンジンをまたぐ形で適用します。
- 向いているケース: 24時間稼働が求められるtoCサービス、SLAでダウンタイムが制約されている契約がある場合
- コスト: アプリケーション側に「両方に書き込むレイヤー」を一時的に追加する開発コストがかかる。移行専用のミドルウェア(pgloaderの継続的レプリケーション機能や、CDCツールを使った差分同期)を使う選択肢もあるが、いずれも構築・検証の工数は無視できない
- 期間: 二重書き込みと突合の期間を短くしすぎると検証が甘くなる。目安としては本番トラフィックの1〜2週間分は並走させ、異常がないことを確認してから読み取りを切り替える
どちらを選ぶかは、事業側の許容ダウンタイムとエンジニアリングコストのトレードオフです。「無停止が理想」と決め打ちせず、実際に何時間なら止められるかを先に確認すると、多くの場合停止移行で十分だと分かります。
そもそも移行すべきか
ここまで診断項目を並べましたが、正直に言うと移行しない方がいいケースも一定数あります。
- pgvectorが目的なら、外部のベクトルDB併用で足りることが多い: 検索対象データ量が小さい、あるいは既存のMySQL構成を崩したくないなら、Pinecone・pgvector以外のベクトル検索サービスをMySQLと併用する構成で十分なケースが多い。DB全体を移行する前に、まず「本当にPostgreSQL本体でなければ実現できない機能か」を切り分ける
- ストアドプロシージャ・トリガーへの依存が深い: 業務ロジックの大部分がDB側に実装されているプロダクトは、書き換えコストが移行のメリットを上回ることがある。まずアプリケーション側へロジックを引き剥がす改修を先にやる方が費用対効果が高い場合もある
- チームにPostgreSQL運用経験がない: 移行した直後に運用でつまずくと、移行のメリットより「新しいDBの学習コスト」が上回る。移行前にステージング環境で最低でも1〜2ヶ月は運用を経験しておきたい
- 「なんとなく新しい方がいい」が動機になっている: 明確な機能要件やコスト削減の試算がない移行は、優先順位が事業インパクトの小さい改修に埋もれがちで、着手しても中断されやすい
移行すべきかどうかの一般的な判断軸(改修とリプレイスの見極め)は既存プロダクト改善の最初の確認観点でも扱っています。DB移行はその中でも特にリスクが本番データに直結する領域なので、「やりたい理由」を事業インパクトに換算してから着手を判断してください。
外注する場合の進め方
DB移行を外部チームに依頼する場合、次の点を発注前に確認すると安心です。
- 診断フェーズを分離して提示できるか: いきなり移行作業を見積もるのではなく、上記のようなデータ型・SQL方言・データ量の診断を独立した工程として先に提案してくるか
- 本番相当データでのリハーサル計画があるか: 開発環境の小さいデータだけで「移行できます」と言っていないか
- ロールバック手順があるか: 移行後に問題が見つかった場合、旧DBに切り戻せる手順と期間が計画に含まれているか
- 移行しない選択肢も提示するか: 診断の結果「今は移行しない方がいい」と正直に言えるパートナーかどうかは、技術力以上に信頼できるかの指標になる
私たちが対応するデータベース関連の技術スタックの詳細はデータベース関連の技術ページに、進め方全体はモダナイゼーション支援サービスにまとめています。
まとめ
- MySQLからPostgreSQLへの移行前には、データ型の差分・SQL方言と機能依存・データ量と移行時間の3点を必ず診断する
- 移行方式は事業が許容できるダウンタイムで決める。止められないなら二重書き込みによる無停止移行、止められるなら停止移行で十分なことが多い
- pgvectorやライセンス費用が動機でも、移行しない選択肢(外部サービス併用、ロジックの引き剥がしを先にやる等)を含めて誠実に検討する価値がある
MySQLからPostgreSQLへの移行を検討していて、何から手を付ければいいか分からないという方は、まず診断から始めることをおすすめします。torcheeesでは既存プロダクト改善の診断と、継続的な改善支援を提供しています。まずはお問い合わせフォームから現状を聞かせてください。