エンタープライズ:特集 2003/08/24 18:55:00 更新

[JAVA Developer特別企画]
MySQL独自のENUM・SET型を使ってみよう

読者の皆さんは、テーブル定義に使用するデータ型で悩んだことはありませんか。フォームから入力されるデータはすべて文字列ですが、ラジオボタンやチェックボックス、選択ボックスのデータは決まった候補から選択する固定の文字列です。ここでは、MySQL独自のデータ型を使って、選択型の文字列を効率よく保存・参照する方法を紹介します。
JAVA Developer 2003年10月号より転載

 MySQLのENUMおよびSET型は、文字列型に分類されるMySQL独自のデータ型です。ENUM型はプルダウン式の選択ボックスやラジオボタン、一方、SET型は複数のチェックボックスにうまく適用できそうなデータ型だと思います。まずはENUMとSET型を使ったテーブル定義を見てみましょう。


CREATE TABLE sample (
blood ENUM('A','B','O','AB'),
favorite SET('ガム','飴','チョコ'))

 どちらもテーブル定義の際に、文字列を(')ではさみ、(,)で区切って複数個を宣言します。宣言できる文字列の最大個数は、ENUM型が65535個、SET型が64個となっています。

フォームから受け取った文字列をそのまま登録できる
 実際にフォーム(図1)から入力したデータを登録してみます。

画面1
画面1 簡単なアンケートフォーム

 血液型がB、好きなお菓子がガムとチョコを選んで登録ボタンを押すと、フォームからのデータを受け取った側では次のINSERT文を実行して、データを登録します。


INSERT INTO sample(blood,favorite)
VALUES('B','ガム,チョコ')

 ここでポイントとなるのは、SET型のデータの指定。フォームでチェックされたお菓子の名前を(,)で区切って連結しています。Javaの場合、RequestオブジェクトのgetParameterValuesメソッドで取り出し、受け取ったそれらをすべて連結させればよいのです。


String[] favorite =
req.getParameterValues("favorite");
String favorites = favorite[0];
for (int i=1; i<favorite.length; i++){
 favorite += ("," + favorite[i]);
}

SET型はLIKE演算子またはFIND_IN_SET関数を使う
 ENUM型を含めたデータの取得は、基本的に通常の文字列型とほぼ同様です。たとえば、血液型別に登録者数を集計するSELECT文は、次のようになります。


SELECT blood,COUNT(*) FROM sample
GROUP BY blood

 また、血液型がABのデータを取得するSELECT文は次のとおりです。


SELECT * FROM sample
WHERE blood='AB'

 通常の文字列と異なるのはソート。内部の数値データがソートの評価対象になるため、文字列の内容とは関係なくソートされます。次のSELECT文を実行した場合は、画面2のようになります。


SELECT * FROM sample
ORDER BY blood

画面2
画面2 ORDER BY句でENUM型を指定した場合、テーブル定義時に宣言した順番にソートされる

 SET型をWHERE句で条件指定する場合は、2つの方法があります。たとえば、好きなお菓子に飴を選んでいるデータは、次の2つのSELECT文を使います。この結果が画面3です。


SELECT * FROM sample
WHERE favorite LIKE '%飴%'


SELECT * FROM sample
WHERE FIND_IN_SET('飴',favorite)

画面3
画面3 好きなお菓子に飴を選んでいるデータを取得

 LIKE演算子は一般の文字型を調べる場合と一緒で、前後に(%)をつけることで、その検索対象を含んだデータを絞り込むことができます。
 FIND_IN_SET関数は、SET型専用の関数です。カラムに文字列が含まれている場合は0より大、含まれていない場合は0が戻り値となります。この例では、戻り値を評価していませんが、意味は戻り値が0より大きいと指定した場合と同じです。


FIND_IN_SET('飴',favorite) > 0

 逆に、


FIND_IN_SET('飴',favorite) = 0

と指定した場合には、飴を含んでいないデータを取得できます。FIND_IN_SET関数を使うことで、柔軟に条件を指定できそうです。
 ENUM型とSET型は、ユニークなデータ型です。MySQL独自のデータ型のため、アプリケーションもMySQLに依存してしまいますが、アンケート内容とそれを格納するテーブルの関係がわかりやすくなると思います。汎用性にこだわらず、使ってみてはいかがでしょうか。

関連リンク
▼JAVA Developer
▼定期購読のご案内
▼バックナンバー販売協力店

JAVA Developer10月号表紙 JAVA Developer 10月号

大特集
再入門 J2SE

特集2 Oracle9i Application Server
[特別企画]
・例外処理のメカニズム
・データベース移行術(2)
 「Oracle→DB2編」
・Tomcatで試すJava2セキュリティ

[松浦 武範,JAVA Developer]