第2章 言語構造

データ型の概要

データ型の概要

リレーショナル型データベースは、文字列や数値、日付など、データの種類にあわせたデータ型が用意されています。データ型は、どのようなデータを扱うかをあらかじめ定義することにより、データの整合性を検査することができ、システムをより安全に運用することを可能にしています。

標準SQLでは基本的なデータ型を定義していますが、各RDBMS製品ごとに実装の違いがあるので、データ型を定義する際は注意が必要です。なるべくDMBS固有のデータ型の利用は避けて、移植性の高いデータ型を利用するように意識したほうがよいでしょう。

MySQLのデータ型は、数値型、日付・時間型、文字列型というカテゴリに大別されます。それぞれのカテゴリを一覧にしますので、テーブルを作成する際に参考にしてください。

SQL99のデータ型一覧
組込みデータ型
文字ストリング型 CHARACTER、CHARACTER VARYING、NCHAR、NVARCHAR、CLOB、NCLOB
バイナリストリング型 BLOB
ビットストリング型 BIT、BIT VARYING
数値型 INT、SMALLINT、NUMERIC、DECIMAL、FLOAT、REAL、DOUBLE
論理値型 BOOLEAN
日時型 DATE、TIME、TIMESTAMP
ユーザ定義型
DISTINCT型
構造型
構造型
行型 ROW
参照型 REF
コレクション型: ARRAY

全データ型一覧

文字列型に分類されるデータ型

テキストを表すデータ型には、固定長と可変長の2種類があります。固定長のデータ型はテーブル定義時に文字数を決め、データ領域も最初から確保することができるので、一般的に検索時に効力を発揮するといわれています。可変長のデータ型は、文字数の上限内で任意の長さの文字列が扱えます。

固定長のデータ型にはCHARACTER、可変長のデータ型にはCHARACTER VARYINGが用意されています。また、ほとんどのDBMSではCHARACTERはCHAR、CHARACTER VARYINGはVARCHARと省略することが可能です。

MySQLの場合、文字数が決まっている場合はCHAR、決まっていない場合はVARCHAR、256文字以上の文字列を扱うときはTEXTと簡単に使い分けられます。SET、ENUMといった型はMySQL専用の文字列型ですので、移植の際は注意が必要です。最大長の小さい順に VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT、固定長であればCHARを選択します。その他、CHARをリストとして扱えるENUM、SETがあります。

文字列型の一覧

[NATIONAL] CHAR(M) [CHARACTER SET キャラクタセット名] [COLLATE コレクション名]
標準SQL: CHARACTER(M)

CHARは、最大255文字までの固定長文字列を格納します。値の格納時に、文末に空白があれば削除します。Mは長さを表し、指定できる範囲は0から255文字です。

[NATIONAL] VARCHAR(M) [CHARACTER SET キャラクタセット名] [COLLATE コレクション名]
標準SQL: CHARACTER VARYING(M)

VARCHARは、最大255文字までの可変長文字列を格納します。VARCHAR型の値は固定長のCHAR型とは異なり、文字数の長さはそのままで格納されます。また、値の格納時に文末の空白を削除しません。

BINARY[(M)]

BINARYはCHARと似ていますが、バイナリバイト文字列を格納します。ソートや比較の際、ケース依存方式(=OSが大文字と小文字を区別するかによること)で行います。

VARBINARY(M)

VARBINARYはVARCHARと似ていますが、バイナリバイト文字列を格納します。 ソートや比較の際、ケース依存方式(=OSが大文字と小文字を区別するかによること)で行います。

TINYBLOB
標準SQL: BLOB

TINYBLOBは、最大255バイトまでのバイナリオブジェクトを格納します。大量の文字データや、画像データ、音声データを格納するのに適しています。VARBINARYを可変長にした型です。

TINYTEXT [CHARACTER SET キャラクタセット名] [COLLATE コレクション名]

TINYTEXTは、最大255バイトまでの非バイナリオブジェクトを格納します。

BLOB
標準SQL: BLOB

BLOBは、最大65535バイトまでの可変長のデータを格納できるバイナリオブジェクトです。大量の文字データや、画像データ、音声データを格納するのに適しています。VARBINARYを可変長にした型です。

TEXT [CHARACTER SET キャラクタセット名] [COLLATE コレクション名]

