目次
MySQLは次のようないくつかのカテゴリのデータタイプをサポートします。数値タイプ、データと時刻タイプ、そして文字列(文字)タイプです。この章ではまず最初にこれらのデータタイプの概要を紹介します。そして次にそれぞれのカテゴリタイプの特性についてのより詳しい説明と、データタイプに必要な記憶容量に関する条件の要約を紹介します。最初の概要はあえて簡単な物になっています。値の指定ができる許容フォーマットのような特定のデータタイプに関する追加情報に関しては、この章の後半で紹介しているより詳しい説明を参照してください。
MySQLは、空間データの拡張子もサポートします。16章Spatial Extensionsにこれらのデータタイプの情報があります。
いくつかのデータタイプの紹介の中で、これらの規則が使用されています。
数値データタイプの要約が次に紹介されます。追加情報については 「数値タイプ」 を参照してください。必要とする記憶容量は 「データタイプが必要とする記憶容量」 に紹介されています。
M
は整数タイプの最大ディスプレイ幅を示しています。最大法定ディスプレイ幅は255です。「数値タイプ」で説明されているように、ディスプレイ幅はそのタイプの許容値幅とは関係ありません。浮動小数点と固定小数点タイプに関しては、M
が格納可能な桁数の合計です。
数値コラムに対して ZEROFILL
を指定すると、MySQLは自動的にそのカラムに
UNSIGNED 属性を追加します。
SERIAL は BIGINT UNSIGNED NOT NULL
AUTO_INCREMENT UNIQUE の別名です。
整数カラム定義の中の SERIAL DEFAULT
VALUE は NOT NULL AUTO_INCREMENT
UNIQUE の別名です。
警告:1つが
UNSIGNED
タイプの時に整数値間で減算を行うと、NO_UNSIGNED_SUBTRACTION
SQLモードが有効でない限り、その結果から符号がなくなります。「キャスト関数と演算子」を参照してください。
ビットフィールドタイプ
Mは1から64の、各値のビット数を表しています。Mが削除された場合、デフォルトは1です。TINYINT[(M)] [UNSIGNED] [ZEROFILL]大変小さい整数符号が付く範囲は
-128から127です。符号が付かない範囲は0から255です。これらのタイプは
TINYINT(1)の同義語です。ゼロの値は誤りであるとみなされます。ゼロ以外の値は正確だとみなされます。mysql>
SELECT IF(0, 'true', 'false');+------------------------+ | IF(0, 'true', 'false') | +------------------------+ | false | +------------------------+ mysql>SELECT IF(1, 'true', 'false');+------------------------+ | IF(1, 'true', 'false') | +------------------------+ | true | +------------------------+ mysql>SELECT IF(2, 'true', 'false');+------------------------+ | IF(2, 'true', 'false') | +------------------------+ | true | +------------------------+しかしここに示されているように、
TRUE値とFALSEはそれぞれが1と0の単なる別名です。mysql>
SELECT IF(0 = FALSE, 'true', 'false');+--------------------------------+ | IF(0 = FALSE, 'true', 'false') | +--------------------------------+ | true | +--------------------------------+ mysql>SELECT IF(1 = TRUE, 'true', 'false');+-------------------------------+ | IF(1 = TRUE, 'true', 'false') | +-------------------------------+ | true | +-------------------------------+ mysql>SELECT IF(2 = TRUE, 'true', 'false');+-------------------------------+ | IF(2 = TRUE, 'true', 'false') | +-------------------------------+ | false | +-------------------------------+ mysql>SELECT IF(2 = FALSE, 'true', 'false');+--------------------------------+ | IF(2 = FALSE, 'true', 'false') | +--------------------------------+ | false | +--------------------------------+最後の二つのステートメントは、
2は、1とも0とも等しくないので、表示される結果を表しています。今後リリースされるMySQLの中で、標準SQLに基づき、ブーリアンタイプの扱いについて完全にカバーしていく予定です。
SMALLINT[(M)] [UNSIGNED] [ZEROFILL]小さい整数符号が付く範囲は
-32768から32767です。符号が付かない範囲は0から65535です。MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]中間サイズの整数符号が付く範囲は
-8388608から8388607です。符号が付かない範囲は0から16777215です。INT[(M)] [UNSIGNED] [ZEROFILL]普通サイズの整数符号が付く範囲は
-2147483648から2147483647です。符号が付かない範囲は0から4294967295です。INTEGER[(M)] [UNSIGNED] [ZEROFILL]このタイプは
INTの同義語です。BIGINT[(M)] [UNSIGNED] [ZEROFILL]大きい整数符号が付く範囲は
-9223372036854775808から9223372036854775807です。符号が付かない範囲は0から18446744073709551615です。BIGINTカラムに関して注意するべき事全ての演算は符号付の
BIGINTかDOUBLE値を利用しているので、ビット関数を使わない限り9223372036854775807(63ビット) 以上の大きい符号無し整数は利用してはいけません!もしそれをしてしまうと、BIGINT値からDOUBLEに変換する時、丸め誤差の為に、結果の最後のいくつかの桁に誤差が出るかもしれません。MySQLは、次のような時に
BIGINTを扱う事ができます。BIGINTカラムに符号無しの大きい値を格納するのに整数を使用する時col_nameがBIGINTカラムを参照する、MIN(やcol_name)MAX(の中col_name)両方の演算数が整数の場合に、(
+、-、*、等の) 演算子を利用する時
文字列を利用する事で、正確な整数を
BIGINTカラムに格納できます。この場合MySQLは、中間倍精度表現を含まない、文字列から数値への変換を行います。両方の演算数が整数の場合、
-、+、そして*演算子は、BIGINT演算を利用します。これは、もし二つの大きい整数を掛け合わした場合、(または整数を戻す関数からの結果)、その結果が9223372036854775807以上の時には、予期しない結果になるという事を意味します。
FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]小さい(単精度) 浮動小数点数許容値は
-3.402823466E+38から-1.175494351E-38、0、そして1.175494351E-38から3.402823466E+38です。これらは、IEEEスタンダードに基づいた理論的な限界です。利用するハードウェアやOSによっては、実際の範囲は少し小さくなるかも知れません。Mは桁数の合計で、Dは小数点以下の桁数の合計です。もしMとDが削除された場合、値はハードウェアに許容された限界まで格納されます。単精度小数点数は大体小数第7位まで正確です。UNSIGNEDが指定されている場合、負数は許可されません。MySQLでは全ての計算が倍精度で行われているので、
FLOATを利用すると、予想外の問題が起きます。「Solving Problems with No Matching Rows」を参照してください。DOUBLE[(M、D)] [UNSIGNED] [ZEROFILL]普通サイズ(倍精度)浮動小数点数許容値は
-1.7976931348623157E+308から-2.2250738585072014E-308、0、そして2.2250738585072014E-308から1.7976931348623157E+308です。これらは、IEEEスタンダードに基づいた理論的な限界です。利用するハードウェアやOSによっては、実際の範囲は少し小さくなるかも知れません。Mは桁数の合計で、Dは小数点以下の桁数の合計です。もしMとDが削除された場合、値はハードウェアに許容された限界まで格納されます。倍精度小数点数は大体小数第15位まで正確です。UNSIGNEDが指定されている場合、負数は許可されません。DOUBLE PRECISION[(、M,D)] [UNSIGNED] [ZEROFILL]REAL[(M,D)] [UNSIGNED] [ZEROFILL]これらのタイプは
DOUBLEの同義語です。例外 :REAL_AS_FLOATSQLモードが無効の時は、DOUBLEではなくREALがFLOATの同義語になります。FLOAT(p) [UNSIGNED] [ZEROFILL]浮動小数点数です。
pは精度をビットで表現しますが、MySQLは結果となるデータタイプに対して、FLOATかDOUBLEのどちらを利用するかを決める為だけにこの値を利用します。pが0から24の時、そのデータタイプはMやD値が無いFLOATになります。pが25から53の時、そのデータタイプはMやD値が無いDOUBLEになります。結果となるカラムの範囲は、このセクションの最初の方で説明されているように、単精度FLOATか倍精度DOUBLEデータタイプの物と同じです。DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]ひとかたまりの 「精密」 固定小数点
Mは桁数の合計で、(精度)Dは小数点以下の桁数の合計です。(縮尺)小数点と(負数に対する) ‘-’ 記号はMの中ではカウントされません。Dが0の時は、小数点や端数部はありません。DECIMALの最高桁数 (M) は65です。サポートされる最高桁数 (D)は30です。Dが削除された時のデフォルトは0です。Mが削除された時のデフォルトは10です。UNSIGNEDが指定されている場合、負数は許可されません。DECIMALカラムを利用した全ての基本的な計算 (+, -, *, /) は、65桁の精度で行われます。DEC[(,M[,D])] [UNSIGNED] [ZEROFILL]NUMERIC[(,M[,D])] [UNSIGNED] [ZEROFILL]FIXED[(M[,D])] [UNSIGNED] [ZEROFILL]これらのタイプは
DECIMALの同義語です。FIXED同義語は他のデータベースと互換性があります。
時間データタイプの要約が次に紹介されます。追加情報については 「日付と時刻タイプ」 を参照してください。必要とする記憶容量は 「データタイプが必要とする記憶容量」 に紹介されています。
DATETIME と DATE
範囲の説明では、「サポートする」というのは、以前の値が有効であったとしても、その保障は無いという意味になります。
SUM() と AVG()
総計関数は、一時的な値とは機能しません。(それらは値を数字に変換するので、最初の数字ではない文字から後ろの部分がなくなってしまいます。)この問題を防ぐ為には、数字単位に変換し総計作業を行い、そしてもう一度一時的な値に変換し直せば良いです。例:
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(time_col))) FROMtbl_name; SELECT FROM_DAYS(SUM(TO_DAYS(date_col))) FROMtbl_name;
日付です。サポートされている範囲は
'1000-01-01'から'9999-12-31'です。MySQL は、DATE値を'YYYY-MM-DD'フォーマットで表示しますが、文字列と数字のどちらでDATEカラムに値を指示してもよいです。日付と時刻の組み合わせです。サポートされている範囲は
'1000-01-01 00:00:00'から'9999-12-31 23:59:59'です。MySQL は、DATETIME値を'YYYY-MM-DD HH:MM:SS'フォーマットで表示しますが、文字列と数字のどちらでDATETIMEカラムに値を指示してもよいです。タイムスタンプです。範囲は
'1970-01-01 00:00:01'UTCから2037年の途中までです。TIMESTAMP値は ('1970-01-01 00:00:00'UTC)からの秒数として格納されます。TIMESTAMPは、'1970-01-01 00:00:00'値を表す事はできません。なぜならば、これはその時から0秒である事に相当し、0という値は'0000-00-00 00:00:00'つまり、「ゼロ」TIMESTAMP値 を表すのに用いられるからです。TIMESTAMPカラムはINSERTまたはUPDATE操作の日付と時刻を記録するのに役立ちます。自分で値を指定しない限り、テーブルのTIMESTAMPカラムはデフォルトで一番最近の操作の日付と時刻に自動的にセットされます。NULL値を指定する事で、現在の日付と時刻をTIMESTAMPカラムに設定する事もできます。自動初期設定と更新の特徴については 「TIMESTAMPMySQL 4.1での性質」 の中で説明されています。ディスプレイ幅が19文字に固定されている
'YYYY-MM-DD HH:MM:SS'フォーマットの中では、TIMESTAMP値は文字列として戻されます。数字の値を得る為には+0をタイムスタンプカラムに加える必要があります。注:MySQL 4.1以前で使用されていた
TIMESTAMPフォーマットはMySQL 5.1 の中ではサポートされていません。古いフォーマットに関する情報については、 MySQL 3.23, 4.0, 4.1 リファレンスマニュアル を参照してください。時刻です。範囲は
'-838:59:59'から'838:59:59'です。MySQL は、TIME値を'HH:MM:SS'フォーマットで表示しますが、文字列と数字のどちらでTIMEカラムに値を指示してもよいです。2桁、または4桁のフォーマットでの年です。デフォルトは4桁のフォーマットです。4桁のフォーマットでは、許容値は
1901から2155、そして0000です。2桁のフォーマットでは、許容値は1970年から2069年を表す、70から69です。MySQLはYEARの値をYYYYフォーマットで表示しますが、YEARカラムには文字列と数字のどちらを使って値を指定する事もできます。
文字列データタイプの要約が次に紹介されています。追加情報については 「文字列タイプ」 を参照してください。必要とする記憶容量は 「データタイプが必要とする記憶容量」 に紹介されています。
MySQLは時々、文字列カラムを CREATE
TABLE や ALTER TABLE
ステートメントで与えられているタイプとは違う物に変更する事があります。「サイレント カラム仕様変更」を参照してください。
MySQL 4.1以降の中には、MySQL4.1以前のバージョンには無かった文字列データタイプの特徴が含まれます。
MySQLは、文字単位の中の文字カラム定義の長さ仕様を解明します。(MySQL 4.1以前は、カラム長さはバイトで解釈されていました。)これは、
CHAR、VARCHAR、そしてTEXTタイプに適応されます。多くの文字列データタイプのカラム定義に、文字セットやカラム照合を指定する属性を含む事ができます。これらの属性は
CHAR、VARCHAR、TEXTタイプ、ENUM、そしてSETデータタイプに適応します。CHARACTER SET属性は文字セットを指定し、そしてCOLLATE属性は文字セットの照合を指定します。例:CREATE TABLE t ( c1 VARCHAR(20) CHARACTER SET utf8, c2 TEXT CHARACTER SET latin1 COLLATE latin1_general_cs );このテーブル定義は、キャラクタセットのデフォルト照合を使った
utf8のキャラクタセットを持つc1という名前のカラムと、latin1のキャラクタセットと大文字と小文字を区別する照合を持つc2という名前のカラムを作成します。CHARSETはCHARACTER SETの同義語です。ASCII属性はCHARACTER SET latin1の省略表現です。UNICODE属性はCHARACTER SET ucs2の省略表現です。BINARY属性は、カラム文字セットのバイナリ照合を指定する省略表現です。この場合、ソートと比較は数値文字値に基づきます。(MySQL 4.1以前のバージョンでは、BINARYはカラムにバイナリ文字列を格納させ、ソートと比較は数値バイト値に基づいていました。これは1バイト文字セットに文字値を使用するのと同じですが、複数バイト文字セットに使用するのとは違います。)
文字カラムのソートと比較は、カラムに割り当てられた文字セットに基づいています。(MySQL 4.1バージョン以前は、ソートと比較はサーバー文字セットの照合に基づいていました。)
CHAR、VARCHAR、TEXT、ENUM、そしてSETデータタイプに対して、語彙の順番ではなく基礎となる文字コード値を利用する為に、バイナリ照合を持つカラムか、ソートと比較を行うBINARY属性を宣言する事ができます。
9章キャラクタセットサポートMySQLの中での文字セットの使用についての追加情報を紹介しています。
[NATIONAL] CHAR(M) [CHARACTER SETcharset_name] [COLLATEcollation_name]格納時に必ずスペースを使って指定された長さに詰められる固定長文字列。
Mはカラム長さを表します。Mの範囲は、0から255文字です。注:
CHAR値が検索された時、後続スペースは削除されます。CHARの長さを255以上に設定しようとすると、CREATE TABLEかALTER TABLEステートメントが実行されたテーブル内でエラーが発生し、その作業は失敗します。mysql>
CREATE TABLE c1 (col1 INT, col2 CHAR(500));ERROR 1074 (42000): Column length too big for column 'col' (max = 255); use BLOB or TEXT instead mysql>SHOW CREATE TABLE c1;ERROR 1146 (42S02): Table 'test.c1' doesn't existCHARはCHARACTERの省略表現です。NATIONAL CHAR(またはそれと同等であるNCHAR) は、CHARカラムが定義済文字セットを使用しなければいけないという事を定義する為の標準のSQLの方法です。MySQL 4.1以降のバージョンでは、この定義済文字セットとしてutf8を利用します。 「各国キャラクタセット」.CHAR BYTEデータタイプはBINARYデータタイプの別名です。これは互換性の特徴です。MySQLで
CHAR(0)タイプのカラムを作成する事ができます。これは主に、カラムの存在に頼っていても、その値は実際には使用しない古いアプリケーションに対応する必要がある時に便利な物です。CHAR(0)はまた、二つの値だけを取り込む事ができるカラムが必要な時にも大変便利です。CHAR(0) NULLとして定義されたカラムは1ビットだけ使用し、NULLと''(空の文字列)値だけを取り込む事ができます。CHAR [CHARACTER SETcharset_name] [COLLATEcollation_name]このタイプは
CHAR(1)の同義語です。[NATIONAL] VARCHAR(M) [CHARACTER SETcharset_name] [COLLATEcollation_name]可変長文字列です。
Mはカラムの最大長さを表します。Mの範囲は0から65,535です。(VARCHARの実際の最大長さは使用する最大行サイズと文字セットによって決まります。最大有効カラム長さは65,532バイトの行サイズによります。)注:MySQL 5.1 は、標準SQL仕様に従うので、
VARCHAR値から後続スペースを削除しません。VARCHARはCHARACTER VARYINGの省略表現です。VARCHARは1バイト、または2バイトの長さのプリフィックスに加え、データと共に格納されています。VARCHARカラムが255以上の長さであればプリフィックスの長さは2バイトです。BINARYタイプはCHARタイプと似ていますが、非バイナリ文字の文字列ではなく、バイナリバイト文字列を格納します。VARBINARYタイプはVARCHARタイプと似ていますが、非バイナリ文字の文字列ではなく、バイナリバイト文字列を格納します。最長255 (28 – 1) バイトの
BLOBカラムです。TINYTEXT [CHARACTER SETcharset_name] [COLLATEcollation_name]最長255 (28 – 1) 文字の
TEXTカラムです。最長65,535 (216 – 1) バイトの
BLOBカラムです。長さ
Mを任意で利用する事もできます。もしこれを実行すると、MySQLはMバイトの長さの値を保持するのに十分な最小BLOBを作成します。TEXT[(M)] [CHARACTER SETcharset_name] [COLLATEcollation_name]最長65,535 (216 – 1) 文字の
TEXTカラムです。長さ
Mを任意で利用する事もできます。もしこれを実行すると、MySQLはM文字の長さの値を保持するのに十分な最小TEXTタイプを作成します。最長16,777,215 (224 – 1) バイトの
BLOBカラムです。MEDIUMTEXT [CHARACTER SETcharset_name] [COLLATEcollation_name]最長16,777,215 (224 – 1) 文字の
TEXTカラムです。最長4,294,967,295、または4GB (232 – 1) バイトの
BLOBカラムです。LONGBLOBカラムの有効な(許可されている)最長長さは、クライアント/サーバープロトコルと使用可能メモリの中に組み込まれている最大パケットサイズにより決まります。LONGTEXT [CHARACTER SETcharset_name] [COLLATEcollation_name]最長4,294,967,295、または4GB (232 – 1) バイトの
TEXTカラムです。LONGTEXTカラムの有効な(許可されている)最長長さは、クライアント/サーバープロトコルと使用可能メモリの中に組み込まれている最大パケットサイズにより決まります。ENUM('value1'、'value2',...)[CHARACTER SETcharset_name] [COLLATEcollation_name]一覧表です。
'、value1''、value2'...、NULLまたは特別な''エラー値のリストから選択された、1つの値しか持つ事ができない文字列オブジェクトです。ENUMカラムは最高65,535 の異なる値を持つ事ができます。ENUM値は、内部的には整数として表されます。SET('value1'、,'value2',...)[CHARACTER SETcharset_name] [COLLATEcollation_name]設定です。それぞれが、
'、value1''、value2'...値のリストから選択されなければいけない、ゼロ、またはそれ以上の値を持つ事ができる文字列オブジェクトです。SETカラムは最高64メンバを持つ事ができます。SET値は、内部的には整数として表されます。
データタイプ仕様の中の DEFAULT
条項はカラムのデフォルト値を表します。例外がひとつあります。デフォルト値は一定でなければいけませんので、それは関数や式にはなり得ません。これは例えば、日付カラムの値に
valueNOW() や CURRENT_DATE
のような関数の値をデフォルトとして設定する事はできないという意味です。例外として、TIMESTAMP
カラムのデフォルトとして
CURRENT_TIMESTAMP
を指定する事ができます。「TIMESTAMP MySQL 4.1での性質」を参照してください。
BLOB と TEXT
カラムはデフォルト値として指定する事ができません。
もしカラム定義が 明示的な DEFAULT
値を含まない場合、MySQLはデフォルト値を次のように規定します。
もし NULL
を値として取る事ができるなら、そのカラムは明示的な
DEFAULT NULL
条項で定義する事ができます。
もし NULL
を値として取る事ができなければ、MySQLは明示的な
DEFAULT
条項でカラムを定義できません。データの入力に関しては、もし
INSERT か REPLACE
ステートメントがカラムの値を含んでいなければ、MySQLはその時有効なSQLモードに従ってカラムを扱います。
もしストリクトSQLモードが有効でなければ、MySQLはカラムデータタイプに暗黙のデフォルト値を設定します。
もしストリクトモードが有効だと、トランザクションテーブルにエラーが起き、ステートメントがロールバックされます。非トランザクションテーブルではエラーが起きますが、もしこれが複数行ステートメントの2行目か後続の行に対してのエラーだとすると、その先行する行が挿入されるでしょう。
テーブル t
が次のように定義されたと仮定してください。
CREATE TABLE t (i INT NOT NULL);
この場合、i
は明示的デフォルトを持ちませんので、ストリクトモードで次の各ステートメントがエラーを発生させ、行の挿入は行われません。もしストリクトモードを使用しない場合、3つ目のステートメントだけがエラーを発生させます。暗黙のデフォルトが最初の2つのステートメントに挿入されますが、DEFAULT(i)
が値を作り出す事ができない為に、3つ目のステートメントは失敗するのです。
INSERT INTO t VALUES(); INSERT INTO t VALUES(DEFAULT); INSERT INTO t VALUES(DEFAULT(i));
詳しくは 「SQL モード」 を参照してください。
与えられたテーブルに対して、どのカラムが明示的な
DEFAULT
条項を持つかを確かめる為に、 SHOW CREATE
TABLE
ステートメントを利用する事ができます。
暗黙のデフォルトは次のように定義されます。
AUTO_INCREMENT属性で宣言された整数タイプ以外の数値タイプのデフォルトは0です。AUTO_INCREMENTカラムのデフォルト値は、その配列の中の次の値です。TIMESTAMP以外の日付と時刻タイプのデフォルトには、「ゼロ」値が適切です。テーブルの最初のTIMESTAMPカラムのデフォルト値は現在の日付けと時刻です。「日付と時刻タイプ」を参照してください。ENUMではない文字列タイプのデフォルト値は空の文字列です。ENUMのデフォルトは、最初の列挙値です。
MySQLは標準SQLの全ての数値データタイプをサポートします。これらのタイプは、概数値データタイプ(FLOAT、REAL、DOUBLE
PRECISION)だけでなく、真数値データタイプ(INTEGER、SMALLINT、DECIMAL、
NUMERIC)を含みます。キーワード
INT は INTEGER
のシノニムで、キーワード DEC は
DECIMAL
のシノニムです。数値タイプが必要とする記憶容量に関しては、「データタイプが必要とする記憶容量」を参照してください。
BIT
データタイプはビットフィールド値を格納します。これは、MyISAM、MEMORY、
InnoDB
テーブルに対してサポートされています。
SQL標準への拡張として、MySQLは
TINYINT、MEDIUMINT、
BIGINT
などの整数タイプもサポートします。次のテーブルには、各整数タイプが必要とする容量と値の範囲が示されています。
| タイプ | バイト | 最小値 | 最大値 |
| (Signed/Unsigned) | (Signed/Unsigned) | ||
TINYINT | 1 | -128 | 127 |
0 | 255 | ||
SMALLINT | 2 | -32768 | 32767 |
0 | 65535 | ||
MEDIUMINT | 3 | -8388608 | 8388607 |
0 | 16777215 | ||
INT | 4 | -2147483648 | 2147483647 |
0 | 4294967295 | ||
BIGINT | 8 | -9223372036854775808 | 9223372036854775807 |
0 | 18446744073709551615 |
MySQLがサポートするその他の拡張として、各タイプの基本キーワードに続くカッコ内に整数データタイプの表示幅を指定するオプションがあります(例
INT(4))。この表示幅オプションは、カラムに指定された幅よりも小さい幅の整数値を表示する際に左側をスペースで埋めるために使用されます。
この表示幅は、カラムに格納する事ができる値の範囲も、カラムに指定された幅を超える値の表示される桁数も制限しません。例えば、SMALLINT(3)
として指定されたカラムは、通常の
-32768 から 32767 の
SMALLINT
範囲を持ち、そして、3文字で許容された範囲外の値は3文字以上の文字を使って表示されます。
オプションの拡張属性 ZEROFILL
が続いて指定された時は、デフォルトはスペースである埋め込み文字はゼロで置き換えられます。例えば、INT(5)
ZEROFILL
として宣言されたカラムには、4
の値は 00004
として表示されます。もし整数カラムの中に表示幅よりも大きい値を格納すると、MySQLが複雑なJOINに対してテンポラリテーブルを生成した時に問題が発生するという事に注意してください。これはMySQLは、データは元のカラム幅に収まると仮定するからです。
注:ZEROFILL
属性はカラムが式や UNION
クエリに含まれている時は無効になります。
全ての整数タイプは、任意の(標準ではない)
拡張子である UNSIGNED
を持つ事ができます。正数だけをコラムの中で許可し、大きい上位数値範囲が必要な時には符号無しの値を利用できます。例えば、INT
カラムが UNSIGNED
の時、カラム範囲のサイズは同じですが、その終点は
-2147483648 と 2147483647
から、0 と 4294967295
までシフトします。
浮動小数点と固定小数点も UNSIGNED
になり得ます。整数タイプと同じように、この拡張子は負の値がカラムの中に格納されるのを防ぎます。しかし整数タイプとは違い、カラム値の上限は同じままです。
数値コラムに対して ZEROFILL
を指定すると、MySQLは自動的にそのカラムに
UNSIGNED 属性を追加します。
浮動小数点タイプでは、MySQLは単精度値には4バイトを使用し、倍精度値には8バイト使用します。
FLOAT と DOUBLE
データタイプは、近似数値データ値を表す為に利用されます。FLOAT
には、SQL基準は、括弧に囲まれたキーワード
FLOAT
に続くビットの中で精度の任意仕様
(指数の範囲ではない)
を許容します。MySQLはまた、この任意精度仕様もサポートしますが、その精度値は格納サイズを決定する為だけに使用されます。0から23の精度は、4バイトの単精度
FLOAT
カラムをもたらします。24から53の精度は、8バイトの倍精度
DOUBLE カラムをもたらします。
MySQLは標準ではない構文を許容します。FLOAT(、M,D)REAL(
またば M,D)DOUBLE
PRECISION(。ここで、「M,D)(」
が意味するのは、値は合計で
M、D)M
桁まで格納でき、そのうちの
D 桁は小数点以下である
という事です。例えば、FLOAT(7,4)
として定義されたカラムは、表示された時には
-999.9999
の様に見えます。MySQLは、値を格納する時に丸めを行いますので、FLOAT(7,4)
カラムに 999.00009
を挿入すると、おおよその結果は
999.0001 になります。
MySQLは DOUBLE を DOUBLE
PRECISION
(標準ではない拡張子)の同義語として扱います。MySQLはまた、REAL_AS_FLOAT
SQLモードが有効でない限り REAL を
DOUBLE PRECISION
(標準ではない変動)の同義語として扱います。
最大ポータビリティの為に、おおよその数値データ値のコードを必要とする格納は、精度仕様や桁数の無いFLOAT
か DOUBLE PRECISION
を利用する必要があります。
DECIMAL と NUMERIC
データタイプは、真数値データ値を格納するために利用されます。MySQLでは、NUMERIC
は DECIMAL
として実行されます。これらのタイプは、金銭データ等の正確な精度を必要とする物を格納するために利用されます。
MySQL 5.1 は、DECIMAL と
NUMERIC
値をバイナリフォーマットに格納します。MySQL
5.0.3バージョン以前では、それらは文字列として格納されていました。22章精密計算を参照してください。
DECIMAL や NUMERIC
カラムを宣言する時は、精度とスケールを指定する事ができます。(そして実際に通常は指定しています。)
次がその例です。
salary DECIMAL(5,2)
この例の中では、5
は精度で、2
がスケールです。精度は、その値に格納された有効な桁数を表し、スケールは小数点以下に格納できる桁数を表しています。もしスケールが0なら、DECIMAL
と NUMERIC
値は小数点と、小数点以下の数字を持ちません。
標準SQLでは、salary
カラムは5桁で、かつ小数点以下2桁の値を格納する必要があります。それ故この場合、salary
カラムに格納できる値の範囲は、-999.99
から 999.99 です。
標準SQLでは、構文
DECIMAL(
は、M)DECIMAL(
に相当します。同じように、構文
M,0)DECIMALは、DECIMAL(
に相当し、その M,0)M
の値はインプリメンテーションが決定する事ができます。MySQLは、この両方の
DECIMAL と NUMERIC
構文の改良形をサポートします。M
のデフォルト値は10です。
DECIMAL や NUMERIC
の最大桁数は65ですが、DECIMAL や
NUMERIC
カラムの実際の範囲はカラムの精度やスケールに制約される事があります。そのようなカラムが、指定スケールで許容されている小数点以下の桁数よりも多い桁数の値を指定した場合、その値はそのスケールに変換されます。(厳密には、OS特有の機能をするのですが、通常その結果は許容桁数の切捨てになります。)
BIT
データタイプは、ビットフィールド値を格納するのに利用されます。BIT(
のタイプは、M)M
ビット値の格納を許容します。M
の範囲は1から64までが可能です。
ビット値を指定するには、b'
表記を利用する事ができます。value'value
はゼロと1で書かれたバイナリ値です。例えば、b'111'
と b'10000000'
は、それぞれ7と128を表しています。「ビットフィールド値」を参照してください。
M ビットよりも短い
BIT(
カラムに値を指定すると、その値の左側にゼロが埋め込まれます。例えば、M)BIT(6)
カラムに b'101'
の値を指定すると、実際には
b'000101'
を指定した事と同じ意味になるのです。
そのデータタイプの許容範囲外の値を数値カラムに格納しようとすると、MySQLの反応はその時有効なSQLモードによって決まります。例えば、もし制限モードが有効でない場合、MySQLは値をその範囲の適切な長さに短縮し、その結果出た値を代わりに格納します。しかし、もしモードが
TRADITIONAL
に設定されていると、SQLスタンダードに従いエラーが発生し、MySQLは範囲外の値を受け付けず、挿入は失敗します。
非ストリクトモードで整数カラムに範囲外の値が指定された時、MySQLはそのカラムデータタイプの範囲に相当する終点の値を格納します。TINYINT
か TINYINT UNSIGNED
カラムに256を格納すると、MySQLはそれぞれに127か255を格納します。浮動小数点や固定小数点カラムが、指定された(またはデフォルトの)精度とスケールの暗黙範囲を超えた値を割り当てると、MySQLはその範囲に対応する終点を表す値を格納します。
MySQLがストリクトモードで機能していない時の短縮によって行われた変換は、ALTER
TABLE、LOAD DATA
INFILE、UPDATE、そして複数行
INSERT
ステートメントに対しては警告としてレポートされます。MySQLがストリクトモードで機能している時は、そのテーブルがトランザクションテーブルかそれ以外の物なのかによって、これらのステートメントは失敗となり、いくつかの、または全ての値の挿入も変更も行われません。詳細に関しては
「SQL モード」 を参照して下さい。
時間的な値を表す日付と時刻タイプは、DATETIME、DATE、TIMESTAMP、
TIME、そして YEAR
です。MySQLが表す事のできない不正データを指示した時に利用される「ゼロ」値と同様に、各時刻タイプは有効値範囲を持ちます。TIMESTAMP
タイプには、後に紹介されますが、特別な更新機能があります。時刻タイプが必要とする記憶容量に関しては、「データタイプが必要とする記憶容量」
を参照してください。
MySQLは不正データを挿入すると警告かエラーを発生させます。SQLモードを適切な値に設定する事で、MySQLがサポートする日付のタイプを指定する事ができます。(詳しくは
「SQL モード」
をご確認ください。)ALLOW_INVALID_DATES
SQLモードを利用する事によって、'1999-11-31'
のような確実な日付をMySQLに指定する事ができます。これは、ユーザーが将来の処理の為にデータベースの中で指定した「間違っているかもしれない」値を格納したい時に便利です。このモードの時MySQLは、月は0から12の範囲、日付は0から31の範囲でしか確認しません。MySQLが
DATE か DATETIME
カラムの中で日付、または月と日付がゼロであるデータの格納を許可するので、これらの範囲はゼロを含むと定義されています。これは、誕生日など、正確な日付が不明なデータを格納する必要があるアプリケーションに大変便利です。その場合は、'1999-00-00'
や '1999-01-00'
等のようにデータを格納するだけでよいのです。このようなデータを格納する時は、DATE_SUB()
や DATE_ADD
など、正確な日付を必要とする物のように、正確な結果を期待する事はできません。(もし日付にゼロを利用したくないのであれば、NO_ZERO_IN_DATE
SQLモードを利用する事ができます。)
MySQLではまた、'0000-00-00' を
「ダミーの日付」
(もしNO_ZERO_DATE
SQLモードを利用していないのであれば)として格納する事ができます。これは、NULL
値を利用するよりも便利な事が多いです。(データとインデックスの容量も少量で済みます。)
日付と時刻タイプを利用する際の注意事項があります。
MySQLは標準アウトプットフォーマットの中で入力された日付や時刻の値を検索しますが、提供された値に対して、いくつものフォーマットを読み取ろうとします。(例えば、日付や時刻タイプに指定される、または比較される値を指定した時。)次のセクションで紹介されているフォーマットだけがサポートされています。正当な値を提供しなければいけません。もし他のフォーマットの値を使用すると、予期しない結果が出る可能性があります。
2桁の年を含む日付の値は、世紀が不明な為あいまいです。MySQLは2桁の年の値を次のルールに従って解釈します。
70-99の範囲の年の値は1970-1999に変換されます。00-69の範囲の年の値は2000-2069に変換されます。
MySQLが値をいくつかのフォーマットで読み取るとしても、日付は一般的に頻繁に使われる、月-日-年や、日-月-年の順番ではなく、(例えば
'09-04-98'、'04-09-98')、年-月-日の順番(例えば'98-09-04')で入力する必要があります。MySQLは、その値が数字で利用されれば、日付と時刻タイプの値を数字に変換し、またその反対も行います。
デフォルトでは、MySQLに日付や時刻タイプの範囲外の値や、そのタイプには不正なデータ(このセクションの始めで触れたように)が入力された時は、その値を 「ゼロ」 に変換します。その例外は、範囲外の
TIME値はTIME範囲の適切な終点にクリップされるという事です。次のテーブルに、それぞれのタイプの 「ゼロ」 値のフォーマットが表されています。
NO_ZERO_DATESQLモードが有効な場合は、これらの値を利用すると警告メッセージが表示される事を覚えておいて下さい。データタイプ 「ゼロ」 値 DATETIME'0000-00-00 00:00:00'DATE'0000-00-00'TIMESTAMP'0000-00-00 00:00:00'TIME'00:00:00'YEAR0000「ゼロ」 値は特別ですが、テーブルに表されている値を利用して格納したり、正確に参照したりする事ができます。
'0'や0の値を利用して行う事も可能です。こちらの方が書き込むよりも簡単です。MyODBCで利用される 「ゼロ」 の日付や時刻値はODBCでは扱う事ができないので、MyODBC 2.50.12以前のバージョンでは自動的に
NULLに変換されます。
DATETIME、DATE、そして
TIMESTAMP
タイプは関連しています。このセクションでは、それらがどのように似ているのか、そしてどのような点で異なっているのかなどの、特徴について説明しています。
DATETIME
タイプは、日付と時刻の両方の情報を含む値が必要な時に利用します。MySQLは、DATETIME
値を 'YYYY-MM-DD HH:MM:SS'
のフォーマットで検索、表示します。サポートされている範囲は
'1000-01-01 00:00:00' から
'9999-12-31 23:59:59' です。
DATE
タイプは時刻の部分は無く、日付の値だけが必要な時に利用します。MySQLは、DATE
値を 'YYYY-MM-DD'
のフォーマットで検索、表示します。サポートされている範囲は
'1000-01-01' から
'9999-12-31' です。
DATETIME と DATE
範囲の説明では、「サポートする」というのは、以前の値が有効であったとしても、その保障は無いという意味になります。
TIMESTAMP
データタイプは、MySQLのバージョンと、そのサーバーが稼動しているSQLモードによって様々な性質を持っています。これらの性質は、このセクションの後のほうで説明します。
DATETIME、DATE、そして
TIMESTAMP
値を、フォーマットの共通セットを利用して、指定する事ができます。
'YYYY-MM-DD HH:MM:SS'か'YY-MM-DD HH:MM:SS'フォーマットの文字列として。「柔軟な」 構文が許可されています。句読点文字が、日付部分と時刻部分の区切り文字として利用される事があります。例えば、'98-12-31 11:30:45'、'98.12.31 11+30+45'、'98/12/31 11*30*45'、そして'98@12@31 11^30^45'は同等です。'YYYY-MM-DD'か'YY-MM-DD'フォーマットの文字列として。「柔軟な」 構文がここでも許可されています。例えば、'98-12-31'、'98.12.31'、'98/12/31'、そして'98@12@31'は同等です。文字列が日付として成り立つという条件で、
'YYYYMMDDHHMMSS'か'YYMMDDHHMMSS'フォーマットの区切り文字が無い文字列として。例えば、'19970523091528'と'970523091528'は'1997-05-23 09:15:28'を表しますが、'971122129015'は不正データで、(これは意味を成さない分の部分がある為)'0000-00-00 00:00:00'となります。文字列が日付として成り立つという条件で、
'YYYYMMDD'か'YYMMDD'フォーマットの区切り文字が無い文字列として。例えば、'19970523'と'970523'は'1997-05-23'を表しますが、'971332'は不正データで、(これは意味を成さない月と日の部分がある為)'0000-00-00'となります。文字列が日付として成り立つという条件で、
YYYYMMDDHHMMSSかYYMMDDHHMMSSフォーマットの数字として。例えば、19830905132800と830905132800は'1983-09-05 13:28:00'という意味になります。文字列が日付として成り立つという条件で、
YYYYMMDDかYYMMDDフォーマットの数字として。例えば、19830905と830905は'1983-09-05という意味になります。NOW()やCURRENT_DATEのような、DATETIME、DATE、またはTIMESTAMPコンテキストで許容可能な値を戻す関数の結果。
不正な
DATETIME、DATE、または
TIMESTAMP 値は、適切なタイプ
('0000-00-00 00:00:00' か
'0000-00-00')の
「ゼロ」 値に変換されます。
日にち部分の区切り文字を含む文字列として指定された値には、月か日にちの値に
10
以下の2桁の値を指定する必要はありません。'1979-6-9'
は '1979-06-09'
と同じです。同じように、時刻部分の区切り文字を含む文字列として指定された値には、時、分、または秒の値に
10
以下の2桁の値を指定する必要はありません。'1979-10-30
1:2:3' は '1979-10-30
01:02:03' と同じです。
数字として指定された値は、6、8、12、または14桁の長さである必要があります。もし数字が8、または14桁の長さなら、それはYYYYMMDD
か YYYYMMDDHHMMSS
フォーマットであり、年は最初の4桁で表されていると仮定されます。もしその数字が6、または12桁であれば、YYMMDD
か YYMMDDHHMMSS
フォーマットであり、年は最初の2桁で表されていると仮定されます。これらの長さではない数字は後ろがゼロで詰められ、これらの中の一番近い桁数と仮定して判断されます。
区切り文字が無い文字列として指定された値はそれ自体の長さのまま判断されます。もしその文字列が8か14文字なら、年は最初の4文字で表されていると判断されます。そうでなければ、年は最初の2文字で表されていると判断されます。文字列は、左から右に順番に、年、月、日、時、分、そして秒として、その文字列に存在する限りの情報が読み取られます。これは、6文字以下の文字列は利用してはいけないという事を意味します。例えば、もし1999年3月を表そうとして
'9903'
と指定すると、MySQLは日付の値に
「ゼロ」 を挿入します。年と月の値は
99 と 03
ですが、日付の部分が全く無いのでこのような事が起こります。ですので、この値は不当な値という事になります。しかし、欠落している月や日付の部分をゼロの値を使って明確に指定する事ができます。例えば、'1999-03-00'
という値を挿入する為に、'990300'
を利用する事ができます。
1つの日付タイプの値を異なる日付タイプのオブジェクトに割り当てる事がある程度可能です。しかし、値の変更や情報の損失などが起こる可能性があります。
もし
DATE値をDATETIMEかTIMESTAMPオブジェクトに割り当てると、DATE値は時刻の情報を持たないので、その結果の時刻の部分は'00:00:00'に設定されます。もし
DATETIMEかTIMESTAMP値をDATEオブジェクトに割り当てると、DATE値は時刻の情報を格納しないので、その結果の時刻の部分は 削除されます。DATETIME、DATE、そしてTIMESTAMP値は、全て同じフォーマットの組み合わせを利用して指定する事ができますが、それらのタイプは全て同じ範囲の値を持つわけではない事を覚えておいてください。例えば、TIMESTAMP値は1970以前や、2037以降にはなり得ないという事です。これは、'1968-01-01'のような日付は、DATETIMEやDATE値としては有効ですが、TIMESTAMP値としては無効で、0に変換されるという意味になります。
日付値を指定する時には、特定の落とし穴に気をつけてください。
文字列として指定された値に許容される柔軟なフォーマットはまぎらわしい事があります。例えば、
'10:11:12'のような値は‘:’ が有る為に時刻値のように見えます。しかし、もし区切り文字が日付のコンテキストで利用されると、'2010-11-12'のように年として解釈されます。'10:45:15'値は、'45'が正しい月を表す値ではないので、'0000-00-00'に変換されます。サーバは、それぞれが1から12、または1から31である事はもちろん、月と日の値が正しい値であることを要求します。ストリクトモードが無効の時は、
'2004-04-31'のような無効な日付は'0000-00-00'に変換され、警告メッセージが表示されます。ストリクトモードが有効な時は、無効な日付はエラーを発生させます。そのような日付を許容するには、ALLOW_INVALID_DATESを有効にしてください。詳細については、「SQL モード」 をご参照ください。2桁の年を含む日付の値は、世紀が不明な為あいまいです。MySQLは2桁の年の値を次のルールに従って解釈します。
00-69の範囲の年の値は2000-2069に変換されます。70-99の範囲の年の値は1970-1999に変換されます。
注:MySQLの古いバージョン
(4.1以前)の TIMESTAMP
データの性質は、このセクションで紹介されている物とは様々な面で明らかに違いました。古い
TIMESTAMP データをMySQL
5.1
で利用する為に変換するには、その詳細について
MySQL 3.23, 4.0, 4.1
リファレンスマニュアル
を必ず参照してください。
TIMESTAMP カラムは
DATETIME
カラムと同じフォーマットで表示されます。言い換えると、表示幅は19文字に決められていて、フォーマットは
YYYY-MM-DD HH:MM:SS となります。
MySQLサーバは MAXDB
SQLモードが有効な時も実行する事ができます。このモードが有効な状態でサーバが実行された時、TIMESTAMP
は DATETIME
と同一です。これは、もしテーブルが作成された時にこのモードが有効だと、TIMESTAMP
カラムは DATETIME
カラムとして作成される、という意味になります。その結果、そのようなカラムは
DATETIME
表示フォーマットを利用し、同じ範囲の値を持ち、自動初期化機能や、現在の日付と時刻に自動的にアップデートする機能はないという事になります。
MAXDB
モードを有効にするには、起動の際に、--sql-mode=MAXDB
サーバオプションを利用するか、ランタイム時にグローバル
sql_mode
変数を設定して、サーバSQLのモードを
MAXDB に設定してください。
mysql> SET GLOBAL sql_mode=MAXDB;
クライアントは接続の為に、次のようにサーバを
MAXDB
モードで起動させる事ができます。
mysql> SET SESSION sql_mode=MAXDB;
次に紹介されている情報は、MAXDB
モードが有効な状態で作成されなかったテーブルだけの
TIMESTAMP
カラムに適合するという事を覚えておいて下さい。なぜならば、そのようなカラムは
DATETIME
カラムとして作成されるからです。
MySQLは、日付か月のカラムにゼロを含むタイムスタンプ値や、有効でない日付値は許容しません。このルールの唯一の例外は、'0000-00-00
00:00:00' の特別値です。
いつ TIMESTAMP
の自動初期化とアップデートが起こるのか、そしてどのカラムがそれらを行うべきなのかを決めるのに、相当な柔軟性があります。
テーブル内の1つの
TIMESTAMPカラムに対して、現在のタイムスタンプをデフォルト値と自動更新値として指定する事ができます。現在のタイムスタンプを、カラムを初期化するデフォルト値にする事、または自動更新のデフォルト値にする事、またはその両方にする事が可能です。現在のタイムスタンプを、1つのカラムを初期化するデフォルト値にし、別のカラムの自動更新のデフォルト値にする事は不可能です。どの
TIMESTAMPカラムが現在の日付と時刻を自動的に初期化したり更新したりするのか指定する事ができます。これは、最初のTIMESTAMPカラムである必要はありません。
次のルールが TIMESTAMP
カラムの初期化と更新を管理しています。
もし
DEFAULT値がテーブルの最初のTIMESTAMPカラムに指定されたら、それは無視されません。CURRENT_TIMESTAMP、または一定の日付と時刻値がデフォルトになり得ます。最初の
TIMESTAMPカラムにとって、DEFAULT NULLはDEFAULT CURRENT_TIMESTAMPと同じです。それ以外の全てのTIMESTAMPカラムにとっては、DEFAULT NULLはDEFAULT 0として扱われます。テーブル内の全ての1つの
TIMESTAMPカラムは、現在のタイムスタンプに初期化された物か、自動的に更新された物として利用されます。CREATE TABLEステートメントの中では、最初のTIMESTAMPカラムは次の方法のどれかで宣言する事ができます。DEFAULT CURRENT_TIMESTAMPとON UPDATE CURRENT_TIMESTAMP条項の両方で、カラムはそのデフォルトに現在のタイムスタンプを持ち、それは自動的に更新されます。DEFAULTとON UPDATE条項のどちらも、DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPとは同じではありません。DEFAULT CURRENT_TIMESTAMP条項と、ON UPDATEではない 条項で、カラムはそのデフォルトに現在のタイムスタンプを持ちますが、それは自動的に更新されません。DEFAULT条項が無い、ON UPDATE CURRENT_TIMESTAMPがある条項では、カラムのデフォルトは0で、それは自動的に更新されます。一定の
DEFAULT値の時は、カラムは一定のデフォルトを持ちます。もしカラムがON UPDATE CURRENT_TIMESTAMP条項を持っていればそれは自動的に更新されますが、そうでない時は更新されません。
言い換えると、現在のタイムスタンプを初期値と自動更新値の両方、またはそのどちらかに利用する事ができる、または、両方とも利用しない事も可能です。(例えば、自動初期化されたカラムを持たずに自動更新を可能にする為に
ON UPDATEを指定する事が可能です。)CURRENT_TIMESTAMPまたはその同義語(CURRENT_TIMESTAMP()、NOW()、LOCALTIME、LOCALTIME()、LOCALTIMESTAMP、またはLOCALTIMESTAMP())はDEFAULTとON UPDATE条項の中で利用する事ができます。それらは全て 「現在のタイムスタンプ」 を意味します。(UTC_TIMESTAMPは許容されていません。現在のタイムゾーンがUTCでない限り、その値の範囲はTIMESTAMPカラムの値の範囲と並びません。)DEFAULTとON UPDATE属性の順番は関係ありません。もしDEFAULTとON UPDATEの両方がTIMESTAMPカラムに指定されると、どちらかがもう片方に先行します。例えば、これらのステートメントは同等になります。CREATE TABLE t (ts TIMESTAMP); CREATE TABLE t (ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); CREATE TABLE t (ts TIMESTAMP ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP);TIMESTAMPカラムに最初の物以外の自動デフォルトや更新を指定するには、一定のDEFAULT値(例えば、DEFAULT 0やDEFAULT '2003-01-01 00:00:00')を明確に指定する事によって、最初のTIMESTAMPカラムの自動初期化や更新動作を抑圧する必要があります。そして、それ以外のTIMESTAMPカラムに対しては、DEFAULTとON UPDATE条項の両方を削除しなければルールは最初のTIMESTAMPカラムと同じで、自動初期化や更新は行われません。例:これらのステートメントは同等です。
CREATE TABLE t ( ts1 TIMESTAMP DEFAULT 0, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); CREATE TABLE t ( ts1 TIMESTAMP DEFAULT 0, ts2 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
「MySQL サーバのタイム ゾーン サポート」
で説明されているように、現在のタイムゾーンをそれぞれの接続ごとに設定する事ができます。TIMESTAMP
値は、現在のタイムゾーンから変換されて格納され、また検索された時に現在のタイムゾーンに再変換されながら、UTCに格納されます。タイムゾーン設定が一定である限り、格納した値と同じ値を復帰させる事ができます。もし
TIMESTAMP
値を格納してから、タイムゾーンを変更して値を検索すると、検索された値は格納した値とは違ってきます。これは、同じタイムゾーンが両方向への変換に利用されなかった為に起こります。現在のタイムゾーンは、time_zone
システム変数の値のように有効です。
カラムが NULL
値を含む事を許容する為に
TIMESTAMP カラムの定義の中に
NULL
属性を含める事ができます。例:
CREATE TABLE t ( ts1 TIMESTAMP NULL DEFAULT NULL, ts2 TIMESTAMP NULL DEFAULT 0, ts3 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP );
もし NULL
属性が指定されていなければ、カラムを
NULL
に設定すると、現在のタイムスタンプに設定されます。NULL
値を許容する TIMESTAMP
カラムは、下記の条件の時以外は現在のタイムスタンプを採用
しない
という事を覚えておいて下さい。
そのデフォルト値は
CURRENT_TIMESTAMPとして定義されます。NOW()かCURRENT_TIMESTAMPがカラムに挿入されます。
言い換えると、NULL
として定義された TIMESTAMP
カラムは次のような定義を利用して作成された時だけ自動初期化します。
CREATE TABLE t (ts TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP);
そうでなければ—
ここに表されているように、もし
TIMESTAMP カラムが DEFAULT
TIMESTAMP を利用せずに NULL
値を許容するために定義されると …
CREATE TABLE t1 (ts TIMESTAMP NULL DEFAULT NULL); CREATE TABLE t2 (ts TIMESTAMP NULL DEFAULT '0000-00-00 00:00:00');
… 現在の日付と時刻に対応した値を明確に挿入しなければいけません。例:
INSERT INTO t1 VALUES (NOW()); INSERT INTO t2 VALUES (CURRENT_TIMESTAMP);
MySQLは TIME 値を
'HH:MM:SS'
フォーマットで検索、表示します。(または長時間値を表すには
'HHH:MM:SS'
フォーマット)TIME 値の範囲は
'-838:59:59' から
'838:59:59'
です。TIME
タイプは、一日のうちの時刻を表す事ができるだけでなく(24時間以下)、経過時間や、二つの出来事の間の時間を表す事もできるので(24時間よりも長い、またはマイナスの事も有る)、時間を表す部分がとても長くなる事があります。
TIME
値は様々なフォーマットで指定する事ができます。
'D HH:MM:SS.fraction'フォーマットの文字列として次のうちの 「柔軟な」 構文の1つを利用する事もできます。'HH:MM:SS.fraction'、'HH:MM:SS'、'HH:MM'、'D HH:MM:SS'、'D HH:MM'、'D HH'、または'SS'。ここでは、Dは日を表し、0から34の値を持つ事ができます。MySQLは端数部分を格納しない事を覚えておいて下さい。時刻を表す、
'HHMMSS'フォーマットで区切り文字を利用しない文字列として例えば、'101112'は'10:11:12'として理解されますが、'109712'は不正データとなり(意味を成さない分の部分を持つ為)、'00:00:00'となります。時刻を表す、
'HHMMSS'フォーマットの数字として例えば、101112は'10:11:12'として理解されます。以下のフォーマットもまた理解されます。SS、MMSS、HHMMSS、HHMMSS.fractionMySQLは端数部分を格納しない事を覚えておいて下さい。CURRENT_TIMEのようにTIMEコンテキストの中で許容される値を返す関数の結果として
時刻部分の区切り文字を含む文字列として指定された
TIME
値には、時、分、または秒の値に
10
以下の2桁の値を指定する必要はありません。'8:3:2'
は '08:03:02' と同じです。
TIME
カラムに省略された値を指定する際には注意してください。MySQLは、コロンが付いていない値は、その値の一番右の二桁が秒を表していると解釈します。(MySQLは
TIME
値を、一日の内の時刻ではなく、経過時間として解釈します。)例えば、'1112'
と 1112
は、'11:12:00'
(11時12分過ぎ)を意味するように感じますが、MySQLはそれを
'00:11:12'
(11分12秒)と解釈します。同じように、'12'
と 12
は'00:00:12'
という意味になります。コロンが付いた
TIME
値は反対に、必ず一日の内の時刻として扱われます。それは、'11:12'
が '11:12:00'
を表し、'00:11:12'
では無いという事になります。
デフォルトでは、TIME
範囲外であるが正当である値は、その値の終点にクリップされます。例えば、'-850:00:00'
と '850:00:00' は
'-838:59:59' と
'838:59:59'
に変換されます。不正な TIME 値は
'00:00:00'
に変換されます。'00:00:00'
自体は正当な TIME
値なので、テーブルに格納された
'00:00:00'
の値から、元の値が
'00:00:00'
値で指定されたのか、不当な値だったのかを知る方法は無いという事を覚えておいて下さい。
不正な TIME
値をもう少し厳しく扱うためには、エラーが発生するようにストリクトSQLモードを有効にしてください。「SQL モード」を参照してください。
YEAR
タイプは年を表すために利用される1バイトのタイプです。
MySQLは YEAR 値を YYYY
フォーマットで検索、表示します。範囲は
1901 から 2155 です。
TIME
値は様々なフォーマットで指定する事ができます。
'1901'から'2155'の範囲の4桁の文字列として1901から2155の範囲の4桁の数字として'00'から'99'の範囲の2桁の文字列として'00'から'69'と、'70'から'99'の範囲の値は、2000から2069と、1970から1999の範囲のYEAR値に変換されます。1から99の範囲の2桁の数字として1から69と、70から99の範囲の値は、2001から2069と、1970から1999の範囲のYEAR値に変換されます。ゼロを数字として直接指定して、2000と解釈させる事ができないので、2桁の数字の範囲は2桁の文字列の範囲と少しだけ違う事を覚えておいて下さい。'0'か'00'の文字列として指定すると、0000として解釈されます。NOW()のようにYEARコンテキストの中で許容される値を返す関数の結果として
不正な YEAR 値は 0000
に変換されます。
MySQLサーバ自体は2000年(Y2K)コンプライアンスに対して何も問題はありません。
MySQLサーバは、
TIMESTAMP値に対して、日付を2037年まで扱う Unix時間関数を利用しています。DATEとDATETIME値には、9999年までの日付が許容されています。全てのMySQLの日付機能は一つのソースファイル、
sql/time.ccで実行されており、2000年問題に対して安全にプログラムされています。MySQLでは、
YEARデータタイプは0年と1901年から2155年を1バイトで格納する事ができ、2桁か4桁でそれらを表示します。全ての2桁の年は1970年から2069年の範囲だと判断されます。ですので、YEARカラムに01を格納すると、MySQLサーバはそれを2001年として扱います。
MySQLサーバ自体がY2Kに対して安全だとしても、そうでないアプリケーションと共に利用すると問題が起きる可能性があります。例えば、多くの古いアプリケーションは、4桁の値よりも、曖昧である2桁の値を利用して年を格納したりコントロールしたりします。この問題は、「欠けている」値を表す為に
00 や 99
などの値を利用するアプリケーションによって作られる可能性があります。残念ながら、異なるアプリケーションは異なるプログラマによって書かれており、それぞれが、異なる仕様や日付管理の関数を利用しているので、これらの問題を修正するのは難しいです。
それ故、MySQLサーバにY2Kの問題が無いとしても、曖昧でない値を入力する事は、アプリケーションの義務です。.2桁の年を含む日付の値は、世紀が不明な為曖昧です。MySQLは内部的に4桁を利用して年を格納するので、そのような値は4桁の形に修正されなければいけません。
DATETIME、DATE、TIMESTAMP、そして
YEAR
タイプに対して、MySQLは次のルールを利用して曖昧な年の値の日付を修正します。
00-69の範囲の年の値は2000-2069に変換されます。70-99の範囲の年の値は1970-1999に変換されます。
これらのルールは、データ値が何を表すかを妥当に推測する単なる経験則である事を覚えておいて下さい。もしMySQLが利用するルールが正しい値を導かなければ、4桁の年の値を含む、曖昧ではない入力が必要になります。
ORDER BY は、2桁の年を持つ
YEAR 値を正しく分類します。
MIN() や MAX()
等のようないくつかの関数は、YEAR
を数字に変換します。これは、これらの関数を利用すると、2桁の年の値は正確に機能しないという意味になります。この場合の修正は、TIMESTAMP
や YEAR
を4桁の年のフォーマットに変換するという事になります。
文字列タイプの種類は、CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM、そしてSET
です。このセクションでは、これらのタイプがどのように機能するのか、クエリの中でどのように利用するのかを説明します。文字列タイプが必要とする記憶容量に関しては、「データタイプが必要とする記憶容量」
を参照してください。
CHAR と VARCHAR
タイプは似ていますが、格納、検索される方法が異なります。また、最大長さと、末尾のスペースが保持されるかどうかという点でも異なります。格納と検索の最中にレターケースの変換は行われません。
CHAR と VARCHAR
タイプには、格納したい最大文字数を表す長さが宣言されています。例えば、CHAR(30)
は最大30文字まで持つ事ができます。
CHAR
カラムの長さは、テーブルを作成した時に宣言した長さに修正されます。長さは0から255までのどの長さにもなり得ます。CHAR
値が格納された時、指定された長さになるよう、右側が詰められます。CHAR
値が検索された時、後続スペースは削除されます。
VARCHAR
カラム内の値は可変長の文字列です。長さは0から65,535の値で指定できます。(VARCHAR
の最大有効長さは、最大行サイズと利用される文字サイズによって決まります。最大カラム長さは65,532バイトの行サイズによります。)
CHAR
とは対照的に、VARCHAR
値は必要な文字数と、長さを記録する為の1バイト(255よりも長いカラムは2バイト)だけを利用して格納できます。
VARCHAR
値は格納される時に詰められません。スタンダードSQLに適合して、値が格納、検索される時に後続スペースは保持されます。
CHAR や VARCHAR
カラムに、その最大長を超える値を指定すると、その値は切り捨てられます。切り捨てられた文字がスペースで無い場合には警告メッセージが表示されます。スペース以外の文字の切捨てに関しては、ストリクトSQLモードを利用する事で警告ではなくエラーを表示させ、その値の挿入を食い止める事ができます。「SQL モード」を参照してください。
次のテーブルは、CHAR(4) と
VARCHAR(4)
カラムに様々な文字列値を格納した結果を表示する事で、CHAR
と VARCHAR の違いを表しています。
| 値 | CHAR(4) | 要求ストレージ | VARCHAR(4) | 要求ストレージ |
'' | ' ' | 4バイト | '' | 1バイト |
'ab' | 'ab ' | 4 バイト | 'ab' | 3バイト |
'abcd' | 'abcd' | 4 バイト | 'abcd' | 5バイト |
'abcdefgh' | 'abcd' | 4バイト | 'abcd' | 5バイト |
テーブルの最終行に格納されたと表示されている値は、ストリクトモードを利用していない時だけ 適応される事を覚えておいて下さい。もしMySQLがストリクトモードで起動していると、カラム長を超える値は 格納されず エラーになります。
もし規定の値が CHAR(4) と
VARCHAR(4)
カラムに格納されると、CHAR
カラムが検索される時に後続スペースが削除されるので、カラムから検索された値は必ずしも同じとは限りません。次の例はこれらの点を例示しています。
mysql>CREATE TABLE vc (v VARCHAR(4), c CHAR(4));Query OK, 0 rows affected (0.01 sec) mysql>INSERT INTO vc VALUES ('ab ', 'ab ');Query OK, 1 row affected (0.00 sec) mysql>SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc;+---------------------+---------------------+ | CONCAT('(', v, ')') | CONCAT('(', c, ')') | +---------------------+---------------------+ | (ab ) | (ab) | +---------------------+---------------------+ 1 row in set (0.06 sec)
CHAR と VARCHAR
カラムの中の値は、そのカラムに指定された
文字セットの照合に従って格納、比較されます。
全てのMySQL照合は PADSPACE
タイプの物だと覚えておいてください。これは、MySQLの中の全ての
CHAR と VARCHAR
値が後続スペースを無視して比較されるという事を意味します。例:
mysql>CREATE TABLE names (myname CHAR(10), yourname VARCHAR(10));Query OK, 0 rows affected (0.09 sec) mysql>INSERT INTO names VALUES ('Monty ', 'Monty ');Query OK, 1 row affected (0.00 sec) mysql>SELECT myname = 'Monty ', yourname = 'Monty ' FROM names;+--------------------+----------------------+ | myname = 'Monty ' | yourname = 'Monty ' | +--------------------+----------------------+ | 1 | 1 | +--------------------+----------------------+ 1 row in set (0.00 sec)
これは全てのMySQLバージョンに当てはまり、サーバのSQLモードに影響されないという事を覚えておいて下さい。
後続文字が剥ぎ取られたり、比較がそれらを無視する場合は、もしカラムが固有の値を要求するインデックスを持っていたら、後続文字数だけが異なるカラム値への挿入は重複キーエラーになります。例えば、もしテーブルが
'a'
を含んでいると、'a '
を格納しようとした時重複キーエラーになります。
BINARY と VARBINARY
タイプは、非バイナリ文字列ではなく、バイナリ文字列を含んでいるところ以外で
CHAR と VARCHAR
に似ています。それは、それらが文字の文字列ではなく、バイトの文字列を含んでいるという事です。これは、それらが文字セットを持たず、ソートと比較は値の中の数値バイトに基づいているという意味です。
許容される最大長は、CHAR と
VARCHAR
と同様で、BINARY と
VARBINARY
の長さは文字ではなく長さのバイトであるという事以外、BINARY
と VARBINARY と同じです。
BINARY と VARBINARY
データタイプは CHAR BINARY と
VARCHAR BINARY
データタイプとは異なります。後者のタイプは、BINARY
属性によってカラムがバイナリ文字列カラムとして扱われる事はありません。代わりに、利用されるカラム文字セットのバイナリ照合を実行し、そしてそのカラム自体がバイナリバイト文字列ではなく非バイナリ文字の文字列を含みます。例えば、CHAR(5)
BINARY は、デフォルト文字セットが
latin1 だと仮定して、CHAR(5)
CHARACTER SET latin1 COLLATE latin1_bin
として扱われます。これは、文字セットや照合を持たない5バイトのバイナリ文字列
BINARY(5) とは異なります。
BINARY
値が格納される時、特定の長さまでパッド値で右側が詰められます。パッド値は
0x00
です。(ゼロバイト)値は挿入時には右側が
0x00
で詰められ、選択時に後続バイトは削除されません。全てのバイトは、ORDER
BY と DISTINCT
操作を含め、比較において重要です。0x00
バイトとスペースは、0x00 <
スペースとなり、比較において異なります。
例:BINARY(3) カラムでは、挿入時
'a ' は
'a \0'
になります。'a\0'
は挿入時 'a\0\0'
になります。選択時、両方の値は変更されません。
VARBINARY
では、挿入時に詰められる事も、選択時にバイトが削除される事もありません。全てのバイトは、ORDER
BY と DISTINCT
操作を含め、比較において重要です。0x00
バイトとスペースは、0x00 <
スペースとなり、比較において異なります。
後続パッドバイトが剥ぎ取られたり、比較がそれらを無視する場合は、もしカラムが固有の値を要求するインデックスを持っていたら、後続パッドバイトだけが異なるカラム値への挿入は重複キーエラーになります。例えば、もしテーブルが
'a'
を含んでいると、'a\0'
を格納しようとした時重複キーエラーになります。
もしバイナリデータの格納に
BINARY
データタイプを利用する予定で、検索した値を格納した値と同一にしたいなら、先行パッドと削除文字を注意深く検討する必要があります。次の例は、BINARY
値の 0x00
パッドがどのようにカラム値比較に影響するか、例を示しています。
mysql>CREATE TABLE t (c BINARY(3));Query OK, 0 rows affected (0.01 sec) mysql>INSERT INTO t SET c = 'a';Query OK, 1 row affected (0.01 sec) mysql>SELECT HEX(c), c = 'a', c = 'a\0\0' from t;+--------+---------+-------------+ | HEX(c) | c = 'a' | c = 'a\0\0' | +--------+---------+-------------+ | 610000 | 0 | 1 | +--------+---------+-------------+ 1 row in set (0.09 sec)
もし検索した値がパッドなしの指定したストレージと同じ値でなければいけないなら、VARBINARY
か、BLOB
データタイプの1つを代わりに利用するのが好ましいです。
BLOB
は様々な大きさのデータを保持する事ができる大きいバイナリオブジェクトです。4つの
BLOB
タイプは、TINYBLOB、
BLOB、MEDIUMBLOB、そしてLONGBLOB
です。これらは、保持する事ができる最大長さだけが異なっています。4つの
TEXT
タイプは、TINYTEXT、TEXT、MEDIUMTEXT、そして
LONGTEXT です。これらは4つの
BLOB タイプに対応し、最大長さと必要とする記憶容量は同じです。「データタイプが必要とする記憶容量」を参照してください。TEXT
や BLOB
カラムのレターケースの変換は格納や検索時には行われません。
BLOB
カラムはバイナリ文字列(バイト文字列)として扱われます。TEXT
カラムは非バイナリ文字列(文字の文字列)として扱われます。BLOB
カラムは文字セットを持たないので、ソートと比較は値の中の数値バイトに基づいています。TEXT
カラムは文字セットを持つので、値は文字セットの照合に基づいてソート、比較されます。
もし TEXT
カラムがインデックスされていたら、インデックス入力比較は最後にスペースが詰められます。これは、もしそのインデックスが固有の値を要求するなら、後続スペースだけが異なる値に対して重複キーエラーが発生するという事を意味します。例えば、もしテーブルが
'a'
を含んでいると、'a '
を格納しようとした時重複キーエラーになります。これは
BLOB
カラムには当てはまりません。
ストリクトモードで実行していない時に、BLOB
や TEXT
カラムに、そのデータタイプの最大長を超える値を指定すると、その値は切り捨てられます。切り捨てられた文字がスペースで無い場合には警告メッセージが表示されます。ストリクトモードを利用すると、警告と共に値が切り捨てられるのではなく、エラーを発生させて、その値を拒否させる事ができます。「SQL モード」を参照してください。
あらゆる点で、BLOB
カラムを、好きな長さに設定できる
VARBINARY
カラムだと考える事ができます。同じように、TEXT
カラムを VARCHAR
カラムと考える事ができます。BLOB
と TEXT は、次の点で
VARBINARY と VARCHAR
とは異なっています。
BLOBとTEXTカラムのインデックスには、インデックスプリフィックス長を指定しなければいけません。CHARとVARCHARでは、プリフィックス長は任意です。「カラムインデックス」を参照してください。
LONG と LONG VARCHAR は
MEDIUMTEXT
データタイプにマップします。これは互換性の特徴です。もし
BINARY 属性を TEXT
データタイプと一緒に利用するなら、そのカラムはカラム文字セットのバイナリ照合に指定されます。
MySQLコネクタ/ODBCは BLOB 値を
LONGVARBINARY
として、TEXT
値をLONGVARCHAR として定義します。
BLOB と TEXT
値は大変長くなり得るので、それらを利用する時にいくつかの制約が発生します。
カラムの
max_sort_lengthバイトだけがソートに利用されます。max_sort_lengthのデフォルト値は1024です。この値は、mysqldサーバーを開始する時に--max_sort_length=オプションを利用して変更する事ができます。「システム変数」を参照してください。Nmax_sort_lengthの値をランタイムに増やす事で、ソートとグループの際により多くのバイトを有効にする事ができます。全てのクライアントがそのセッションmax_sort_length変数の値を変更する事ができます。mysql>
SET max_sort_length = 2000;mysql>SELECT id, comment FROM t->ORDER BY comment;GROUP BYやORDER BYを、max_sort_lengthバイトよりも多くのバイトを有効にしたい時の長い値を含むBLOBやTEXTカラム上で利用する別の方法は、カラム値を固定長オブジェクト変換するという方法です。これを行う標準的な方法はSUBSTRING()関数を利用する方法です。例えば、次のステートメントによってcommentカラムの2000バイトがソートの際に考慮されるようになります。mysql>
SELECT id, SUBSTRING(comment,1,2000) FROM t->ORDER BY SUBSTRING(comment,1,2000);BLOBやTEXTオブジェクトの最大サイズはそのタイプによって判断されますが、クライアントとサーバーの間で実際に送信できる最大値は、有効メモリの量とコミュニケーションバッファのサイズによって判断されます。max_allowed_packet変数の値を変更する事でメッセージバッファサイズを変更する事ができますが、サーバとクライアントプログラムの両方に対してその作業を行う必要があります。例えば、mysql と mysqldump の両方がクライアント側のmax_allowed_packet値を変更する事を許可します。「サーバパラメータのチューニング」、「mysql — MySQL コマンド ライン ツール」、「mysqldump — データベースバックアッププログラム」を参照して下さい。ソート中のパケットサイズとデータオブジェクトのサイズを必要とする記憶容量に基づいて比較したい場合には、 「データタイプが必要とする記憶容量」 を参照してください。
BLOB や TEXT
値はそれぞれ内部的に別々に割り当てられたオブジェクトによって表現されます。これは、テーブルが開かれた時にそれぞれのカラムに容量が一度割り当てられるという形の、その他全てのデータタイプとは異なります。
時には、メディアファイルのようなバイナリデータを
BLOB や TEXT
カラムに格納する事が望ましい場合もあるでしょう。MySQLの文字列操作関数がこのようなデータを利用するのに役に立つでしょう。「文字列関数」を参照してください。安全とその他の理由の為、これを行うには、アプリケーションユーザに
FILE
特権の利用を許可するのではなく、アプリケーションコードを利用して行う方が望ましいです。詳細については、MySQLフォーラムで、様々な言語やプラットフォームで議論する事ができます。(http://forums.mysql.com/)
ENUM
は、テーブルを作成する際カラム仕様の中で明確に列挙された許容値リストから選択された値を持つ文字列オブジェクトです。
列挙値は引用された文字列直定数である必要があります。これは、式でも、文字列値を評価するものでもありません。これは、ユーザ変数を列挙値として採用するべきではないという事も意味します。
その値は、特定の条件下では('')や
NULL
の空の文字列になる事もあります。
もし
ENUMに無効な値(許容値リストに存在しない文字列)を挿入すると、特別エラー値として空の文字列が代わりに挿入されます。この文字列は、ゼロの数値を持つという点で、「通常の」 空の文字列とは区別することができます。 この後でもう少し詳しく説明します。もしストリクトSQLモードが有効なら、無効な
ENUM値を挿入しようとするとエラーが発生します。もし
ENUMカラムがNULLの許容を宣言すると、NULL値はそのカラムにとって正当な値となり、デフォルト値はNULLになります。もしENUMカラムがNOT NULLを宣言すると、許容値リストの最初の要素がそのデフォルト値となります。
それぞれの列挙値はインデックスを持ちます。
カラム仕様の中の許容可能エレメントリストからの値は1から始まる番号がつけられています。
空の文字列エラーインデックス値は0です。これは、どの無効な
ENUM値に行が指定されたのかを見つける為に、次のSELECTステートメントを利用する事ができるという事を意味します。mysql>
SELECT * FROMtbl_nameWHEREenum_col=0;NULL値のインデックスはNULLです。「インデックス」 という言葉は、列挙値リストの中の位置だけを表しています。これは、テーブルインデックスとは全く関係がありません。
例えば、ENUM('one', 'two',
'three')
として指定されたカラムはここに表されている値のどれでも持つ事ができます。それぞれの値のインデックスも表示されています。
| 値 | インデックス |
NULL | NULL |
'' | 0 |
'one' | 1 |
'two' | 2 |
'three' | 3 |
1つの列挙は最大65,535エレメントを持つ事ができます。
テーブルが作成された時に、テーブル定義の中の
ENUM
メンバー値から後続スペースが自動的に削除されます。
検索された時は、ENUM
カラムに格納された値はカラム定義で使用されたレターケースで表示されます。ENUM
カラムは文字セットと照合に指定できる事を覚えて置いてください。バイナリ、またはケースに敏感な照合には、カラムに値を指定する時レターケースが考慮されます。
もし ENUM
値を数値コンテキストで検索するなら、カラム値のインデックスは返されます。例えば、このようにして
ENUM
カラムから数値を検索する事ができます。
mysql> SELECT enum_col+0 FROM tbl_name;
もし ENUM
カラムに数字を格納すると、その数字は可能値のインデックスとして扱われ、格納された値はそのインデックスを持つ列挙番号となります。(しかしこれは全ての入力を文字列として扱う
LOAD DATA とは機能
しません。)もし数値が引用されると、列挙値リストの中に適合する文字列がなければ、そのままインデックスとして解釈されます。これらの理由により、ENUM
カラムを数字のように見える列挙値で定義する事は、複雑になり得るので
お勧めできません。例えば、次のカラムは
'0'、'1'、そして
'2'
の文字列値のある列挙番号を持ちますが、1、2、そして
3
の数値インデックス値は次のようになります。
numbers ENUM('0','1','2')
もし 2
を格納すると、それはインデックス値として解釈され、'1'
となります。 (インデックス2の値)もし
'2'
を格納すると、それは列挙値と適合するので
'2'
として格納されます。もし
'3'
を格納すると、どの列挙値とも適合しないのでインデックスとして扱われ、'2'
となります。 (インデックス3の値)
mysql>INSERT INTO t (numbers) VALUES(2),('2'),('3');mysql>SELECT * FROM t;+---------+ | numbers | +---------+ | 1 | | 2 | | 2 | +---------+
ENUM
値は、カラム仕様にリストされた列挙番号の順番に従ってソートされます。(言い換えると、ENUM
値はそれらのインデックス番号によってソートされるという事になります。)例えば、'a'
は ENUM('a', 'b') では
'b'
の前にソートしますが、'b'
は ENUM('b', 'a') では
'a'
の前にソートします。空の文字列は、空ではない文字列の前にソートし、そして
NULL
値はその他の全ての列挙値の前にソートします。予期しない結果を防ぐ為には、ENUM
リストをアルファベット順に指定してください。カラムがインデックス番号ではなく、語彙的にソートされる為に、GROUP
BY CAST(col AS CHAR) か GROUP BY
CONCAT(col) を利用する事もできます。
ENUM
カラムに有効な全ての値を究明したければ、SHOW
COLUMNS FROM
を利用し、アウトプットの tbl_name LIKE
enum_colType
カラムの中の ENUM
定義を解析してください。
SET
はゼロ、またはそれ以上の値を持つことができる文字列オブジェクトであり、それらはそれぞれ、テーブルが作成された時に指定された許容値リストから選択する必要があります。複数セットメンバーによって成り立つ
SET
カラム値は、カンマで区切られたメンバーによって指定されます。(‘,’)この結果は、SET
メンバー値自体はコンマを含むべきではないという事です。
例えば、SET('one', 'two') NOT
NULL
として指定されたカラムはここに表されている値のどれでも持つ事ができます。
'' 'one' 'two' 'one,two'
SET
は最高64の異なるメンバを持つ事ができます。
テーブルが作成された時に、テーブル定義の中の
SET
メンバー値から後続スペースが自動的に削除されます。
検索された時は、SET
カラムに格納された値はカラム定義で使用されたレターケースで表示されます。SET
カラムは文字セットと照合に指定できる事を覚えて置いてください。バイナリ、またはケースに敏感な照合には、カラムに値を指定する時レターケースが考慮されます。
MySQLは、最初のセットメンバに対応する格納値の低位ビットを利用して
SET
値を数値で格納します。SET
値を数値コンテキストで検索すると、その値は、カラム値を構成するセットメンバーに対応するビットセットを持ちます。例えば、このようにして
SET
カラムから数値を検索する事ができます。
mysql> SELECT set_col+0 FROM tbl_name;
もしメンバがSET
カラムに格納されると、その数字のバイナリ表現に設定されているビットがカラム値のセットメンバを決定します。SET('a','b','c','d')
として指定されたカラムには、メンバは次の少数とバイナリ値を持ちます。
SET メンバ | 少数値 | バイナリ値 |
'a' | 1 | 0001 |
'b' | 2 | 0010 |
'c' | 4 | 0100 |
'd' | 8 | 1000 |
もしこのカラムに、バイナリでは
1001 となる 9
を指定すると、最初と4番目の SET
値メンバである 'a' と
'd' が選択され、結果値は
'a,d' となります。
1つ以上の SET
エレメントを含む値には、値を挿入する時のエレメントがどの順番でリストされるかは関係ありません。また、決められたエレメントがその値の中で何回リストされるかという事も関係ありません。値が後で検索される時には、テーブル作成時に指定された順番に従ってリストされたエレメントと一緒に、値の中のそれぞれのエレメントが一度表示されます。例えば、カラムが
SET('a','b','c','d')
として指定されたと仮定します。
mysql> CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
もし
'a,d'、'd,a'、'a,d,d'、'a,d,a'、そして
'd,a,d'
という値を挿入すると、次のようになります。
mysql> INSERT INTO myset (col) VALUES
-> ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
すると、これらの値が検索された時、'a,d'
と表示されます。
mysql> SELECT col FROM myset;
+------+
| col |
+------+
| a,d |
| a,d |
| a,d |
| a,d |
| a,d |
+------+
5 rows in set (0.04 sec)
もしサポートされていない値に
SET
カラムを設定すると、その値は無視され警告が表示されます。
mysql>INSERT INTO myset (col) VALUES ('a,d,d,s');Query OK, 1 row affected, 1 warning (0.03 sec) mysql>SHOW WARNINGS;+---------+------+------------------------------------------+ | Level | Code | Message | +---------+------+------------------------------------------+ | Warning | 1265 | Data truncated for column 'col' at row 1 | +---------+------+------------------------------------------+ 1 row in set (0.04 sec) mysql>SELECT col FROM myset;+------+ | col | +------+ | a,d | | a,d | | a,d | | a,d | | a,d | | a,d | +------+ 6 rows in set (0.01 sec)
もしストリクトSQLモードが有効なら、無効な
SET
値を挿入しようとするとエラーが発生します。
SET
値は数値でソートされます。NULL
値は非 NULL SET
値の前にソートします。
通常は、FIND_IN_SET() 関数か
LIKE オペレーターを利用して
SET 値を検索します。
mysql>SELECT * FROMmysql>tbl_nameWHERE FIND_IN_SET('value',set_col)>0;SELECT * FROMtbl_nameWHEREset_colLIKE '%value%';
最初のステートメントは
set_col が
value
セットメンバを含む行を見つけます。二つ目のステートメントも似ていますが、全く同じではありません。2つ目のステートメントは、他のセットメンバの部分列としても、set_col
が value
をどこかに含む行を見つけます。
次のステートメントもまた正当です。
mysql>SELECT * FROMmysql>tbl_nameWHEREset_col& 1;SELECT * FROMtbl_nameWHEREset_col= 'val1,val2';
これらのステートメントの最初の部分が最初のセットメンバを含む値を探します。二つ目の部分が正確に適合する値を探します。二つ目のタイプの比較に注意してください。'
のセット値を比較すると、val1、val2''
を比較するよりも異なる結果が返されます。カラム定義の中でリストされているのと同じ順番で値を指定する必要があります。
val2、val1'
SET
カラムに有効な全ての値を究明したければ、SHOW
COLUMNS FROM
を利用し、アウトプットの tbl_name LIKE
set_colType
カラムの中の SET
定義を解析してください。
MySQLにサポートされているデータタイプが必要とする記憶容量がカテゴリごとにリストされています。
MyISAM
テーブル内の行の最大サイズは65,534バイトです。BLOB
と TEXT
カラムはそれぞれ、このサイズに対してたった5から9バイトを占めています。
重要NDBCluster
ストレージエンジンを利用しているテーブルには、必要とする記憶容量を計算する際考慮するべき
4-byteアラインメント
の要因があります。これは、全ての
NDB
データ格納が4バイトの倍数単位で行われるという意味になります。それ故、—テーブルの中で
NDB
以外のストレージエンジンを利用している
—カラム値は、格納に15バイトを利用し、NDB
テーブルの中で16バイトを必要とします。この要求は、このセクションで紹介される他の全ての条件に当てはまります。例えば、NDBCluster
テーブルの中で、
TINYINT、SMALLINT、MEDIUMINT、そして
INTEGER
(INT)カラムタイプはそれぞれ1つのレコードにつき4バイトを必要とします。
さらに、クラスタテーブルが必要とする記憶容量を計算する時、NDBCluster
ストレージエンジンを利用する全てのテーブルがプライマリキーを要求する事を覚えておく必要があります。もしプライマリキーがユーザによって定義されない時は、NDB
によって 「隠れ」
プライマリキーが作成されます。この隠れプライマリキーは1つのテーブルレコードに付き31から35バイトを消費します。
クラスタメモリ要求を計算する時には、MySQLForge
で有効な ndb_size.pl
ユーティリティが便利です。このPerlスクリプトは現在のMySQL(非クラスタ)データベースに接続し、そのデータベースが
NDBCluster
ストレージエンジンを利用するとどれくらいの容量を必要とするかについてのレポートを作成します。
数値タイプが必要とする記憶容量
| データタイプ | 要求ストレージ |
TINYINT | 1バイト |
SMALLINT | 2バイト |
MEDIUMINT | 3バイト |
INT, INTEGER | 4バイト |
BIGINT | 8バイト |
FLOAT( | 4 bytes if 0 <= p <= 24, 8 bytes if 25
<= p <= 53 |
FLOAT | 4バイト |
DOUBLE [PRECISION], REAL | 8 バイト |
DECIMAL(,
NUMERIC( | 変動; 後の説明を参照 |
BIT( | 約(M+7)/8 バイト |
DECIMAL (とNUMERIC
)カラムの値は、少数第9位(10基準)の桁を4バイトにパックするバイナリフォーマットを利用して表現されます。各値の整数部と端数部の格納は別々に決定されます。9桁の倍ごとに4バイト、「余りの」
桁には4バイトの端数容量がそれぞれ必要です。余りの桁に必要なストレージ要求を以下のテーブルで紹介します。
| 余り桁数 | バイト数 |
| 0 | 0 |
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 2 |
| 5 | 3 |
| 6 | 3 |
| 7 | 4 |
| 8 | 4 |
データと時刻タイプが必要とする記憶容量
| データタイプ | 記憶容量 |
DATE | 3バイト |
DATETIME | 8バイト |
TIMESTAMP | 4バイト |
TIME | 3バイト |
YEAR | 1バイト |
文字列タイプの記憶容量
| データタイプ | 記憶容量 |
CHAR( | バイト、0
<= 255 |
VARCHAR( | L + 1 バイト、 一方で
そして 0
<= 255 (下のメモを参照)
または
L + 2 バイト、一方で
そして 256
<= 65535 (下のメモを参照). |
BINARY( | バイト、0
<= 255 |
VARBINARY( | L + 1 バイト 一方で
そして 0
<= 255 (下のメモを参照)
または
L + 2 バイト、 一方で
そして 256
<= 65535 (下のメモを参照). |
TINYBLOB, TINYTEXT | L+1 バイト、一方で
L <
28 |
BLOB, TEXT | L+2 バイト 一方で
L <
216 |
MEDIUMBLOB, MEDIUMTEXT | L+3 バイト、一方で
L <
224 |
LONGBLOB, LONGTEXT | L+4 バイト、一方で
L <
232 |
ENUM(' | 列挙値により1か2バイト(最高65,535値) |
SET(' | セットメンバの数により、1、2、3、4、または8バイト(最高64メンバ) |
CHAR、VARCHAR、そして
TEXT
タイプでは、先行テーブルの中の
L と M
の値は文字数として解釈される必要があり、そしてカラム仕様の中のこれらのタイプの長さは文字数を表します。例えば、TINYTEXT
値を格納するには、L
文字に加え1バイトが必要です。
VARCHAR、VARBINARY、そして
BLOB と TEXT
タイプは可変長タイプです。それぞれが必要とする記憶容量はこれらの要因によって決まります。
カラム値の実長さ
カラムの可能最大長さ
カラムに使用される文字セット
例えば、VARCHAR(10)
カラムは最大長さ10の文字列を保持する事ができます。カラムが
latin1
文字セットを利用すると仮定すると(一文字につき1バイト)、実際の記憶容量は文字列の長さ(L)と、その文字列の長さを記録する1バイトです。'abcd'
文字列では、L
は4で、必要とする記憶容量は5バイトです。もし同じカラムが代わりに
VARCHAR(500)
として宣言されていたら、その文字列
'abcd' は 4 + 2 = 6
バイトを必要とします。カラム長は255以上なので、プリフィックスには1バイトではなく2バイトが要求されます。
特定の
CHAR、VARCHAR、または
TEXT
カラム値を格納するのに利用される
バイト
数を計算するには、そのカラムに利用される文字セットを考慮に入れなければいけません。特に、utf8
ユニコード文字セットを利用する時には、全ての
utf8
文字セットが同じバイト数を利用するわけではないという事を覚えておく必要があります。utf8
文字の異なるカテゴリに利用される格納についての概要は、「Unicodeのサポート」
を参照してください。
注:VARCHAR
や VARBINARY カラムの
有効 最大長は65,532です。
MySQL 5.1の NDBCLUSTER
ストレージエンジン
は可変幅カラムをサポートします。これは、そのような値が4バイトにそろっている場合以外は、MySQLクラスタテーブルの
VARCHAR
カラムが、他のストレージエンジンを利用した時と同じ容量を必要とするという意味になります。それ故、latin1
文字セットを利用する VARCHAR(50)
カラムに格納された 'abcd'
文字列は8バイトを必要とします。(MyISAM
テーブルの中の同じカラム値に必要とされる6バイトではない)これは、VARCHAR(50)
カラムが、格納された文字列の長さに関わらず、1つのレコードにつき52バイトを必要としていた、NDBCLUSTER
の初期バージョンからの変更点を表しています。
BLOB と TEXT
タイプは、そのタイプの最大長さにより、カラム値の長さを記録する為に1、2、3、またはバイトを必要とします。「BLOBとTEXT タイプ」を参照してください。
TEXT と BLOB
カラムは、TEXT
カラム内のそれぞれの行が二つの部分で構成される、NDBクラスタストレージエンジンの中で異なる方法で実行されます。そのうちの1つは固定サイズ(256バイト)で、実際に元のテーブルに格納されます。それ以外の物は、隠れテーブルに格納された256バイト以上のデータで構成されます。この二つ目のテーブルの行は常に2,000バイトの長さです。もし
サイズ <= 256
(サイズ
が行のサイズを表している)時、TEXT
カラムのサイズは256で、そうでない時のサイズは256
+ サイズ + (2000 –
(サイズ – 256) %
2000)です。
ENUM
オブジェクトのサイズは異なる列挙値の数によって決定します。1バイトは、最大255の値を持つ列挙に使用されます。2バイトは、256から65,535の間の値を持つ列挙に使用されます。「ENUM タイプ」を参照してください。
SET
オブジェクトのサイズは異なるセットメンバの数によって決定します。もしセットサイズがN
なら、オブジェクトは1、2、3、4、または8バイトに丸められた
(
バイトをコピーします。N+7)/8SET
は最高64メンバを持つ事ができます。「SET タイプ」を参照してください。
最適な格納の為には、毎回一番正確なタイプの利用を試みる必要があります。例えば、もし整数カラムが
1 から 99999
の範囲の値に利用されたら、MEDIUMINT
UNSIGNED
が最適タイプです。要求される値を全て表すタイプの中で、このタイプが使用する容量が一番少ないです。
DECIMAL
カラムを利用した全ての基本的な計算 (+,
-, *, /)
は、65桁の精度で行われます。「数値タイプの概要」を参照してください。
もし精度がそれほど重要でなかったり、スピードが最優先事項でなければ、DOUBLE
タイプでも十分でしょう。高精度の為に、BIGINT
の中に格納されている固定小数点タイプにいつでも変換する事ができます。これで、64ビットの整数で全ての計算をし、その後必要に応じて結果を浮動小数点値に変換する事ができます。
他のベンダーによってSQL推進の為に書かれたコードを促進する為に、次のテーブルに書かれているようにMySQLはデータタイプをマップします。これらのマッピングにより、他のデータベースシステムからテーブル定義をMySQLにインポートする事が容易になります。
| 他のベンダータイプ | MySQLタイプ |
BOOL, | TINYINT |
BOOLEAN | TINYINT |
CHAR VARYING( | VARCHAR( |
DEC | DECIMAL |
FIXED | DECIMAL |
FLOAT4 | FLOAT |
FLOAT8 | DOUBLE |
INT1 | TINYINT |
INT2 | SMALLINT |
INT3 | MEDIUMINT |
INT4 | INT |
INT8 | BIGINT |
LONG VARBINARY | MEDIUMBLOB |
LONG VARCHAR | MEDIUMTEXT |
LONG | MEDIUMTEXT |
MIDDLEINT | MEDIUMINT |
NUMERIC | DECIMAL |
データタイプのマッピングは、元のタイプの仕様が廃棄された後、テーブル作成時に行われます。もし他のベンダーが利用したタイプでテーブルを作成して、DESCRIBE
ステートメントを発行すると、MySQLは、同等のMySQLタイプを利用してテーブル構成をレポートします。例:
tbl_name
mysql>CREATE TABLE t (a BOOL, b FLOAT8, c LONG VARCHAR, d NUMERIC);Query OK, 0 rows affected (0.00 sec) mysql>DESCRIBE t;+-------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------------+------+-----+---------+-------+ | a | tinyint(1) | YES | | NULL | | | b | double | YES | | NULL | | | c | mediumtext | YES | | NULL | | | d | decimal(10,0) | YES | | NULL | | +-------+---------------+------+-----+---------+-------+ 4 rows in set (0.01 sec)