EnterpriseZine(エンタープライズジン)

EnterpriseZine(エンタープライズジン)

テーマ別に探す

第7回 MySQL事始 データ型

edited by DB Online   2011/09/22 00:00

選択肢型

データに格納する値をあらかじめ設定した特定の値だけに制限することができます。ENUM型は単一の値のみ、SET型は複数の値を選択することができます。

このENUM型は、サンプルデータのCountryLanguageテーブルで、「その言語がその国の公用語か」を表すIsOfficial列で使用されています。他にもCountryテーブルの「大陸名」を表すContinent列で使用されています。



mysql> SHOW CREATE TABLE CountryLanguage\G
*************************** 1. row ***************************
       Table: CountryLanguage
Create Table: CREATE TABLE `CountryLanguage` (
  `CountryCode` char(3) NOT NULL DEFAULT '',
  `Language` char(30) NOT NULL DEFAULT '',
  `IsOfficial` enum('T','F') NOT NULL DEFAULT 'F',
  `Percentage` float(4,1) NOT NULL DEFAULT '0.0',
  PRIMARY KEY (`CountryCode`,`Language`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

あらかじめ設定した値以外の値を挿入更新すると、警告が表示され値は無視されます。"DEFAULT"値が設定されていれば"DEFAULT"値を、されていなければNULLが格納されます。



mysql> CREATE TABLE tf1 (TF ENUM('T','F'));
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO tf1 VALUES ('T');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO tf1 VALUES ('Z');
Query OK, 1 row affected, 1 warning (0.01 sec)

Warning (Code 1265): Data truncated for column 'TF' at row 1

mysql> SELECT * FROM tf1;
+------+
| TF   |
+------+
| T    |
|      |
+------+
2 rows in set (0.00 sec)

ENUM型は内部的には選択肢を番号に置き換えて格納しているため、値そのものでも割り当てられた番号でも参照、挿入などが可能です。




mysql> SELECT Code, Name, Continent FROM Country WHERE Continent = "Asia" LIMIT 2;
+------+----------------------+-----------+
| Code | Name                 | Continent |
+------+----------------------+-----------+
| AFG  | Afghanistan          | Asia      |
| ARE  | United Arab Emirates | Asia      |
+------+----------------------+-----------+
2 rows in set (0.00 sec)

mysql> SELECT Code, Name, Continent FROM Country WHERE Continent = 2 LIMIT 2;
+------+-------------+-----------+
| Code | Name        | Continent |
+------+-------------+-----------+
| NLD  | Netherlands | Europe    |
| ALB  | Albania     | Europe    |
+------+-------------+-----------+
2 rows in set (0.00 sec)

SET型は、値をカンマで区切って指定します。例えば、列の定義がSET('alpha', 'beta') NOT NULLとなっている場合、以下の4つの値を格納できます。



''
'alpha'
'beta'
'alpha,beta'

カンマで区切って指定できる値は最大64個です。

ENUM型と同様にあらかじめ設定した値以外の値を挿入更新すると、警告が表示され値は無視されます。



mysql> CREATE TABLE s1 (id SERIAL, mc SET('a', 'b', 'c') NOT NULL);
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO s1(mc) VALUES ('a'), ('a,c'), ('d');
Query OK, 3 rows affected, 1 warning (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 1

Warning (Code 1265): Data truncated for column 'mc' at row 3

格納されている値の取得にはLIKEFIND_IN_SET()関数を使用します。



mysql> SELECT * FROM s1 WHERE mc LIKE '%c%';
+----+-----+
| id | mc  |
+----+-----+
|  2 | a,c |
+----+-----+
1 rows in set (0.00 sec)

mysql> SELECT * FROM s1 WHERE FIND_IN_SET('a', mc) > 0;
+----+-----+
| id | mc  |
+----+-----+
|  1 | a   |
|  2 | a,c |
+----+-----+
2 rows in set (0.00 sec)

定義された値はENUM型同様に数値で格納されていますが、各値が2進数で扱われています。ここの例では、'a'は1、'b'は2、'c'は4となっています。'a''c'が含まれる列は合計の5となります。



mysql> SELECT * FROM s1 WHERE mc = 5;
+----+-----+
| id | mc  |
+----+-----+
|  2 | a,c |
+----+-----+
1 rows in set (0.00 sec)

列の定義が分かっている場合、ビット配列で該当する要素を1として検索することができます。以下では1要素目と3要素目を検索するためにb'101'としています。



mysql> SELECT * FROM s1 WHERE mc = CONVERT(b'101', UNSIGNED);
+----+-----+
| id | mc  |	
+----+-----+
|  2 | a,c |
+----+-----+
2 rows in set (0.00 sec)

 



著者プロフィール

  • 梶山隆輔(カジヤマリュウスケ)

    日本オラクル株式会社 MySQL Global Business Unit Asia Pacific & Japan担当 MySQL Principal Sales Consultant オラクル社において、MySQLのお客様環境への導入支援や製品の技術解説を担当するセールスコンサルタントチームのアジア太平洋地域リーダー。多国籍なMySQL部門にて、台湾、オーストラリア、インドに在籍するチームメンバーを束ね、アジア太平洋地域の25以上の国や地域でのMySQL普及やビジネスの拡大をミッションとする。  

バックナンバー

連載:MySQL事始

もっと読む

All contents copyright © 2007-2020 Shoeisha Co., Ltd. All rights reserved. ver.1.5