TEXTは、最大65535バイトまでの非バイナリオブジェクトを格納します。VARCHARを可変長にした型です。

MEDIUMBLOB
標準SQL: BLOB

MEDIUMBLOBは、最大16777215バイトまでの可変長のデータを格納できるバイナリオブジェクトです。大量の文字データや、画像データ、音声データを格納するのに適しています。VARBINARYを可変長にした型です。

MEDIUMTEXT [CHARACTER SET キャラクタセット名] [COLLATE コレクション名]

MEDIUMTEXTは、最大16777215バイトまでの非バイナリオブジェクトを格納します。VARCHARを可変長にした型です。

LONGBLOB
標準SQL: BLOB

LONGBLOBは、最大4294967295バイトまでの可変長のデータを格納できるバイナリオブジェクトです。大量の文字データや、画像データ、音声データを格納するのに適しています。VARBINARYを可変長にした型です。

LONGTEXT [CHARACTER SET キャラクタセット名] [COLLATE コレクション名]

LONGTEXTは、最大4294967295バイトまでの非バイナリオブジェクトを格納します。VARCHARを可変長にした型です。

ENUM ('value1','value2',...)

ENUMは、CHARをリストにしたもので、最大65535個の値を格納します。ENUMの定義は、文字列を値とする配列を宣言します。

# テストとして ENUM フィールドだけのテーブルを作成
CREATE TABLE enum_table(
	enum_col ENUM('AAA', 'BBB', 'CCC')
);

配列の要素は1から始まり、最大65535までの要素を持つことができます。フィールドの値は、要素の値になります。たとえば、上記で定義したフィールドの要素は、1から3です。そのフィールドに1を渡した場合、要素の 1 番目の値 "AAA" に変換されて格納されます。

# 要素 1 の値がフィールド値になります
INSERT enum_table SET enum_col=1;
SELECT * FROM enum_table;
出力結果
-> one
ENUM の規則
  • ENUMに無効な値を代入した場合、 空文字が挿入されます。
  • NULLと定義されたENUMは、デフォルト値がNULLになります。 もしENUMがNOT NULLと定義されたならば、 デフォルト値は、要素の最初の値になります。
  • ENUMフィールドに値を与える場合は大文字・小文字は無関係です。
  • ENUMを数値で検索した場合、その値と同じ順番の要素の値を持ったレコードが選択されます。
  • ENUMのソートは、要素の順に従って行われます。たとえば、ENUM("b", "a") ならば
    "b"、 "a" の順番にソートされます。空文字列は空ではない文字の前にソートされ、 NULLは他の要素の前に並びます。

空文字エラーの値は0です。不正なENUM値を見つけるには、以下のようにします。

SELECT * FROM tbl_name WHERE enum_col=0;

次の例では、ENUMフィールドで指定可能な値のリストを全て取りだしています。

SHOW COLUMNS FROM table_name LIKE
enum_column_name
SET('value1','value2',...)

ENUMと同じように複数の要素を持ちます。ただし、ENUMがフィールド値を文字列として格納しますが、SETは2進数のビットとして格納します。最大64個の要素を格納します。

SET型のフィールドの値は、カンマ( ,
)区切りで並べられた複数のメンバーで構成されています。そのために、 SETメンバーの値は、カンマを含むことはできません。 

# テストとして SET フィールドだけのテーブルを作成
CREATE TABLE set_table(
	set_col SET('AAA', 'BBB', 'CCC', 'DDD')
);

SETの要素 'AAA' から 'DDD'を順番に挿入するには、2進数で0001、0010、0100、1000 とします。

# 2進数で値を挿入
INSERT set_table SET set_col=0001;

SELECT * FROM set_table;
出力結果
-> AAA

SETへ代入する値は文字列、10進数、2進数が可能です。文字列の場合はSETの要素値をそのまま代入します。10進数の場合は、先頭の要素が10進数の値を1と対応、次の値からは前の要素の10進数に1を加えて代入します。たとえば、3番目の用を10進数で代入するには1番目と2番目の10進数を加え、さらに1をを加えるので、1 + 2 + 1 で4を代入することになります。2進数の場合は、右のビットから1ずつ要素の順番にずらしていきます。これらの対応表は以下のとおりです。

