Open Source WEB

MERGEでのUNION指定

MERGE型のテーブルの作り方は、14.2. The MERGE Storage Engine を見れば実例が載っている。 英語以外への翻訳は、例によってフランス語しかないので、あきらめて英語を読もう。

マニュアルの中の肝心な部分は、以下の例の部分である。

mysql> CREATE TABLE t1 (
    ->    a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->    message CHAR(20));
mysql> CREATE TABLE t2 (
    ->    a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->    message CHAR(20));
mysql> INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1');
mysql> INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');
mysql> CREATE TABLE total (
    ->    a INT NOT NULL AUTO_INCREMENT,
    ->    message CHAR(20), INDEX(a))
    ->    TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;

これを参考に、「都道府県」テーブルを以下のように作ってみた。

mysql> CREATE TABLE `都道府県` (
    ->     `名称` VARCHAR(10), `読み` VARCHAR(20), `人口` INT, `面積` FLOAT(10,2)
    -> ) TYPE=MERGE UNION = (`東京`,`北海道`) DEFAULT CHARSET=eucjpms;
Query OK, 0 rows affected, 1 warning (0.04 sec)
                                                                                      
mysql> SHOW TABLES;
+----------------+
| Tables_in_日本 |
+----------------+
| 北海道         |
| 東京           |
| 都道府県       |
+----------------+
3 rows in set (0.00 sec)
 
mysql>

「東京」と「北海道」を単に合わせたのが「都道府県」なのであるが、 テーブルをリストすると、上のように表示され、 「都道府県」テーブルのDESCRIBEは、以下のようになる。

mysql> DESCRIBE `都道府県`;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| 名称  | varchar(10) | YES  |     | NULL    |       |
| 読み  | varchar(20) | YES  |     | NULL    |       |
| 人口  | int(11)     | YES  |     | NULL    |       |
| 面積  | float(10,2) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
 
mysql> SELECT * FROM `都道府県`;
+----------+----------------+--------+--------+
| 名称     | 読み           | 人口   | 面積   |
+----------+----------------+--------+--------+
| 千代田区 | ちよだく       |  39551 |  11.64 |
| 中央区   | ちゅうおうく   |  87416 |  10.15 |
| 新宿区   | しんじゅくく   | 299808 |  18.23 |
| 世田谷区 | せたがやく     | 835702 |  58.08 |
| 調布市   | ちょうふし     | 214032 |  21.53 |
| 町田市   | まちだし       | 405008 |  71.62 |
| 大島町   | おおしままち   |   8786 |  91.06 |
| 檜原村   | ひのはらむら   |   3004 | 105.42 |
| 小笠原村 | おがさわらむら |   2755 | 104.41 |
| 中央区   | ちゅうおうく   | 196489 |  46.42 |
| 豊平区   | とよひらく     | 209021 |  46.35 |
| 旭川市   | あさひかわし   | 356931 | 747.60 |
| 歌志内市 | うたしないし   |   5396 |  55.99 |
| 北見市   | きたみし       | 110995 | 421.08 |
| ニセコ町 | にせこちょう   |   4642 | 197.13 |
| 羅臼町   | らうすちょう   |   6717 | 397.84 |
+----------+----------------+--------+--------+
16 rows in set (0.00 sec)
 
mysql>

これだけ見ると、まったく普通のテーブルだ。


INSERT

しかし、データを加えようとすると、

mysql> INSERT INTO `都道府県` VALUES ('洞爺村','とうやむら',2221,113.69);
ERROR 1031 (HY000): Table storage engine for '都道府県' doesn't have this option
mysql>

となってしまう。INSERTできないようである。 MERGEテーブルというのは本当に複数のMyISAMテーブルを集めただけなので、 インサートしようとしてもどのMyISAMテーブルに加えてよいか分からないので 当然であろう。

仕方がないので、元のMyISAMテーブルを指定してINSERTしてみよう。 上のデータは、'洞爺村'という北海道の村なので、北海道テーブルに加える。

mysql> INSERT INTO `北海道` VALUES ('洞爺村','とうやむら',2221,113.69);
Query OK, 1 row affected (0.00 sec)
 
