The EDB Blog
2011年8月1日

この数ヶ月、仕事のプロジェクトに没頭していたので、最終的には子供たちが1週間離れた後の週末にSQL / MEDの以前のハッキングに戻ってしまいました(ここで静かで良い$ DEITYです)!2、3時間以内に私は「生焼けの」MySQL用外部データラッパーを稼働させました。PostgreSQL 9.1では、MySQLデータベースのテーブルに直接マップするか、MySQLサーバーで実行するクエリーにマップする外部テーブルオブジェクトを作成できるようになりました。

 

ここに例があります:

-- Create the required functions for the FDW.
CREATE FUNCTION mysql_fdw_handler()
RETURNS fdw_handler
AS '$libdir/mysql_fdw'
LANGUAGE C STRICT;

CREATE FUNCTION mysql_fdw_validator(text[], oid)
RETURNS void
AS '$libdir/mysql_fdw'
LANGUAGE C STRICT;

-- Create the data wrapper or "transport".
CREATE FOREIGN DATA WRAPPER mysql_fdw
HANDLER mysql_fdw_handler
VALIDATOR mysql_fdw_validator;

-- Create the foreign server, a pointer to the MySQL server.
CREATE SERVER mysql_svr
FOREIGN DATA WRAPPER mysql_fdw
OPTIONS (address '127.0.0.1', port '3306');

-- Create one or more foreign tables on the MySQL server. The first of
-- these maps to a remote table, whilst the second uses an SQL query.
CREATE FOREIGN TABLE employees (
id integer,
name text,
address text)
SERVER mysql_svr
OPTIONS (table 'hr.employees');

CREATE FOREIGN TABLE ex_staff (
id integer,
name text,
address text)
SERVER mysql_svr
OPTIONS (query 'SELECT * FROM hr.employees WHERE date_left IS NOT NULL');

 

 

-- PUBLICの、MySQLへの接続で使用するユーザ名/パスワードを。
-- FDWに伝えるユーザマッピングを作成しますこれはロール毎に
-- 行うことができます。
CREATE USER MAPPING FOR PUBLIC
SERVER mysql
OPTIONS (username 'dpage', password '');
 
それでは、試してみましょう。MySQLのテストテーブルは次のとおりです:
 
mysql> SELECT * FROM employees;
+----+-------------+----------------------------+------------+
| id | name | address | date_left |
+----+-------------+----------------------------+------------+
| 1 | Dave Page | 27 High Street, Georgetown | NULL |
| 2 | Fred Bloggs | 46 Mill Road, Klasborough | NULL |
| 3 | Fred Bloggs | 24 The Wharf, Westhampton | 2010-05-23 |
+----+-------------+----------------------------+------------+
セットに3行(0.00秒)
 
そして、PostgreSQL 9.1ベータ3:
 
postgres=# SELECT * FROM employees;
id | name | address
----+-------------+----------------------------
1 | Dave Page | 27 High Street, Georgetown
2 | Fred Bloggs | 46 Mill Road, Klasborough
3 | Fred Bloggs | 24 The Wharf, Westhampton
(3 行)
 
postgres=# SELECT * FROM ex_staff;
id | name | address
----+-------------+---------------------------
3 | Fred Bloggs | 24 The Wharf, Westhampton
(1 row)
 
不思議なことに、EXPLAINの出力は次のようになります:
 
postgres=# EXPLAIN SELECT * FROM employees;
QUERY PLAN
----------------------------------------------------------------
Foreign Scan on employees (cost=10.00..13.00 rows=3 width=68)
Local server startup cost: 10
MySQL query: SELECT * FROM hr.employees
(3 行)
 
かなりきちんとしたね?現在の実装にはいくつかの制限があります:
  • 現在quals(WHERE句)をMySQLサーバーにプッシュしようとする試みは行われていないので、MySQLが検出するすべての行はPostgreSQLに返され、そこでフィルタリングされます。PostgreSQLにはこのための定義済みのAPIはまだありません。リモートリレーショナルデータベースに必要なRedis FDWで使用した簡単な例よりも複雑なものを構築する方法はすぐには分かりません。つまり、WHERE句を外部テーブルの定義に組み込むことができます。
  • MySQL C APIは、結果セット全体にランダムにアクセスするか、または少なくとも最初の行にカーソルをリセットする簡単な方法を提供していないようです。結果セット全体をクライアント(この場合はPostgreSQL)にコピーする場合を除きます。PostgreSQLがRescan関数を呼び出す場合、最初の行に戻ることができる必要があるため、現在は、結果セット全体を、必要に応じてサーバーから読み込むのではなく、コピーします。

マイナーな調整はさておき、今のところは、おそらくこの小さなプロジェクトを取るつもりです。9月のシカゴでのPostgres Open 2011と、11月のSãoPauloでのPGBR 2011の両方で話します。うまくいけば、そこでお会いしましょう。

 

MySQLのFDWソースコードはGithubで入手可能であり、PostgreSQLのライセンスを使用します。

 

 

dave.page's picture

Dave has been actively involved in the PostgreSQL Project since 1998, as the lead developer of pgAdmin, maintainer of the PostgreSQL installers and one of the projects resident Windows hackers. He also serves on the project's web and sysadmin teams and is a member of the PostgreSQL Core Team....