SETの要素値 10進数 2進数値
AAA 1 0001
BBB 2 0010
CCC 4 0100
DDD 8 1000

SETは複数の要素を選択することも可能です。この場合は単純に、要素ごとに2進数のビットをつけていくだけです。たとえば、AAA,CCC,DDD と選択したい場合は、1101 となります。BBB も選択したい場合は 1111 です。

SETの値をSELECTする場合は、LIKEかFIND_IN_SET()が便利です。

SELECT * FROM set_table WHERE set_col
LIKE '%DDD%';
SELECT * FROM set_table WHERE FIND_IN_SET('DDD',set_col);
出力結果
>0;

以下のように完全一致でSELECTすることもできます。

SELECT * FROM tbl_name WHERE set_col ='val1,val2';

SELECTする際は10進数や2進数を使えないので注意してください。

NCHAR(M) / NATIONAL CHARACTER (M)
標準SQL: NCHAR / NATIONAL CHARACTER

NCHARは、最大255文字のUnicode文字列を保持します。それ以外はCHAR型と同じです。

NATIONAL CHARACTER VARYING(M)
標準SQL: NATIONAL CHARACTER VARYING

NATIONAL CHARACTER VARYINGは、最大255文字のUnicode可変長文字列を保持します。

BLOBとTEXT

可変長のデータを保持できます。格納可能なデータの最大長によって
TINYBLOB、BLOB、MEDIUMBLOBとLONGBLOBがあります。
TEXTとBLOBの違いは、TEXTはケースに依存しないでソートと比較され、 BLOBはケースに依存して比較されることです。

TEXTはVARCHAR 、BLOBはVARCHAR BINARYの大きくなったものといえます。

BLOBとTEXTの特徴
  • インデックスを持たない
  • 値の後ろについている連続した空白文字を切り落とさない
  • DEFAULT 値を持たない
  • フィールド定義でNOT NULLを明示的に与えない限り、つねにNULLフィールドとなる
  • MyODBCはBLOBをLONGVARBINARYとして、TEXTをLONGVARCHARとして定義する

BLOB ・ TEXTフィールドをGROUP BY句やORDER BY句の対象にする場合は、フィールドの値を固定長に変換する必要があるので、 SUBSTRING関数を利用してください。

構文:
SELECT フィールド名 FROM テーブル名
ORDER BY substring(フィールド名, 20);

フィールドの位置を指定、もしくは別名を使用することによって、BLOBやTEXTの値でGROUP化できます。

構文:
SELECT id, substring(blob_col, 1, 100)

FROM テーブル名
GROUP BY 2;

SELECT id, substring(blob_col, 1, 100) AS b 
FROM テーブル名
GROUP BY b;

数値型に分類されるデータ型

数値型に分類されるデータ型は、大別すると整数と浮動少数点数があり、扱える数値の範囲によってさらに数種類が用意されています。整数用のNUMERIC、DECIMAL、INTEGER、浮動小数点数用のFLOAT、REAL、DOUBLE PRECISION、バック無し浮動少数点数用のDECIMALがあります。

パック無し
数値が文字列として格納されることを意味し、数値のそれぞれの桁、小数点、及び負数での - 符号に1文字使用します。
データ型のオプション

UNSIGNED
整数だけを扱います。そのため、扱える数値範囲が大きくなります。

ZEROFILL
全ての数値型はZEROFILLオプション属性を持てます。 ZEROFILLフィールドの値は、それらが表示される際に、左からゼロが最大長になるまでつけられます。

たとえば、INT(3) ZEROFILLと定義した場合、 8 という値は 008 となります。

(M) / (D)
Mは、最大表示サイズ、最大は 255 です。D は、浮動小数点数型に適用され、小数点以下の桁数です。
DECIMAL値の範囲は M 及び D で指定した範囲になります。たとえば、DECIMAL(4,2)とした場合、最大4桁の長さでそのうち2桁が小数点以下になます。値の範囲は、-99.99 から
999.99 となります(マイナス記号も1文字としてカウントされます)。

