突然、MySQL用のVPストレージエンジンが気になったので試してみました。
VP(Vartical Partitioning)とは、文字通りテーブルの縦分割のことで、カラムがいっぱいあるテーブルをバッサリと縦に切って(もちろんPRIMARY KEYのカラムは両方に持ちますよ)別々のテーブルに分けて管理するというもの。
これだけなら、テーブルを分割したあとで、アプリケーションのほうで必ず両方のテーブルの整合性が保てるように追加/削除/更新をすれば良いだけなのですが、「だけ」とは言ってもこれは結構面倒。VPストレージエンジンを使うと元のテーブルレイアウトのままでもアクセスすることができるのです(親テーブル/子テーブル群 的に考えるとイメージがわきやすいでしょうか)。
まずは試してみます。Windows上で細かいことは気にせずにさくっと*1。
http://spiderformysql.com/download_spider.html
から、Spider 2.26 の
mysql-5.5.14-spider-2.26-vp-0.15-win32.zip
vp-init-0.15-for-5.5.14.tgz
を落としてアーカイブを展開します。
コマンドプロンプトで展開したディレクトリに移動して、
D:\MyDir> bin\mysqld
を実行。シンプルにシンプルに(笑)。
これで MySQL サーバが動作しています。
もうひとつコマンドプロンプトを開いて、同じディレクトリに移動して、
D:\MyDir> bin\mysql -uroot
でクライアントを実行します。
ストレージエンジンを確認してみると、VPエンジンはまだありません。
mysql> show engines; +--------------------+---------+------------//-+--------------+------+------------+ | Engine | Support | Comment | Transactions | XA | Savepoints | +--------------------+---------+------------//-+--------------+------+------------+ | CSV | YES | CSV storag.. | NO | NO | NO | | PERFORMANCE_SCHEMA | YES | Performanc.. | NO | NO | NO | | InnoDB | DEFAULT | Supports t.. | YES | YES | YES | | MyISAM | YES | MyISAM sto.. | NO | NO | NO | | MRG_MYISAM | YES | CollectionA.. | NO | NO | NO | | MEMORY | YES | Hash based... | NO | NO | NO | +--------------------+---------+---------------+--------------+------+------------+ 6 rows in set (0.00 sec)
VPエンジンは自分で設定する必要があります。
もうひとつ落としてきたファイルを展開して、出てきた install_vp.sql を実施します。
既存時の対応とかOSの判定とか色々やっていますが、要するに Windows 上で初めて設定するならば、以下の2つのことをやっているだけです
install plugin vp soname 'ha_vp.dll'; create function vp_copy_tables returns int soname 'ha_vp.dll';
おもしろいのが、OS判定や既存判定などをしてから上記コマンドを実行するために、ストアドプロシジャを使っている点です。
従来ならばシェルスクリプトやバッチファイルがこの役割を担っていたのでしょうけれども、ストアドプロシジャにすることで、OSの垣根を越えて、MySQL上で同じスクリプトが動作するのです。 プロシジャを作成して、実行して、すぐに消す、という処理が、この install_vp.sql には記述されています。
ということで、上記2コマンドを今回は手動で実行してから、改めてストレージエンジン状況を見てみます。
(略) | VP | YES | Vertical Pa.. | YES | YES | NO | +--------------------+---------+---------------+--------------+------+------------+ 7 rows in set (0.00 sec)
できました、できましたよ。
早速サンプルのテーブルを作ってみます。
mysql> use test mysql> CREATE TABLE a1 (id integer, c01 varchar(255), c02 varchar(255), c03 varchar(255), PRIMARY KEY (id)) engine=innodb; mysql> CREATE TABLE a2 (id integer, c02 varchar(255), c04 varchar(255), c05 varchar(255), PRIMARY KEY (id)) engine=innodb; mysql> CREATE TABLE aall (id integer, c01 varchar(255), c02 varchar(255), c03 varchar(255), -> c04 varchar(255), c05 varchar(255), PRIMARY KEY(id)) -> engine=vp comment 'table_name_list "a1 a2"';
できました。データ登録。
mysql> INSERT INTO aall VALUES (10, "col1", "col2", "col3", "col4", "col5"); mysql> INSERT INTO aall VALUES (20, "colA", "colB", "colC", "colD", "colE");
mysql> SELECT * FROM aall; SELECT * FROM a1; SELECT * FROM a2; +----+------+------+------+------+------+ | id | c01 | c02 | c03 | c04 | c05 | +----+------+------+------+------+------+ | 10 | col1 | col2 | col3 | col4 | col5 | | 20 | colA | colB | colC | colD | colE | +----+------+------+------+------+------+ 2 rows in set (0.00 sec) +----+------+------+------+ | id | c01 | c02 | c03 | +----+------+------+------+ | 10 | col1 | col2 | col3 | | 20 | colA | colB | colC | +----+------+------+------+ 2 rows in set (0.00 sec) +----+------+------+------+ | id | c02 | c04 | c05 | +----+------+------+------+ | 10 | col2 | col4 | col5 | | 20 | colB | colD | colE | +----+------+------+------+ 2 rows in set (0.00 sec)
きれいに分かれてくれていますね。c02カラムが重複(a1,a2両方のテーブルに含まれている)していますが、きちんと両方に同じものを入れてくれています。
aallテーブルにアクセスしていれば、あたかも今までと何も変わらないかのように利用できます。
・レガシーな設計で、カラム数が膨大な(横に長い)テーブルなどを、これで分割管理できる
・まずは分割するけど、何も考えずにもとのレイアウト、もとの名前でアクセスできるようにするのが第一段階かな
・分割後のテーブルの一部を spider エンジンで別のハコに飛ばすこともできそう
・読み込み処理は、コンパクトになった子テーブル側のほうから行うように,プログラムを変更して幸せになるシーンもあるかもしれない
・ビューとの違いは、子テーブル側のほうが実テーブルなので書き込みもできるし、読み込みの際のメモリ占有量もコンパクトになりそう
整合性などについて気になるので、後ほど実験してみたいと思います。
.