mysql> SELECT * FROM `都道府県` WHERE `名称` LIKE '%村';
+----------+----------------+------+--------+
| 名称     | 読み           | 人口 | 面積   |
+----------+----------------+------+--------+
| 檜原村   | ひのはらむら   | 3004 | 105.42 |
| 小笠原村 | おがさわらむら | 2755 | 104.41 |
| 洞爺村   | とうやむら     | 2221 | 113.69 |
+----------+----------------+------+--------+
3 rows in set (0.01 sec)
 
mysql>

UPDATE

INSERTは無理だが、変更はできるのではないだろうか。 どのMyISAMテーブルかを指定せずに変更してみよう。

何でも良いのだが、'千代田区'という名称を'千代田村'に変更してみよう。 もちろん、このときには、テーブルは「都道府県」で指定する。

mysql> UPDATE `都道府県` SET `名称`='千代田村' WHERE `名称`='千代田区';
Query OK, 1 row affected (0.13 sec)
Rows matched: 1  Changed: 1  Warnings: 0
 
mysql> SELECT * FROM `東京`;
+----------+----------------+--------+--------+
| 名称     | 読み           | 人口   | 面積   |
+----------+----------------+--------+--------+
| 千代田村 | ちよだく       |  39551 |  11.64 |
| 中央区   | ちゅうおうく   |  87416 |  10.15 |
| 新宿区   | しんじゅくく   | 299808 |  18.23 |
| 世田谷区 | せたがやく     | 835702 |  58.08 |
| 調布市   | ちょうふし     | 214032 |  21.53 |
| 町田市   | まちだし       | 405008 |  71.62 |
| 大島町   | おおしままち   |   8786 |  91.06 |
| 檜原村   | ひのはらむら   |   3004 | 105.42 |
| 小笠原村 | おがさわらむら |   2755 | 104.41 |
+----------+----------------+--------+--------+
9 rows in set (0.00 sec)
 
mysql>

OKだ。


ファイルはどうなっているだろうか

GA(Generally Available)としてリリースされた 5.0.15のバイナリー を使い始めたところで、デフォルトののまま使っているので、 /usr/local/mysql/data がMySQLのデータディレクトリになっている。

shell# ls -l
合計 60
-rw-rw----    1 mysql    mysql          65 10月 27 17:15 db.opt
-rw-rw----    1 mysql    mysql          17 10月 28 21:39 都道府県.MRG
-rw-rw----    1 mysql    mysql        8666 10月 28 21:39 都道府県.frm
-rw-rw----    1 mysql    mysql         316 10月 28 21:03 東京.MYD
-rw-rw----    1 mysql    mysql        1024 10月 28 21:57 東京.MYI
-rw-rw----    1 mysql    mysql        8666 10月 28 21:03 東京.frm
-rw-rw----    1 mysql    mysql         276 10月 28 21:52 北海道.MYD
-rw-rw----    1 mysql    mysql        1024 10月 28 21:57 北海道.MYI
-rw-rw----    1 mysql    mysql        8666 10月 28 21:27 北海道.frm
shell# 

都道府県というファイルは2つできていて、拡張子が.frmのファイルは 当然フォーマットファイルである。

拡張子が .MRG のファイルは何なのだろうか?

shell# file 都道府県.MRG
都道府県.MRG: UTF-8 Unicode text
shell# cat 都道府県.MRG
東京
北海道
shell#

MRGファイルは、どのMyISAMファイルの和であるかを保持しているだけらしい。 とっても安直な構造のようで、微笑ましい。

よく見ると、.frm ファイルのサイズはどれも同じである。

shell# diff 都道府県.frm 東京.frm
バイナリー・ファイル都道府県.frmと東京.frmは違います
shell# diff 東京.frm 北海道.frm
shell#

ということで、MyISAMのフォーマットファイルは、フォーマットが完全に一致 していれば、フォーマットファイルは完全一致するようだ。 しかし、MERGEテーブルのフォーマットファイルはサイズは同じになっても、 何か違いがあるらしい。

MERGEの場合

テーブル名.frm   テーブル定義が記述されているファイル

テーブル名.MRG   MyISAMテーブルのリスト

それにしても、ちゃんと日本語が使えちゃうなぁ。


戻る:テーブルがMERGEの場合はどうなるか

次へ:一時テーブルの場合はどうなるか


フィードバック:

Name:
Comment:

There is no comment.

このサイトは、 IPA の「平成15年度オープンソフトウエア活用基盤整備事業」 の委託事業として開発されたKahuaで試験的に運用しております。

Copyright (c) 2004-2007 株式会社タイムインターメディア About Us