FEDERATED
5.0.3から追加されたストレージエンジンで、その用途は他のMySQLのテーブルにアクセスできるようにするためのもの(他のRDBMS
でいうところのDBLINKのようなもの)です。今回紹介するストレージエンジンの中では『使える』部類に入るものではないかと思います。また、
FEDERATEDのユニークな点は、現在はMySQLとしか連携できませんが、将来的に他のRDBMS(PostgreSQLやOracleなど)との
連携も計画されていることが挙げられるでしょう。
他のテーブルを参照する
では早速、試してみましょう。以下ではFEDERATEDテーブルを作るホストをmy5-1、FEDERATEDで参照されるホストをmy5-2とし、下準備として図4のSQLを実行しておきます。
<図4:FEDERATEDを使う準備>
●my5-2でrootユーザで実行するSQL
CREATE DATABASE wd;
GRANT SELECT, INSERT, UPDATE, DELETE
, CREATE, ALTER, DROP, REFERENCES, INDEX
, LOCK TABLES
ON wd.* TO wd@'%' IDENTIFIED BY 'press2';
●my5-2でwdユーザで実行するSQL
use wd;
DROP TABLE IF EXISTS user_master;
CREATE TABLE IF NOT EXISTS user_master (
id SMALLINT UNSIGNED
,name VARCHAR(32) NOT NULL
,age TINYINT UNSIGNED
,PRIMARY KEY (id)
) ENGINE=InnoDB;
INSERT INTO user_master VALUES
(1,'ichirou', 21)
,(2,'jirou', 32)
,(3,'saburou', 43)
;
●my5-1でrootユーザで実行するSQL
CREATE DATABASE wd;
GRANT SELECT, INSERT, UPDATE, DELETE
, CREATE, ALTER, DROP, REFERENCES, INDEX
, LOCK TABLES
ON wd.* TO wd@'%' IDENTIFIED BY 'press1';
準備ができたところでFEDERATEDのテーブルを作るために、my5-1にwdユーザでログインし、図5のSQLを実行します。うまくで
きたら参照(SELECT * FROM
f_userなど)してみましょう。また、FEDERATED経由のテーブルは更新もできるので、INSERTやDELETEも試してみましょう。
<図5:FEDERATEDエンジンのテーブルを作る>
use wd;
DROP TABLE IF EXISTS f_user;
CREATE TABLE IF NOT EXISTS f_user (
id SMALLINT UNSIGNED NOT NULL
,name VARCHAR(32) NOT NULL
,age TINYINT UNSIGNED
,PRIMARY KEY (id)
) ENGINE=FEDERATED
CONNECTION='mysql://wd:press2@my5-2/wd/user_master';
FEDERATEDの注意点など
とりあえずテーブルを作ってみましたが、FEDERATEDには注意点がいくつかあります。
テーブル定義
先の例でも見たように、参照する側(my5-1)のDDLは、参照される側(my5-2)のDDLと以下の点以外は同じにする必要があるとされています。
- - テーブル名は異なってももよい。
- - ENGINE=FEDERATEDにする。
- - CONNECTION=を付加する。
ここで図4と図5を見比べると他にも異なる点があります。そう、idカラムの「NOT NULL」です。参照される側でCREATE
TABLEした際には、PRIMARY KEYによって暗黙的にNOT
NULL制約が付与されましたが、(少なくとも今回の環境のバージョンでは)FEDERATEDを使う参照する側ではNOT
NULLを明示的に指定する必要があり、NOT NULLを指定しない場合は
ERROR 1121 (42000): Column ‘id’ is used with UNIQUE or INDEX but is
not defined as NOT NULL
というエラーが発生しました。
接続ユーザのパスワード
SHOW CREATE TABLEでFEDERATEDなテーブルのテーブル定義を見ると、接続ユーザのパスワードが表示されてしまいます。将来的に改善されることが示唆されていますが、それまでは権限情報の取り扱いには注意してください。
トランザクション
FEDERATED経由のテーブルに対してSTART
TRANSACTIONしてもトランザクション処理は行われず、AUTOCOMMITモードの様な動作になります。同様にFEDERATED経由のテーブ
ルに対してLOCK TABLESを発行しても効果はありません。
なお、参照される側で実行されたトランザクションやLOCK
TABLESは、参照する側のFEDERATEDなテーブルにも効果があります。例えば、my5-2でLOCK TABLES user_mastert
WRITEが発行されると、my5-1でのSELECT * from f_userはブロックされて待たされます。
FEDERATEDテーブルの削除
DROP TABLE文で削除可能です。参照する側でDROP TABLEを実行しても、参照される側のテーブルは消されませんので安心してください
参照される側のテーブル定義の変更
参照される側のテーブル定義が変わった場合、例えばカラムが追加されたり削除された場合、参照する側のFEDERATEDなテーブルは作り直
す必要があるのですが、FEDERATEDはALTER TABLEをサポートしていないため、DROP TABLEしてCREATE
TABLEしなおす必要があります。
他のバージョンとも連携できるか
試した限りでは、MySQL 4.0.24のテーブルを参照できました。
FEDERATEDを開拓
さて、ここまででFEDERATEDの優等生的な解説が終わりました。好奇心旺盛な読者の方はあれやこれや疑問点が出てきたのではないでしょ
うか。ここからは開拓団の本領発揮ということで、あんなことやこんなことを実用性を無視して試してみたいと思います。ただ、これから紹介する挙動の中に
は、もしかしたら実はバグで将来のバージョンでは修正され、挙動が変わるものもあるかもしれませんので、その点、ご了承ください。
参照する側に作られるものは?
参照する側でカラム定義付きのCREATE
TABLE文を発行する必要があったことから推測できる通り、参照する側では何も作られないわけではなく、拡張子.frmのファイルが作られま
す。*.frmファイルはFEDERATED固有のものではなくMyISAMやInnoDBのテーブルでも作られるテーブル定義が格納されているファイル
です。
自動再接続するか?
当然、参照される側のmysqldが停止している間はFEDERATED経由で参照できませんが、参照される側が起動すれば参照する側が自動
的に再接続してくれますので、再度CREATE
TABLEを発行する必要はありません。また、wait_timeout(初期値は8時間)が過ぎて接続が切れた場合も再接続してくれます。ちなみに、再
接続の機能はFEDERATEDに実装されているものではなく、FEDERATEDが接続に使用しているMySQLのCクライアント
API(mysql_real_connect)の機能によるものです。
ローカルのテーブルと結合できるか?
できます。JOINはもちろん、UNIONなども可能です。試しにこのようなテーブルをローカルに作り、
use wd;
DROP TABLE IF EXISTS linux_user;
CREATE TABLE IF NOT EXISTS linux_user (
id SMALLINT UNSIGNED
,distrib VARCHAR(32) NOT NULL
,PRIMARY KEY (id)
) ENGINE=InnoDB;
INSERT INTO linux_user VALUES
(1,’Debian’)
,(3,’Fedora’)
;
FEDERATEDなf_userテーブルと結合すると、図6のように期待通り結合できることが確認できます。
<図6:FEDERATEDテーブルとの結合>
wd@my5-1[wd]> SELECT
l.id AS id
,u.name AS name
,u.age AS age
,l.distrib AS distrib
FROM linux_user AS l LEFT JOIN f_user AS u ON l.id = u.id;
+----+---------+------+---------+
| id | name | age | distrib |
+----+---------+------+---------+
| 1 | ichirou | 21 | Debian |
| 3 | saburou | 43 | Fedora |
+----+---------+------+---------+
2 rows in set (0.01 sec)