各整数型が必要とする範囲
タイプ バイト 最小値 最大値
TINYINT 1 -128 127
TINYINT
(UNSIGNED)
0 255
SMALLINT 2 -32768 32767
SMALLINT
(UNSIGNED)
0 65535
MEDIUMINT 3 -8388608 8388607
MEDIUMINT
(UNSIGNED)
0 16777215
INT 4 -2147483648 2147483647
INT
(UNSIGNED)
0 4294967295
BIGINT 8 -9223372036854775808 9223372036854775807
BIGINT
(UNSIGNED)
0 18446744073709551615

数値型の一覧

BIT [(M)]

BITは、ビット値を扱う型です。BITの引数Mは1から64の、各値のビット数を表しています。デフォルトは1です。

TINYINT
[(M)] [UNSIGNED] [ZEROFILL]

TINYINTは、-128 から 127 までの符号付き0 から 255 までの符号なしの整数を格納する型です。

BOOL / BOOLEAN

BOOLEANは、標準SQLではTRUE、もしくはFALSEの論理値を扱う型です。

※論理値とは、データが真であるかどうかを表す値のことです。

MySQLの現バージョンのBOOL、BOOLEANは、TINYINT(1)の同義語です。標準SQLのBOOLEANのように、ブール値を扱うために用意されたデータ型です。

扱える値はTRUE、FALSE、NULLです。

# 0 がブール値でTRUEかFALSEかを出力
SELECT IF(0, 'TRUE', 'FALSE');
出力結果
-> FALSE
# 1 がブール値でTRUEかFALSEかを出力
SELECT IF(1, 'TRUE', 'FALSE');
出力結果
-> TRUE
# 2がブール値でTRUEかFALSEかを出力
SELECT IF(2, 'TRUE', 'FALSE');
出力結果
-> TRUE

TRUEは 1 、FALSEは 0 の別名です。

SELECT TRUE, FALSE;
出力結果
-> 1 0
SELECT IF( 0 = FALSE, 'TRUE', 'FALSE' );
出力結果
-> TRUE
SELECT IF( 1 = TRUE, 'TRUE', 'FALSE' );
出力結果
-> TRUE
SMALLINT
[(M)] [UNSIGNED] [ZEROFILL]
標準SQL: SMALLINT

SMALLINTは、-32768 から 32767 までの符号付きもしくは 0 から 65535 までの符号なしの整数を格納する型です。

MEDIUMINT
[(M)] [UNSIGNED] [ZEROFILL]

MEDIUMINTは、-8388608 から 8388607 までの符号付きもしくは 0 から 16777215 までの符号なしの整数を格納する型です。

INTEGER [(M)] [UNSIGNED] [ZEROFILL] / INT
標準SQL: INTEGER, INT

INTEGER、INTは、-2147483648 から 2147483647 までの符号付きもしくは 0 から 4294967295 までの符号なしの整数を格納する型です。

BIGINT
[(M)] [UNSIGNED] [ZEROFILL]

BIGINTは、-9223372036854775808 から 9223372036854775807 までの符号付きもしくは 0 から 18446744073709551615 までの符号なしの整数を格納する型です。

DECIMAL (M,D) [ZEROFILL] / DEC / NUMERIC / FIXED
標準SQL: DECIMAL(M, D) / NUMERIC(M, D)

DECIMAL、NUMERICは、パック無し浮動小数点を格納する型です。

正確な精度で計算することができるので、たとえば貨幣などの値を扱う際などに効果的です。DECIMAL値の範囲は M 、 D で指定した範囲になります。 D を省略した場合は 0 、M
を省略した場合は 10 に設定されます。D が 0 の時、値は小数点や小数部を持ちません。M
は符号や小数点を含みます。 DECIMALがサポートする最高桁数(M)が65、最高桁数(D)は30です。

DOUBLE [(M,D)] [ZEROFILL]

DOUBLE PRECISION / REAL
標準SQL: DOUBLE PRECISION

DOUBLEは、-1.7976931348623157E+308 から -2.2250738585072014E-308、 0、2.2250738585072014E-308 から 1.7976931348623157E+308 の(倍精度)浮動小数点数を格納するデータ型です。

M は桁数の合計で、D は小数点以下の桁数の合計です。M と D が削除された場合、値はハードウェアに許容された限界まで格納されます。倍精度小数点数は大体小数第15位まで正確です。

