2026年6月28日
2026年6月28日
PostgreSQLのFOREIGN DATA WRAPPERの活用|postgres_fdwで別DBのテーブルを参照する手順
PostgreSQL の FOREIGN DATA WRAPPER(FDW)を使うと、別のサーバーにあるデータベースのテーブルや CSV ファイルを、手元のデータベースの「外部テーブル」として SELECT できます。データを毎回エクスポートして取り込まなくても、複数のデータベースをまたいだ集計や、移行時の突き合わせがしやすくなります。この記事では、標準で付属する postgres_fdw を中心に、接続の設定、外部テーブルの作り方、性能を左右する「プッシュダウン」の確認、権限とパスワードの扱い、運用上の注意までを説明します。
WordPress 本体は MySQL / MariaDB を前提としており、PostgreSQL は公式にはサポートされていません(2026年10月現在)。この記事は、WordPress とは別に PostgreSQL を分析用・業務用に運用している場面を想定しています。WordPress の MySQL を PostgreSQL 側から参照する方法については、後半で注意点とあわせて触れます。
FDWの仕組みと主な種類
FDW は、外部のデータ源と PostgreSQL をつなぐ「ドライバー」のようなものです。使う流れは、どの FDW でも共通で次の4段階です。
- 拡張機能を有効にする(
CREATE EXTENSION) - 接続先を「外部サーバー」として登録する(
CREATE SERVER) - どのユーザーで接続するかを決める(
CREATE USER MAPPING) - 外部テーブルを定義する(
CREATE FOREIGN TABLEまたはIMPORT FOREIGN SCHEMA)
PostgreSQL 本体に付属する(contrib に含まれる)代表的なものは二つです。
postgres_fdw:別の PostgreSQL サーバーに接続します。条件の絞り込みや結合を接続先で実行させる機能が充実しており、もっともよく使われます。file_fdw:サーバー上の CSV などのファイルを読み取り専用のテーブルとして扱います。
このほか、MySQL 向けの mysql_fdw や Oracle 向けの oracle_fdw など、第三者が開発している FDW もあります。こちらは PostgreSQL 本体とは別に開発・配布されているため、使う PostgreSQL のバージョンに対応しているか、更新が続いているかを導入前にリポジトリで確認してください。
postgres_fdwの設定手順
ここでは、分析用サーバー(ローカル側)から、業務用サーバー(リモート側)の sales データベースにある orders テーブルを参照する例で説明します。作業は検証環境で一通り試し、本番ではバックアップを取ってから行ってください。
1. リモート側で読み取り専用のロールを用意する
まずリモート側に、FDW 専用の接続ユーザーを作ります。参照だけが目的なら、必要なテーブルの SELECT だけを許可します。
-- リモート側(業務用サーバー)で実行
CREATE ROLE fdw_reader LOGIN PASSWORD 'your-strong-password';
GRANT CONNECT ON DATABASE sales TO fdw_reader;
GRANT USAGE ON SCHEMA public TO fdw_reader;
GRANT SELECT ON public.orders, public.customers TO fdw_reader;
リモート側の pg_hba.conf で、ローカル側サーバーの IP アドレスからこのユーザーが接続できるように設定し、ファイアウォールでも 5432 番ポートなどを接続元に限って開けます。ここが漏れていると、後の手順で「接続できない」というエラーになります。
2. ローカル側で外部サーバーとユーザーマッピングを作る
-- ローカル側(分析用サーバー)で実行
CREATE EXTENSION IF NOT EXISTS postgres_fdw;
CREATE SERVER sales_srv
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host '10.0.0.5', port '5432', dbname 'sales', sslmode 'require');
CREATE USER MAPPING FOR analyst
SERVER sales_srv
OPTIONS (user 'fdw_reader', password 'your-strong-password');
GRANT USAGE ON FOREIGN SERVER sales_srv TO analyst;
CREATE SERVER の OPTIONS には、host や sslmode など libpq の接続パラメーターの多くを書けます。ネットワークを経由する場合は通信を暗号化しておくのが安全です。CREATE USER MAPPING FOR analyst は「ローカルの analyst ロールが使うときは、リモートに fdw_reader として接続する」という対応づけです。
3. 外部テーブルを作る
テーブルを一つずつ定義することもできますが、IMPORT FOREIGN SCHEMA を使うと、リモートの定義をまとめて取り込めます。
CREATE SCHEMA remote_sales;
IMPORT FOREIGN SCHEMA public
LIMIT TO (orders, customers)
FROM SERVER sales_srv
INTO remote_sales;
-- 動作確認
SELECT count(*) FROM remote_sales.orders;
外部テーブルは、リモート側の列名や型が変わっても自動では追従しません。リモートでスキーマを変更したら、外部テーブルを作り直す運用にしておくと、「列が存在しない」というエラーに慌てずに済みます。
プッシュダウンを確認する
FDW の性能は、条件や集計をリモート側で実行させられるか(プッシュダウン)で大きく変わります。リモートの全行を取り寄せてからローカルで絞り込むと、ネットワークとメモリの負担が大きくなります。確認には EXPLAIN VERBOSE を使います。
EXPLAIN VERBOSE
SELECT customer_id, sum(amount)
FROM remote_sales.orders
WHERE ordered_at >= '2026-09-01'
GROUP BY customer_id;
出力の Remote SQL: という行に、リモートへ送られる SQL が表示されます。ここに WHERE や GROUP BY が含まれていればプッシュダウンされています。含まれていない場合は、次の点を確認します。
- 組み込みの不変(IMMUTABLE)な関数や演算子は送られやすい一方、独自に定義した関数はそのままでは送られません。拡張機能の関数は、外部サーバーの
extensionsオプションに登録すると送れる場合があります。 - ローカルの表と外部テーブルを結合すると、結合はローカルで行われます。同じ外部サーバー上の表どうしの結合は、リモートで実行されることがあります。
- 実行計画の見積もりが大きく外れる場合は、
ANALYZE remote_sales.orders;でローカル側に統計を取るか、外部サーバーやテーブルにuse_remote_estimate 'true'を設定してリモートの見積もりを使わせます。後者は計画のたびにリモートへ問い合わせるため、短いクエリが多い用途では逆に遅くなることがあります。
大量の行を取り寄せる場合は、1回に取得する行数を決める fetch_size オプション(既定は100行)を大きくすると往復が減ることがあります。どのオプションが使えるかはバージョンで違うため、使っている PostgreSQL の公式ドキュメントで確認してください。
権限とパスワードの扱い
FDW の設定で注意したいのは、接続情報の管理です。
- ユーザーマッピングのパスワードは、データベースのシステムカタログに保存されます。漏えい時の影響を小さくするため、リモート側のロールは読み取り専用・必要なテーブルだけに絞ります。
- PostgreSQL では、スーパーユーザー以外のユーザーマッピングはパスワード認証で接続することが求められます。リモート側を
trust認証にしていると接続が拒否されるのは、この仕様によるものです。 - 外部テーブルへの書き込みは、リモート側のロールに権限があれば可能です。参照だけの用途なら、リモート側で
SELECT以外を与えないことで誤更新を防げます。 - バックアップ(
pg_dump)には外部テーブルの定義は含まれますが、リモートのデータそのものは含まれません。リモート側は別にバックアップが必要です。
WordPressのMySQLを参照する場合の注意
第三者製の mysql_fdw を使えば、WordPress の MySQL にある wp_posts などを PostgreSQL から参照する構成も技術的には可能です。ただし、次のリスクを理解したうえで検討してください。
- 本番の WordPress データベースに重いクエリが送られると、サイトの表示が遅くなります。参照先はレプリカ(読み取り専用の複製)にするのが望ましい構成です。
- MySQL 側の接続ユーザーは必要なテーブルの
SELECTだけに限定し、WordPress 本体が使うユーザーを流用しないでください。 - 文字コード(utf8mb4)や日付型の扱いで値がずれることがあります。導入前に、件数と代表的な行の値を両側で突き合わせます。
定期的な集計だけが目的なら、FDW で常時つなぐより、MySQL から定期的にエクスポートして取り込む方が、障害の影響範囲を小さくできる場合もあります。
まとめ
- FDW は「拡張機能 → 外部サーバー → ユーザーマッピング → 外部テーブル」の4段階で設定します。
postgres_fdwとfile_fdwは本体に付属します。第三者製の FDW は対応バージョンと保守状況を確認してから使います。- 性能は
EXPLAIN VERBOSEのRemote SQLで、条件や集計がリモートに送られているかを見て判断します。 - リモート側には読み取り専用で権限を絞った専用ロールを作り、通信は暗号化します。リモートのデータは別途バックアップします。
- WordPress の MySQL を参照する場合はレプリカを使い、本番サイトへの負荷を避けます。