REALは単精度、DOUBLE PRECISIONは倍精度の浮動小数点を格納する型です。DOUBLE
は引数によって単精度か倍精度かが決まります。

FLOAT (精度) [ZEROFILL]
標準SQL: FLOAT

FLOATは、浮動小数点数を格納する型です。精度をビットで表現しますが、MySQLは結果となるデータ型に対して、FLOATかDOUBLEのどちらを利用するかを決める為だけにこの値を利用します。制度が 0 から 24 の場合、そのデータ型は M や D 値が無い FLOATになります。精度が 25 から 53 の時、そのデータ型は M や D 値が無い DOUBLE になります。

FLOAT
[(M,D)] [ZEROFILL]
標準SQL: FLOAT

FLOATは、-3.402823466E+38 から -1.175494351E-38、 0、1.175494351E-38 から 3.402823466E+38 までの小さい(単精度) 浮動小数点数を格納する型です。

M は桁数の合計で、D は小数点以下の桁数の合計です。もし M と D が削除された場合、値はハードウェアに許容された限界まで格納されます。単精度小数点数は大体小数第7位まで正確です。

MySQL拡張:整数値の表示幅指定

MySQLの拡張として、型名に続けてカッコ内に指定する整数値の表示幅、例えば INT(4)
などがあります。このオプションの幅指定は、フィールドに指定された幅よりも少ない幅の値の表示の左側を埋めるために使用されます。ただし、実際の値の範囲や、桁数は制約されません。

値の範囲を超える場合

フィールドの型の値の許容範囲を超えた数値を代入しようとすると、その値は許容範囲内に切り詰められます。
たとえば、 TINYINT型の範囲は -128 から 127 ですが、999 を TINYINT型のフィールドに挿入しようとすると、値は 127 に切り詰められて格納されます。

日付型に分類されるデータ型

時間的な値を表す日付と時刻型には、DATETIME、DATE、TIMESTAMP、TIME、YEARがあります。DATETIMEが扱える日付データの書式はYYYY-MM-DD HH:MM:SS、DATEはYYYY-MM-DD、TIMEはHH:MM:SS、YEARはYY、もしくはYYYYといったように、それぞれの書式によって日付と時刻型が用意されています。

日付と時刻型は日数を加算したり減産することが可能で、書式や値の範囲に当てはまらないデータはエラーになります。

日付型の一覧

DATE

DATE型は、YYYY-MM-DD形式の日付を格納します。

DATETIME
標準SQL: DATETIME

DATETIME型は、YYYY-MM-DD HH:MM:SS形式の日付と時刻を格納します。

TIMESTAMP [(M)]
標準SQL: TIMESTAMP

TIMESTAMP型は、YYYY-MM-DD HH:MM:SS形式の日付と時刻を格納します。範囲は 1970-01-01 00:00:01 UTCから 2037年の途中までです。INSERTやUPDATE時に、自動的に現在の日付と時刻を格納します。TIMESTAMPカラムが複数ある場合は、最初のカラムのみが自動で更新されます。

※MySQLをMAXDBモードで実行している場合、TIMESTAMPはDATETIMEと同じように動作します。TIMESTAMPカラムの自動更新は行われません。

MySQL独自の仕様:MySQL 4.1より前のバージョンでは、TIMESTAMPの書式は以下の表に示すようにその表示サイズに依存します。

データ型 表示フォーマット
TIMESTAMP(14) YYYYMMDDHHMMSS 
TIMESTAMP(12) YYMMDDHHMMSS 
TIMESTAMP(10)  YYMMDDHHMM 
TIMESTAMP(8) YYYYMMDD 
TIMESTAMP(6) YYMMDD 
TIMESTAMP(4) YYMM 
TIMESTAMP(2) YY
TIME
標準SQL: TIME

TIME型は、HH:MM:SS形式、もしくはHHMMSS形式の時刻を格納します。経過時間や間隔などの時刻を格納できるように、HHは3桁の数字まで格納することができます。

YEAR[(2|4)]

YEAR型は、YY形式の2桁、またはYYYY形式の4桁(デフォルト)の年です。4桁形式は許容値が1901~2155、0000で、2桁形式が1970~2069を表す、70から69です。

DATETIME, DATE, TIMESTAMP の書式

DATETIME、DATE、TIMESTAMPは、様々な書式を使うことができます。日付や時刻の区切り文字としては、数字以外でしたら、スラッシュ( / )やドット( . )などが使えます。また、YYYYをYYで指定、区切り文字を省略することも可能です。

データ型の所要容量

データベースの設計の中でも特に難しいのが全データの所要容量の計算です。データは設計後に登録されるものですから、その容量を予測することは非常に困難で、正解というものがありません。それでも、可能な限り、必要とされるデータ容量を計算しておくことは良いことです。ここでは、個々のデータ型の所要容量を紹介します。

データ型毎の所要容量は次のとおりです。 

文字列型の容量
データ型 所要容量
CHAR(M) M バイト
VARCHAR(M) 文字列の長さ+1 バイト
TINYBLOB,
TINYTEXT
文字列の長さ+1 バイト
BLOB, TEXT 文字列の長さ+2 バイト
MEDIUMBLOB,
MEDIUMTEXT
文字列の長さ+3 バイト
LONGBLOB,
LONGTEXT
文字列の長さ+4 バイト
ENUM('value1','value2',...) 1 もしくは 2 バイト
要素数に依存 (最大値 65535 )
SET('value1','value2',...) 1~4、もしくは 8 バイト
要素数に依存 (最大要素 64 )
数値型の容量
データ型 所要容量
TINYINT 1 バイト
SMALLINT 2 バイト
MEDIUMINT 3 バイト
INT 4 バイト
INTEGER 4 バイト
BIGINT 8 バイト
FLOAT(X) X <= 24 の場合 4 バイト、25 <= X
<= 53 の場合 8 バイト
FLOAT 4 バイト
DOUBLE 8 バイト
DOUBLE
PRECISION
8 バイト
REAL 8 バイト
DECIMAL(M,D) M バイト (M < D の場合 D+2)
NUMERIC(M,D) M バイト (M < D の場合 D+2)
日付・時間型の容量
データ型 所要容量
DATE 3 バイト
DATETIME 8 バイト
TIMESTAMP 4 バイト
TIME 3 バイト
YEAR 1 バイト

VARCHAR、BLOB、TEXT型は、可変長型です。その容量はフィールド値の実際の長さに依存します。VARCHAR(10)フィールドは、最大10文字分の長さの文字列を保持し、その実際の容量は、文字列の長さ L と、その長さを記録するための1バイトを加えた数値になります。たとえば、文字列 "ABCD" においては、L は 4 で、所要容量は 5 バイトです。

ENUMのサイズは、要素数によって決まります。要素数が 255 以内では、1バイト、それ以上は 2 バイトが使用されます。

SETのサイズは、要素数によって決められます。サイズを N とすると、オブジェクトは (N+7) / 8 バイトで、1から4、または8バイトに切上げられます。

ユーザ変数

MySQLは、@variablename構文でスレッド固有の変数をサポートします。変数名は現在の文字セットのアルファベットと数字、アンダーライン( _ )、ダラー( $ )、ドット( . )文字からなります。デフォルト文字セットは ISO-8859-1 Latin1 で、mysqld に --default-character-set オプションを与えることで変更できます。

変数の初期値はNULLです。変数は整数値、実数値、文字列値が格納可能です。

SET構文で変数を設定

SET @variable= { integer expression |
real expression | string expression }
[,@variable= ...].

@variable:=expr 構文で、式中で変数を設定

select
@t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
-> 5 5 1 4

ユーザ変数は式が許される場所で使用できます。

注意: SELECT句のLIMIT 節、LOAD DATA ステートメントの IGNORE number LINESのように、数値が明示的に要求される文脈での使用は例外です。

※SELECT句では、それぞれの式はクライアントに送られた時にだけ評価されます。これは、SELECT部で設定された変数を必要とする式を参照する HAVING, GROUP BY, ORDER BY節ができないことを意味します。
※SELECT句のLIMIT 節、LOAD DATAステートメントの IGNORE number LINESのように、数値が明示的に要求される文脈での使用は例外です。

例えば、次のステートメントは期待通りには動作しません。

SELECT (@aa:=id) AS a, (@aa+3) AS b FROM table_name HAVING b=5;

この理由は、@aa が現在のレコードの値ではなく、前に受け取ったレコードの id の値になるからです。

関連記事