Go to the first, previous, next, last section, table of contents.


7 MySQL 言語リファレンス

7.1 リテラル:文字列と数値をどのように書くか?

7.1.1 文字列

文字列は文字の並びです。引用符(`'')または二重引用符(`"')で括ら れます(後者は ANSI モードで実行していない場合のみ)。 例:

'a string'
"another string"

文字列中では、いくつかのシーケンスは特別な意味を持ちます。これらのシーケ ンスのそれぞれはエスケープ文字として知られるバックスラッシュ (`\')で始まります。MySQL は次のエスケープシーケンスを認識 します。

\0
ASCII 0 (NUL) 文字。
\n
改行文字。
\t
タブ文字。
\r
リターン文字。
\b
バックスペース文字。
\'
引用符(`'')。
\"
二重引用符(`"')。
\\
バックスラッシュ(`\')文字。
\%
`%' 文字。これは `%' がワイルドカード文字として解釈される文脈 で、`%' そのものを検索するために使用されます。
\_
_ 文字。これは `_' がワイルドカード文字として解釈される文脈 で、_ そのものを検索するために使用されます。

いくつかの文字列文脈で `\%' または `\_' を使用すると、これらは文 字列 `%'`_' ではなく、`\%'`\_' を返します。

文字列中に引用符を含める方法はいくつかあります:

次の SELECT ステートメントは、クォートとエスケープがどのように働 くかを示します:

mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
+-------+---------+-----------+--------+--------+
| hello | "hello" | ""hello"" | hel'lo | 'hello |
+-------+---------+-----------+--------+--------+

mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
+-------+---------+-----------+--------+--------+
| hello | 'hello' | ''hello'' | hel"lo | "hello |
+-------+---------+-----------+--------+--------+

mysql> SELECT "This\nIs\nFour\nlines";
+--------------------+
| This
Is
Four
lines |
+--------------------+

バイナリデータを BLOB フィールドに挿入したい場合、次の文字をエスケープ シーケンスで表す必要があります:

NUL
ASCII 0。`\0' (バックスラッシュと ASCII `0' 文字) に置き換える べきです。
\
ASCII 92, バックスラッシュ。`\\' と表記してください。
'
ASCII 39, 引用符。`\'' と表記してください。
"
ASCII 34, 二重引用符。`\"' と表記してください。

C コードを書く場合、INSERT 節で文字をエスケープするために、C API 関数 mysql_escape_string() を使用できます。 「22.3 C API 関数概要」節参照. Perl では、DBI パッケージの quote メソッドを使 用して、特殊文字を適当なエスケープシーケンスに変換できます。 「22.5.1.1 The DBI interface」節参照.

上記の特殊文字のどれかを含む可能性のある全ての文字列について、エスケープ 関数を使用すべきです!

7.1.2 数値

整数は数字の並びで表現されます。 浮動小数点は `.' で小数を分割します。 どちらの型も負数を表すために `-' を前につけます。

正当な数値の例:

1221
0
-32

有効な浮動小数点の例:

294.42
-32032.6809e+10
148.00

整数が浮動小数点の文脈で使用されるかもしれません; この場合、浮動小数点に 変換されます。

7.1.3 16進法の値

MySQL は16進法の値をサポートします。 数値の文脈では、これらは整数(64ビット精度)のように振る舞います。 文字列の文脈では、hexの桁のそれぞれのペアが文字に変換された バイナリー文字のように振る舞います。

mysql> SELECT 0xa+0
       -> 10
mysql> select 0x5061756c;
       -> Paul

16進数表記は、ODBC において BLOB の値を与えるためにしばしば使用されます。

7.1.4 NULL

NULL は ``no data'' を意味し、数値型の 0 や文字列型の空文 字列とは異なることに注意してください。 「20.15 NULL 値での問題」節参照.

テキストファイルの読み込みや書き出し時に、NULL\N で 表現されます。 (LOAD DATA INFILE, SELECT ... INTO OUTFILE). 「7.18 LOAD DATA INFILE構文」節参照.

7.1.5 データベース名、テーブル名、インデックス名、フィールド名、エイリアス名

データベース名、テーブル名、インデックス名、フィールド名、エイリアス名は MySQL では全て同じ規則に基づきます:

注意: 規則は MySQL 3.23.6 で変更されました。それは識別子(データベー ス名、テーブル名、フィールド名)の ` でのクォートを導入した時です (ANSI モードで実行する場合は、" も識別子をクォートするために働きま す)。

識別子 最大長 許される文字
データベース 64 ディレクトリ名として許されるすべての文字。/ を除く。
テーブル 64 ファイル名として許されるすべての文字。/. を除く。
フィールド 64 すべての文字
エイリアス 255 すべての文字

注意: 上記に加え、識別子内には ASCII(0) と ASCII(255) を持てません。

注意: 識別子が制限された単語であったり特殊文字を含む場合は、それを使用する 時には常に ` でクォートする必要があります:

SELECT * from `select` where `select`.id > 100;

MySQL の前のバージョンでは、名前の規則は次に従います:

1e のような名前は使用しないことを勧めます。1e+1 のような式が あいまいだからです。これは、式 1e + 1 として、または数値 1e+1 として解釈されます。

MySQL では次の形式のいずれかを使用してフィールドを参照できます:

フィールドの参照方法 意味
col_name クエリ中で使用されるテーブル内に存在している col_name という名前のフィールド
tbl_name.col_name 現在のデータベースのテーブル tbl_name 内のフィールド col_name
db_name.tbl_name.col_name データベース db_name のテーブル tbl_name 内のフィールド col_name。この形式は 3.22 以降 で有効です。
`column_name` キーワードであったり特殊文字を含むフィールド。

参照が曖昧でないならば、ステートメント中のフィールド参照の前に tbl_name または db_name.tbl_name を記述する必要はありません。例えば、テー ブル t1t2 がそれぞれフィールド c を含み、t1t2 の両方を使用する SELECT ステートメントで c を取 り出すとします。この場合、c はステートメントで使用されるテーブル 間で唯一でないので曖昧です。そのため、t1.c または t2.c と 記述するこよによりどちらのテーブルを意味するかを示す必要があります。同様 に、データベース db1 のテーブル t とデータベース db2 のテーブル t から取り出す場合、これらのテーブル中の項 目は、db1.t.col_namedb2.t.col_name として参照する必要 があります。

構文 .tbl_name は現在のデータベース内のテーブル tbl_name を意味します。この構文はいくつかの ODBC が `.' 文字をテーブル名の前 に置くために許されています。

7.1.5.1 名前のケース依存性

MySQL では、データベースとテーブルは、ディレクトリと そのディレクトリ中のファイルに対応します。そのため、下で動作するオペレー ティングシステムのケース依存性は、データベースとテーブル名のケース依存性を決定します。 データベース名とテーブル名は Unix ではケース依存で、Win32 ではケース非依 存です。

注意: Win32 ではデータベース名とファイル名はケース非依存ですが、 同じクエリ内で、データベースやテーブルを異なるケースを使用して参照すべき ではありません。 以下のクエリは動きません。なぜなら my_tableMY_TABLE の両方を 参照しているからです:

mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;

フィールド名は全ての場合でケース非依存です。

テーブルの別名はケース依存です。 以下のクエリは動きません。なぜなら aA のエイリアスを両方 参照しているからです:

mysql> SELECT col_name FROM tbl_name AS a
           WHERE a.col_name = 1 OR A.col_name = 2;

フィールドのエイリアス名はケース非依存です。

7.2 ユーザー変数

MySQL は、@variablename 構文でスレッド固有の変数をサポー トします。変数名は現在の文字セットのアルファベットと数字、それに `_'`$'`.' 文字からなります。デフォルト文字セットは ISO-8859-1 Latin1 です。 これは mysqld--default-character-set オプションを 与えることで変更できます. (3.23.14 以上の場合のみ。 それ以前のバージョンでは MySQL 再コンパイルが必要) 「10.1.1 データとソートに使用されるキャラクターセット」節参照。

変数は初期化する必要はありません。デフォルトでは NULL であり、整数 値、実数値、文字列値を格納できます。すべてのスレッド変数は、スレッドが終了 すると自動的に解放されます。

SET 構文で変数を設定できます:

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

@variable:=expr 構文で、式中で変数を設定することも可能です:

select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
+----------------------+------+------+------+
| @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 (@aa:=id) AS a, (@aa+3) AS b FROM table_name HAVING b=5;

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

7.3 フィールド型

MySQLは多くのフィールド型をサポートしており、それらは3つのカテゴリにグループ化されます: 数値型、日付及び時間型、そして文字列(文字)型。 この章ではまず、利用できる型の概要から始まり、それから各カテゴリの各フィールド型の所要記憶容量の要約と、型の属性についてのより詳細な情報を提供します。 概要は意図的に簡潔にまとめています。値として指定できる書式のようなフィールド型固有の付加情報は、詳細の説明部にて調べて下さい。

MySQLでサポートされるフィールド型は以下に示す通りです。後に続く文字の意味は説明のために使われます:

M
最大表示サイズを意味します。最大の表示桁数は 255.
D
浮動小数点数型に適用され、小数点以下の桁数を表します。 最大の値は 30 ですが、これは M-2 より大きくなってはいけません。

中カッコ(`['及び`]')は型定義の一部であり、それがオプションであることを表します。

もしあるフィールドに ZEROFILL を指定した場合、 MySQL は自動で UNSIGNED 属性をそのフィールドに 追加します。

TINYINT[(M)] [UNSIGNED] [ZEROFILL]
とても小さい整数。符号つきの範囲は -128127。符号なしの範囲は 0255
SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
小さい整数。符号つきの範囲は -3276832767。符号なしの範囲は 065535
MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
中間の整数。符号ありの範囲は -83886088388607。符号なしの範囲は 016777215
INT[(M)] [UNSIGNED] [ZEROFILL]
通常の整数。符号ありの範囲は -21474836482147483647。符号なしの範囲は 04294967295
INTEGER[(M)] [UNSIGNED] [ZEROFILL]
これは、INTの同義語です。
BIGINT[(M)] [UNSIGNED] [ZEROFILL]
大きい整数。符号ありの範囲は -92233720368547758089223372036854775807。 符号なしの範囲は 018446744073709551615。 全ての演算は符合付き BIGINT または DOUBLE で行われるため、 符合無しの 9223372036854775807 (63 bits) よりも大きな整数を ビット関数以外で使用すべきではありません! -+及び*は、両方の引数がINTEGER値の時、BIGINT演算を使うことに注意して下さい!これは、2つの大きな整数のかけ算を行なう(又は整数を返す関数の結果が大きな整数である)時、結果が9223372036854775807よりも大きい場合に予期しない結果を受け取ることがあるということを意味しています。
FLOAT(precision) [ZEROFILL]
浮動小数点数。符号なしにはできません。単精度浮動小数点数では precision<=24 で、倍精度浮動小数点数では 25〜53 の間です。 これらの型は次で述べるFLOATDOUBLE型に似ています。 FLOAT(X)は、FLOAT及びDOUBLE型に一致する同じ範囲を持っていますが、 表示サイズや小数点以下桁数が定義されません。 MySQL 3.23 では、これは正しい浮動小数点です。前の MySQL バージョンでは, FLOAT(precision) は常に小数部は2桁で した。 この構文は ODBC 互換です。
FLOAT[(M,D)] [ZEROFILL]
小さい浮動小数点数。符号なしにはできません。 範囲は -3.402823466E+38-1.175494351E-3801.175494351E-383.402823466E+38です。 M は表示幅で D は小数部桁数です。引数が無いか引数が24以下の FLOAT は単精度浮動小数点数を意味します。
DOUBLE[(M,D)] [ZEROFILL]
通常の浮動小数点数。符号なしにはできません。 範囲は -1.7976931348623157E+308-2.2250738585072014E-30802.2250738585072014E-3081.7976931348623157E+308です。 M は表示幅で D は小数部桁数です。引数が無いか DOUBLE か、25 <= X <= 53 である FLOAT(X) は倍精度浮動小数点数を意味します。
DOUBLE PRECISION[(M,D)] [ZEROFILL]
REAL[(M,D)] [ZEROFILL]
これらはDOUBLEの同義語です。
DECIMAL[(M[,D])] [ZEROFILL]
パック無し浮動小数点数。符号なしにはできません。CHARフィールドのように振舞います。`パック無し'は、数値が文字列として格納されることを意味し、数値のそれぞれの桁、小数点、及び負数での`-'符号に1文字使用します。 Dが0の時、値は小数点や小数部を持ちません。DECIMAL値の最大範囲はDOUBLEと同じですが、実際の範囲はDECIMALフィールドに与えられたM及びDの選択に強制されます。 D を省略した場合は 0 に設定されいます。M を省略した場合は 10 に設定されます。 MySQL 3.22 では、 M 引数は符号や小数点を含みます。
NUMERIC(M,D) [ZEROFILL]
DECIMALと同じ。
DATE
日付。サポートされる範囲は'1000-01-01'から'9999-12-31'まで。 MySQL'YYYY-MM-DD'の書式でDATE値を表示しますが、DATEフィールドへの値の割当ては、文字列もしくは数値のいずれかの使用が許されます。
DATETIME
日付と時刻の組み合わせ。サポートされる範囲は'1000-01-01 00:00:00''9999-12-31 23:59:59'です。MySQLDATETIME値を'YYYY-MM-DD HH:MM:SS'という書式で表示しますが、DATETIMEフィールドへの値の割当ては、文字列もしくは数値のいずれかの使用が許されます。
TIMESTAMP[(M)]
タイムスタンプ。範囲は'1970-01-01 00:00:00'2106年末までです。MySQLTIMESTAMP値をYYYYMMDDHHMMSSYYMMDDHHMMSSYYYYMMDD又はYYMMDDという書式で表示し、それはM14(もしくは誤ってそれ以上の値を指定した時)、128又は6のいずれが指定されたかに依存します。しかしながらTIMESTAMPフィールドへの値の割当ては、文字列もしくは数値のいずれかの使用が許されます。 TIMESTAMPフィールドは、最後に操作された時刻を自動的に設定するので、INSERTUPDATE操作の時刻を記録するのに役立ちます。 NULL値を与えることによっても、現在時刻を設定できます。 「7.3.6 日付と時間の型」節参照。
TIME
時間。範囲は'-838:59:59''838:59:59'です。 MySQLTIME値を'HH:MM:SS'という書式で表示しますが、TIMEフィールドへの値の割当ては、文字列もしくは数値のいずれかの使用が許されます。
YEAR[(2|4)]
年。2桁または4桁形式(デフォルトは4桁)。許される値は、4桁形式では 19012155, 0000 で、2桁形式(70〜69)では 1970〜2069 です。MySQLYEAR 値を YYYY 形式で表示しますが、 YEAR フィールドへの値の割り当ては文字列と数字のどちらでも使用できま す。(YEARMySQL 3.22 での新しい型です。)
[NATIONAL] CHAR(M) [BINARY]
固定長文字列で、格納時には必ず指定された長さまで右側に空白を埋めます。 Mの範囲は 1 から 255 文字です。後続の空白は値の取り出し時に削除され ます。BINARY キーワードが与えられない場合、CHAR 値のソートと 比較は、デフォルト文字セットに従ってケース非依存の方法で行なわれます。 NATIONAL CHAR (短い形式は NCHAR) は、ANSI SQL で、CHAR フィー ルドがデフォルト文字セットを使用することを定義する方法です。これは MySQL ではデフォルトです。 CHARCHARACTER の略記です。 MySQLCHAR(0) 型のフィールドの生成を許します。これは主 に、実際にはもう値が使われていないフィールドが存在することに依存しているよ うないくつかの古いアプリケーションに対応する必要がある時に便利です。2つの 値だけを取ることができるフィールドを必要とする時にもとても良いことです: NOT NULL として定義されていない CHAR(0) は1ビットだけを占有 し、2つの値だけを取ることができます: NULL または ""
[NATIONAL] VARCHAR(M) [BINARY]
可変長文字列。 注意: 後続の空白は格納時に削除されます(これは ANSI SQL 仕様と異なります)。 Mの範囲は 1 から 255 文字です。 BINARY キーワードが与えられない場合、ソートと比較はケースに依存しません。 「7.7.1 暗黙のフィールド定義変更」節参照. VARCHARCHARACTER VARYING の略記です。
TINYBLOB
TINYTEXT
最大長 255 (2^8 - 1) 文字の TEXT/BLOB。 「7.7.1 暗黙のフィールド定義変更」節参照.
BLOB
TEXT
最大長 65535 (2^16 - 1) 文字の TEXT/BLOB。 「7.7.1 暗黙のフィールド定義変更」節参照.
MEDIUMBLOB
MEDIUMTEXT
最大長 16777215 (2^24 - 1) 文字の TEXT/BLOB。 「7.7.1 暗黙のフィールド定義変更」節参照.
LONGBLOB
LONGTEXT
最大長 4294967295 (2^32 - 1) 文字の TEXT/BLOB。 「7.7.1 暗黙のフィールド定義変更」節参照.
ENUM('value1','value2',...)
列挙。 対象となる文字列は、値を一つだけ持ち、値リスト'value1', 'value2',...(又はNULL)から選ばれます。ENUMは最大65535個の固有値を持つことができます。
SET('value1','value2',...)
組。 対象となる文字列は0以上の値を持ち、それぞれ値リスト'value1', 'value2',...から選ばれなければなりません。 SETは、最大 64個の要素を持つことができます。

7.3.1 フィールドタイプの所要容量

MySQLがサポートする各フィールドタイプ毎の所要容量を、カテゴリ別に以下に記述します。

7.3.2 数値タイプ

フィールドタイプ 所要容量
TINYINT 1 byte
SMALLINT 2 bytes
MEDIUMINT 3 bytes
INT 4 bytes
INTEGER 4 bytes
BIGINT 8 bytes
FLOAT(X) X <= 24 の場合 4、25 <= X <= 53 の場合 8
FLOAT 4 bytes
DOUBLE 8 bytes
DOUBLE PRECISION 8 bytes
REAL 8 bytes
DECIMAL(M,D) M bytes (M < D の場合 D+2)
NUMERIC(M,D) M bytes (M < D の場合 D+2)

7.3.3 日付と時間タイプ

フィールドタイプ 所要容量
DATE 3 bytes
DATETIME 8 bytes
TIMESTAMP 4 bytes
TIME 3 bytes
YEAR 1 byte

7.3.4 文字列タイプ

フィールドタイプ 所要容量
CHAR(M) M bytes, 1 <= M <= 255
VARCHAR(M) L+1 bytes, where L <= M and 1 <= M <= 255
TINYBLOB, TINYTEXT L+1 bytes, where L < 2^8
BLOB, TEXT L+2 bytes, where L < 2^16
MEDIUMBLOB, MEDIUMTEXT L+3 bytes, where L < 2^24
LONGBLOB, LONGTEXT L+4 bytes, where L < 2^32
ENUM('value1','value2',...) 1 or 2 bytes, 列挙値の数に依存 (最大値は 65535 )
SET('value1','value2',...) 1, 2, 3, 4 or 8 bytes, 要素の数に依存 (最大要素 64 )

VARCHARBLOB、及びTEXT型は可変長型であり、所要容量は、フィールドのとり得る最大サイズというよりはむしろフィールド値の実際の長さに依存します(前の表でLと表しました)。 例えば、VARCHAR(10)フィールドは、最大10文字分の長さの文字列を保持することが出来ます。実際の所要容量は、文字列の長さ(L)と、その長さを記録するための1バイトを加えます。文字列'abcd'においては、Lは4で、所要容量は5バイトです。

BLOBTEXT型は、フィールド値の長さを記録するのに、1、2、3、又は4バイト必要とし、型のとり得る最大の長さに依存します。

テーブルが可変長フィールド型を含む場合、そのレコードフォーマットもまた可変長となるでしょう。 テーブルが作成された時、MySQLは確かな条件の下、フィールドを可変長タイプから固定長タイプへ変更し、副作用を起こすことに注意して下さい。

ENUMオブジェクトのサイズは、異なる列挙値の数によって決められます。 列挙する数が255以内では、1バイトが使用されます。 列挙する数が65535以内では、2バイトが使用されます。

SETオブジェクトのサイズは、異なる要素の数によって決められます。 組のサイズをNとすると、オブジェクトは(N+7)/8バイトを占有し、1、2、3、4又は8バイトに切上げられます。 1つのSETは、最大64要素を持つことができます。

7.3.5 数値型

MySQL は ANSI/ISO SQL92 数値型をすべてサポートします。これらの型 は正確な数値データ型(NUMERIC, DECIMAL, INTEGER, SMALLINT)、近似数値型(FLOAT, REAL, DOUBLE PRECISION)を含みます。キーワード INTINTEGER の同義語で、 DECDECIMAL の同義語です。

MySQL では NUMERICDECIMAL 型は、SQL92 標準で許 されているように同じ型として実装されています。これらは正確な精度を維持する ことが重要な値(例えば金銭データ)に使用されます。これらの型の一つのフィール ドを宣言する時、精度と大きさが指定できます(通常はそうします); 例えば:

    salary DECIMAL(9,2)

この例では、9 (precisoin) は値を格納する重要な数値の桁数を表 します。そして 2 (scale) は小数点に続いて格納される桁数を表 します。従って、この場合 salary フィールドに格納することができる値 の範囲は、-9999999.99 から 9999999.99 です。ANSI/ISO SQL92 では、構文 DECIMAL(p)DECIMAL(p,0) と等しいです。同様に、 構文 DECIMALDECIMAL(p,0) と等しいです。ここで p の値の決定は実装に許されてます。DECIMAL/NUMERIC データ型のこ れらの異なる形式は、MySQL は現在サポートしていません。この型の主 な利益は精度と大きさの両方を明示的に制御する機能から引き出されるので、これ は通常深刻な問題ではありません。

DECIMALNUMERIC 値は、値の小数の精度を維持するため、バイ ナリ浮動小数点数としてではなく、文字列として格納されます。1文字は値のそれ ぞれの桁(scale > 0 の場合)と `-' 記号(負数の場合)に使用されま す。scale が 0 の場合、DECIMALNUMERIC 値は小数点 と小数部を含みません。

DECIMALNUMERIC 値の最大範囲は DOUBLE と同じです。 しかし DECIMALNUMERIC フィールドに与えられる実際の範囲は フィールドに与えられた precisionscale によって強制されま す。このフィールドに、指定された scale で許されるよりも多い桁の小数 部を持つ数値が割り当てられた場合、値はその scale に丸められます。 DECIMALNUMERIC フィールドに、指定された(またはデフォルト の) precisionscale で示された範囲を超えた大きさの値を割 り当てた時、MySQL はその範囲の対応する最大値を表す値を格納します。

ANSI/ISO SQL92 標準に対する拡張として、上の表にリストしたように、 MySQL は整数型 TINYINT, MEDIUMINT, BIGINT も サポートします。MySQL によってサポートされる他の拡張として、オプ ションで、型の基本キーワードに続けて括弧内に指定する整数値の表示幅(例えば INT(4))があります。このオプションの幅指定は、フィールドに指定された 幅よりも少ない幅の値の表示の左側を埋めるために使用されます。しかしフィール ドに格納することができる値の範囲や、フィールドに指定された幅を超える幅の値 について表示される桁数は制約されません。オプションの拡張属性 ZEROFILL を指定して使用された場合、デフォルトの埋められる空白は 0 で置き換えられます。例えば、INT(5) ZEROFILL として宣言されたフィー ルドでは、値 40004 として取り出されます。注意: 整数フィー ルド内に表示幅よりも大きい値を格納する場合、MySQL が複雑な join のために一時テーブルを生成する時に、問題を体験するでしょう。この場合 MySQL はデータがオリジナルのフィールド幅に合っていることを信用す るためです。

すべての整数型はオプションの(非標準)属性 UNSIGNED を持つことができ ます。符合無しの値はフィールド内に正の数だけを許可したくて、フィールドに対 して少し大きい数値の範囲が必要な時に使用できます。

FLOAT 型は近似数データ型を表すために使用されます。ANSI/ISO SQL92 標 準は、FLOAT キーワードに続く括弧中にオプションの精度(指数の範囲では ない)の指定を許しています。MySQL 実装はこのオプションの精度指定も サポートしています。キーワード FLOAT が精度の指定無しでフィールド型 として使用された時は、MySQL は値を格納するために4バイトを使用しま す。FLOAT キーワードに続く括弧中に2つの数値を与える構文もサポートさ れます。このオプションでの、最初の数値は値に必要な容量をバイトで表します。 2番目の数値は、格納、表示される小数部の桁数を指定します(DECIMALNUMERIC と同様)。MySQL がフィールドに指定されたよりも大き い小数部の桁数を持つ数値をこのフィールドに格納する時、値の格納時に余計な桁 を取り除くように値が丸められます。

REALDOUBLE PRECISION 型は精度指定を許しません。 ANSI/ISO SQL92 標準に対する拡張として、MySQLDOUBLEDOUBLE PRECISION 型の同義語として認識します。REAL の精度は DOUBLE PRECISION の指定よりも小さいことを要求する標準と異なり、 MySQL はどちらも8バイトの倍精度小数点の値として実装しています ("ANSI モード"で実行していない場合)。移植性を最大にするためには、近似数値 データ値の格納を要求するコードは、精度や小数部桁数の指定無しの FLOATDOUBLE PRECISION を使用すべきです。

フィールドの型の値の許容範囲を超えた数値を代入しようとすると、MySQL は その値を許容範囲いっぱいに切り詰め、その結果を代わりに代入します。

例えば、 INT フィールドの範囲は -2147483648 から 2147483647 です。 もし -9999999999INT フィールドに挿入しようとすると、値は範囲の最低値に 修正され、 -2147483648 が代わりに代入されます。同様に、9999999999 の場合、 2147483647 が代わりに代入されます。

そして、INT フィールドが符号無しの場合、フィールドの範囲の大きさは 同じですが、限界値は 04294967296 になります。 もし -99999999999999999999 を代入しようとすると、 値は 04294967296 として代入されます。

ALTER TABLE, LOAD DATA INFILE, UPDATE または multi-row INSERT 時、これらの変換は `警告' として得られます。

7.3.6 日付と時間の型

日付と時間の型は DATETIME, DATE, TIMESTAMP, TIME, YEAR です. これらはそれぞれ値に適正な範囲があり、 ``zero'' はあなたが間違った値を指定した場合に用いられます。注意: MySQL は 確実に '厳密でない' 正しい日付の値、例えば 1999-11-31 を格納するこ とができます。この理由は、日付をチェックする処理の責任はアプリケーションに あり、SQL サーバにはないと考えているからです。日付を'速く'チェックするため に、MySQL は月が 0〜12 の範囲であるかと日が 0〜31 の範囲であるか だけをチェックします。上述の範囲は、MySQLDATE または DATETIME フィールドに、日または月日が 0 である日付を格納できるため に定義されています。これは、正確な日付を知らない誕生日を登録する必要がある アプリケーションに非常に有用です。この場合、1999-00-001999-01-00 のような日付を単純に登録できます(もちろん、このような日 付を DATE_SUB()DATE_ADD のような関数で使用して、正しい値 が返ることは期待できません)。

これは、日付と時間型で作業する場合に、一般的に考慮しなければならないことです:

7.3.6.1 西暦2000年問題とデータ型

MySQL 自体は2000年問題に対して安全です( 「1.7 2000 年対応」節参照)が、 MySQL に提示される入力値に関してはそうではありません。2桁の 年の入力は何世紀なのかわからないので全て曖昧です。このような値は MySQL が内部で年に4桁を使っていることから4桁の形式に変換されてしまいます。

MySQL は曖昧な日付を DATETIME, DATE, TIMESTAMP および YEAR 型に関して、以下の ルールに従って解釈します。

これらのルールはデータが何を意味しているかに対して妥当な推定を与えるに 過ぎないことに注意してください。この MySQL 発見的手法が正しい値を生成し ない場合は曖昧でない4桁の年を含む入力を与えるべきです。

ORDER BY は2桁の YEAR/DATE/DATETIME 型を正しくソートされます。

注意: MIN()MAX() のようないくつかの関数は TIMESTAMP/DATE を数値 に変換します。これは年が2桁のタイムスタンプはこれらの関数で正しく動作しな いことを意味します。この場合の修復は、TIMESTAMP/DATE を4桁の年の形 式に変換するか、MIN(DATE_ADD(timestamp,INTERVAL 0 DAYS)) のような何 かを使用することです。

7.3.6.2 DATETIME, DATE, TIMESTAMP

DATETIME, DATE, TIMESTAMP型はお互いに関連しています。このセクションで はそれらの特徴と、それぞれがどう同じでどう違うかを示します。

DATETIME 型は日付と時刻の情報を含む値が必要な場合に使います。MySQLDATETIME 値を 'YYYY-MM-DD HH:MM:SS' のフォーマットで取り出し、表示します。 サポートされる範囲は '1000-01-01 00:00:00' から '9999-12-31 23:59:59' です。 (「サポートされる」とはさらに過去の値でも動くかも知れませんが保証の限りではないという意味です)

DATE 型は時刻の部分なしで日付の値のみが必要な場合に使います。MySQLDATE 値を'YYYY-MM-DD' のフォーマットで取り出し、表示します。サポートされ る範囲は '1000-01-01' から '9999-12-31' です。

TIMESTAMP タイプは INSERTUPDATE 操作に自動的に 現在の日付と時刻をマークする場合に提供される型です。 もし複数の TIMESTAMP フィールドがある場合には最初 の一つだけが自動的に更新されます。

最初の TIMESTAMP フィールドの自動更新は以下のいずれかの条件で起こります:

最初以外の TIMESTAMP フィールドも現在の日付と時刻にすることができます。それらのフィールドを NULL または NOW() にすることです。

どの TIMESTAMP フィールドも明示的に望む値をセットすることで現在の日時でない値に することができます。それは最初の TIMESTAMP フィールドについても同じです。この特 性は例えば TIMESTAMP フィールドをあるレコードが生成されたときの日時にし、その後その行 が更新されても変化しないようにしたいというようなときに使えます。

一方、この手法は DATATIME フィールドを行生成時に NOW() で初期化し、以降の更新時に それをほうっておくのと同じように簡単であるとわかるでしょう。

TIMESTAMP の値は 1970 年の最初から 2037 年のどこかの時点までの範囲で有効で、 1秒の時間分解能を持ちます。値は数値として表示されます。

MySQLTIMESTAMP 値を取り出したり表示するのに使うフォーマットは以下の表 に示すようにその表示サイズに依存します。「目一杯の」 TIMESTAMP フォーマッ トは14桁ですが、 TIMESTAMP フィールドはより短い表示サイズで生成することもできます:

フィールド型 表示フォーマット
TIMESTAMP(14) YYYYMMDDHHMMSS
TIMESTAMP(12) YYMMDDHHMMSS
TIMESTAMP(10) YYMMDDHHMM
TIMESTAMP(8) YYYYMMDD
TIMESTAMP(6) YYMMDD
TIMESTAMP(4) YYMM
TIMESTAMP(2) YY

全ての TIMESTAMP フィールドは表示サイズに関係なく同じ格納サイズを持ちます。もっ とも一般的な表示サイズは 6 , 8 , 12 および 14 です。表示サイズはテーブル生成時 に任意の値に指定できますが、 0 および 14 以上の値は強制的に 14 になります。1 から 13 までの奇数のサイズは強制的に一つ大きい偶数になります。

DATETIME, DATE, TIMESTAMP 値は以下の共通フォーマットセットのいずれかを 使って指定できます:

無効な DATETIME , DATE , TIMESTAMP の値は適切な「ゼロ」値に変換されます( '0000-00-00 00:00:00' , '0000-00-00' または 00000000000000 )。

日時の部分に区切りを持つ文字列で指定される値で、月、日の値が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桁で 年が与えられるものと仮定されます。これら以外の長さの数値はあとに 0 が追加 されてこれらのうちのもっとも近い長さのものと解釈されます。

区切りなしの文字列で与えられる値はそれ自身の長さを使って解釈されます。 もし文字列が8または14文字ならば年は最初の4文字で与えられると仮定されま す。そうでなければ最初の2文字で与えられると仮定されます。文字列は左か ら右に年、月、日、時、分、秒と文字列中に表現されている分だけ順に解釈さ れます。つまり6文字以下の文字列は使ってはいけないということです。例え ば1999年3月を指定するつもりで '9903' を指定した場合、 MySQL は「ゼロ」日付 をテーブルに挿入します。これは年と月の部分は 9903 ですが日の部分が欠け ている(ゼロ)ために値が有効な日付でないために起こります。

TIMESTAMP フィールドは有効な値を、表示サイズに関係なく指定された値を最高精度の 時間分解能で格納します。このことはいくつかの意味合いを持ちます。

年の値が二桁で指定された場合、世紀の部分がないので曖昧な値となります。 MySQL は二桁の年の値を以下に示す規則にそって変換します:

ある日付型を他の日付型のオブジェクトに拡張して指定することができます。 しかしそれは値の変化や情報の欠落を起こす可能性があります。

日付の値を指定するときの落とし穴に注意してください:

7.3.6.3 TIME

MySQLTIME の値を 'HH:MM:SS' (時の部分が大きい場合は 'HHH:MM:SS') というフォーマットで扱い、また表示します。 (時の部分が大きい場合は 'HHH:MM:SS')。 TIME 値の範囲は '-838:59:59' から '838:59:59' の範囲です。 時の部分がこんなに大きいのは、TIME 型は一日すなわち24時間以内 の時刻を表現するのに用いられるだけではなく経過時間や二つの事象の間隔 (どちらも24時間を越えたり、負の数になる場合もあります)を表現すること もあるからです。

TIME 値は様々なフォーマットで指定可能です:

文字列で時刻の各部の区切りを含む TIME の値については、時、分、秒が 10 以下 の場合、2桁の数字を指定する必要はありません。'8:3:2''08:03:02' と同 じです。

「短い」 TIME 値を TIME フィールドとして指定する場合は要注意です。 MySQL はその値をもっとも右端の桁は秒を表すと仮定して解釈します (MySQLTIME の値を一日の うちの時刻としてより経過時間として解釈します)。例えば '11:12','1112', 1112'00:11:12' (11時12分)を表しているつもりでいても、 MySQL はこれらを '00:00:12' (11分12秒)として解釈します。 同様に '12' および 12'00:00: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' と指定された値なのか無効なために変換された結果なのかを区 別する方法はないことに注意してください。

7.3.6.4 YEAR

YEAR 型は年を表現するのに使われる1バイトの値です。

MySQLYEAR の値を YYYY というフォーマットで扱い、 また表示します。範囲は 1901 から 2155 です。

YEAR 型は様々なフォーマットで指定可能です:

無効な YEAR 値は 0000 に変換されます。

7.3.7 文字列型

文字列型は CHAR, VARCHAR, BLOB, TEXT, ENUM および SET です。

7.3.7.1 CHAR 型と VARCHAR

CHAR 型と VARCHAR 型はよく似ていますが格納、取り出しの手順に違いがあります。

CHAR フィールドの長さはテーブルを生成するときに宣言した長さに固定されます。長さ は 1 から 255 までの値を取ります。CHAR が格納されるときには指定された長さに なるように右側に空白が詰められます。CHAR の値が取り出された場合には右側 (後続)の空白は取り除かれます。

VARCHAR フィールドの値は可変長文字列です。 VARCHAR フィールドは CHAR フィールド と同じく 1 から 255 までの長さに宣言できます。 (MySQL 3.23 では, CHAR の長さは 0 から 255 まで許されています.) しかし CHAR 型と異なり VARCHAR 型の値は必要な文字数の分に 長さを記録する1 バイトを足した領域に格納されます。値には桁合わせのための空白はつけられ ません。後続の空白は値の格納時に取り除かれます。(この空白の除去は ANSI SQL仕様とは違っています。)

もし CHAR または VARCHAR フィールドに、フィールドの最大長を 越える長さの値を与えた場合は、適合するように切り詰められます。

以下の表はこれらの二つのフィールド型の違いを、CHAR(4) および VARCHAR(4) に様々 な文字列値を格納した結果を示すことで表しています。

CHAR(4) 必要な格納域 VARCHAR(4) 必要な格納域
'' ' ' 4 バイト '' 1 バイト
'ab' 'ab ' 4 バイト 'ab' 3 バイト
'abcd' 'abcd' 4 バイト 'abcd' 5 バイト
'abcdefgh' 'abcd' 4 バイト 'abcd' 5 バイト

CHAR(4) フィールドの後続の空白は取り出し時にとりのぞかれるので、CHAR(4)および VARCHAR(4) から取り出される値はどの場合でも同じです。

CHAR および VARCHAR フィールドの値はテーブルの生成時に BINARY 属性が つけられない限り、大文字と小文字を区別しないでソート・比較されます。BINARY 属性はその 列の値が大文字、小文字を区別して、MySQLサーバを実行しているマシンの ASCII順にソート・比較されることを意味します。

BINARY 属性は「固定的」です。つまり、もし BINARY であると指定された フィールドが式の中にあると式全体が BINARY の値として比較されるのです。

MySQL はテーブル生成時に何も断らずにCHAR または VARCHAR 型の フィールドを変更する事があります。 「7.7.1 暗黙のフィールド定義変更」節参照.

7.3.7.2 BLOBTEXT

BLOB は大きなバイナリ型のオブジェクトで、可変長のデータを保持できます。 4 つの BLOB 型、すなわち TINYBLOB, BLOB, MEDIUMBLOBLONGBLOB は保持できるデータの最大長が違うだけです。 「7.3.1 フィールドタイプの所要容量」節参照.

4 つの TEXT 型、すなわち TINYTEXT, TEXT, MEDIUMTEXTLONGTEXT は 4 つの BLOB 型に対応し、同じ最大長と 格納条件を持っています。 TEXTBLOB の違いは、 TEXT はケースに依存しないでソートと比較され、 BLOB はケースに依存して(文字コードで)比較されることだけです。 いうならば、TEXT は、ケースに依存しない BLOB です。

もし BLOBTEXT フィールドにそれらの最大長以上の値が与えられた場合、 その値はきっちり収まるように切り落とされます。

ほとんどの点で、TEXT フィールドを VARCHAR の大きい物と見なすことが出来ます。 同様に、BLOB フィールドは VARCHAR BINARY フィールドの大きくなった物です。 違いは、

MyODBCBLOBLONGVARBINARY として、 TEXTLONGVARCHAR として定義します。

BLOBTEXT フィールドは極端に長いので、それらを使用する際には、 いくつかの困った事にでくわすかもしれません:

それぞれの BLOB, TEXT フィールドは、一意のアロケートされたオブジェクトによって、 内部では表されることに注意してください.。 これはテーブルが開かれるときに一度だけアロケートされる他のフィールドとは対照的です。

7.3.7.3 ENUM

ENUM はストリングオブジェクトで、 その値は、通常、テーブル作成時のフィールド定義で列挙された値の中から選ばれます。

値はある状況下では 空文字 ("") か NULL を取ることがあります:

列挙されたそれぞれの値はインデックスを持ちます:

たとえば、フィールドが ENUM("one", "two", "three") と定義されたなら、 以下に示す値をとります。 それぞれのインデックス値も示します。

インデックス
NULL NULL
"" 0
"one" 1
"two" 2
"three" 3

列挙は最大 65535 個の要素まで可能です。

ENUM フィールドに値を与える場合は大文字小文字は無関係です。 しかし、後でフィールドから検索される値は、大文字小文字をもちます。 これはテーブル作成時に与えられたリストの値です。

もし ENUM を数値の文脈で検索した場合、そのメンバーを前から数えた 時の順番が数値で返ってきます。 もし ENUM に数値を代入しようとした場合、その数値の位置にある メンバーが代入されます。 (しかし、これは LOAD DATA では働きません。これはすべての入力を文字 列として扱います。)

ENUM 値は列挙メンバがフィールド指定にリストされた順に従ってソートさ れます。 (つまり、ENUM 値はインデックス値に従ってソートされます。) 例えば、ENUM("a", "b") ならば "a""b" の前にソートされ、 ENUM("b", "a") ならば "b""a" の前にソートされます。 空文字列は空ではない文字の前にソートされ、 NULL は他の列挙の前に並びます。

ENUM フィールドで指定可能な値のリストを全て取りたいならば、 次のようにします: SHOW COLUMNS FROM table_name LIKE enum_column_name そして二番目のフィールドの ENUM 定義を分析します。

7.3.7.4 SET

SET は文字型オブジェクトでゼロかそれ以上を値持ちます。 テーブル作成時には、それぞれの値はリストから選ばれるべきです。 SET 型のフィールドの値は、コンマ(`,') 区切りで並べられた複数のメンバーで構成されています。 これは、 SET メンバーの値中にコンマを含むことが出来ない、 ということです。

例えば、 SET("one", "two") NOT NULL と指定されたフィールドは以下の値をとります:

""
"one"
"two"
"one,two"

SET は最大 64 個の異なったメンバーがもてます。

MySQLSET の値を数値として代入します。代入された 値の最下位のビットが最初のメンバーに対応します。もし SET 値を 数値の文脈で検索した場合、検索される値はフィールドの値に対応します。 もしメンバーが SET フィールドに代入された場合、 二進数で表される数値が、メンバーの数値として決定されます。 SET("a","b","c","d") とフィールドが定義されたとします。 メンバーは以下の2進数の値を持ちます:

SET member 10進数 2進数値
a 1 0001
b 2 0010
c 4 0100
d 8 1000

もしこのフィールドに 9 を与えた場合、これは2進数で 1001 ですから、 1 番目と 4 番目の SET メンバーである "a""d" が 選択され、結果、 "a,d" となります。

1つ以上の SET 要素を含む値においては,あなたが値を挿入するとき,要素がどんな 順序で記載されているのかは重要ではありません. また,何回要素が与えられたのかは 重要ではありません. 後で値が検索されるとき, 値の中のそれぞれの要素は ただ一回だけ表れます。そのとき、テーブル作成時に与えられた順に要素は並びます。 例えば、フィールドが SET("a","b","c","d") と設定されていたなら、 "a,d", "d,a", "d,a,a,d,d" は検索されると "a,d" と なります。

SET 値は数値として代入されます。 NULL 値は非 NULL SET 値の前にソートされます。

通常、LIKEFIND_IN_SET() を使用して SET フィールド の SELECT を行います:

mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%';
mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;

しかし、以下も動作します:

mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';
mysql> SELECT * FROM tbl_name WHERE set_col & 1;

最初の文は完全一致するものを探します。 二つ目は第一番目のメンバーを含む値を探します。

もし SET フィールドで設定可能なすべてのメンバーを知りたい場合: SHOW COLUMNS FROM table_name LIKE set_column_name とし、 2番目にあらわされる SET 定義を分析します。

7.3.8 正しいフィールド型の選択

もっとも効率よく格納するには、全てにおいて一番正確な型を使用することです。 例えば、1-99999 の整数 には、MEDIUMINT UNSIGNED が最良の型です。

良くある問題は、貨幣の値の正確な表現です。MySQL では DECIMAL 型を使用すべきです。これは文字列として格納し、正確さのロ スは発生しません。正確さが重要でない場合は DOUBLE 型でも十分良い です。

高精度のため、常に BITINT に格納される固定小数点型に変換できます。 これは、全ての計算を整数で行なうようにし、結果だけを浮動小数点に変換して 戻します。

7.3.9 フィールドインデックス

MySQL の全てのフィールドはインデックスを持つことができます。 適切なフィールドでのインデックスの使用は、SELECT の 性能を向上する最良の方法です。

一つのテーブルには最大16個のインデックスが許されます。 インデックスの最大長は256バイトで、 これは MySQL コンパイル時に変更できます。

CHARVARCHAR フィールドには接頭部にインデックスを持つことができます。 フィールド全体をインデックス化するより、 これははるかに早く、少ないディスク容量でできます。

CREATE TABLE 構文でフィールドにインデックスを作るには、 以下のようにします:

KEY index_name (col_name(length))

以下の例は name フィールドの最初の10文字にインデックスを創り出します:

mysql> CREATE TABLE test (
          name CHAR(200) NOT NULL,
          KEY index_name (name(10)));

BLOBTEXT フィールドでは、そのフィールドの頭の部分に インデックスを張らなくてはなりません。 フィールドの全体にインデックスは張れません。

7.3.10 複数フィールドインデックス

MySQL は異なるフィールドのセットに一つのインデックスを持つことができます。 インデックスは最大15個のコラムまで許されます。 (CHARVARCHAR フィールドの接頭部をインデックスとして使用できます)

複数フィールドインデックスは、 ソートされた配列(インデックス化されたフィールドの値が結合されている配列)  を扱うことができます。

インデックス化されたコラムに対して、既知の値を WHERE 節で指定した時、 たとえ他のフィールドの値を指定しなくとも、 MySQL は複数フィールドインデックスを使用します。

以下のテーブルがあると仮定してください:

mysql> CREATE TABLE test (
           id INT NOT NULL,
           last_name CHAR(30) NOT NULL,
           first_name CHAR(30) NOT NULL,
           PRIMARY KEY (id),
           INDEX name (last_name,first_name));

name インデックスは、last_namefirst_name にまたがるインデックスです。 このインデックスは、last_name に対するクエリや、 name インデックスは以下のクエリで使われます:

mysql> SELECT * FROM test WHERE last_name="Widenius";

mysql> SELECT * FROM test WHERE last_name="Widenius"
                          AND first_name="Michael";

mysql> SELECT * FROM test WHERE last_name="Widenius"
                          AND (first_name="Michael" OR first_name="Monty");

mysql> SELECT * FROM test WHERE last_name="Widenius"
                          AND first_name >="M" AND first_name < "N";

しかし name インデックスは以下のクエリでは使用されません:

mysql> SELECT * FROM test WHERE first_name="Michael";

mysql> SELECT * FROM test WHERE last_name="Widenius"
            OR first_name="Michael";

MySQL がクエリの性能を上げるためにどうインデックスを使用しているか、 より詳しい情報はこちら: 「12.4 MySQL はどのようにインデックスを使用するか?」節.

7.3.11 他のデータベースエンジンのフィールド型の使用

ほかのベンダーからSQLを簡単に書けれるように、 MySQL は以下の表に しめすフィールド型をサポートします。これらは、テーブルの定義を、 他のデータベースエンジンから MySQL に簡単に移行させてくれます:

Other vendor type MySQL type
BINARY(NUM) CHAR(NUM) BINARY
CHAR VARYING(NUM) VARCHAR(NUM)
FLOAT4 FLOAT
FLOAT8 DOUBLE
INT1 TINYINT
INT2 SMALLINT
INT3 MEDIUMINT
INT4 INT
INT8 BIGINT
LONG VARBINARY MEDIUMBLOB
LONG VARCHAR MEDIUMTEXT
MIDDLEINT MEDIUMINT
VARBINARY(NUM) VARCHAR(NUM) BINARY

もし他のベンダーの型を使用してテーブルを作ろうとすると、 テーブル作成時のフィールドの型のマッピングが発生し、 DESCRIBE tbl_name 構文を発行します。 そして MySQL は、使用された型と等価な MySQL の型を用いて テーブルを構成したことを告げます。

7.4 SELECTWHERE 節で使用する関数

SQL ステートメント中の select_expression または where_definition は後述の関数を使用した任意の式からなります。

演算と関数を式の中で呼ぶ時、本ドキュメントに示しているもの以外の、 NULL を含む式は常に NULL 値を生成します

注意: 関数名とそれに続く語句の間には、空白はありません。 これは関数の呼び出しと、関数と同名のテーブル(かフィールド)の参照を、 MySQL パーサが区別するのを助けます。

次の例では、mysql プログラムの出力は短くなっています。つまり:

mysql> select MOD(29,9);
1 rows in set (0.00 sec)

+-----------+
| mod(29,9) |
+-----------+
|         2 |
+-----------+

これは次に変換されています:

mysql> select MOD(29,9);
        -> 2

7.4.1 グループ化関数

( ... )
丸かっこ。 式の評価の優先度を強制するために使用します。
mysql> select 1+2*3;
        -> 7
mysql> select (1+2)*3;
        -> 9

7.4.2 通常の算術演算

普通の算術演算が有効です。 -, +, * は、二つの引数が正数ならば BIGINT (64bit精度) で計算されることに注意してください!

+
足し算
mysql> select 3+5;
        -> 8
-
引き算
mysql> select 3-5;
        -> -2
*
掛け算
mysql> select 3*5;
        -> 15
mysql> select 18014398509481984*18014398509481984.0;
        -> 324518553658426726783156020576256.0
mysql> select 18014398509481984*18014398509481984;
        -> 0
最後の式の結果は不当です。なぜなら結果は 64 ビットを超えた整数だからです。
/
割り算。
mysql> select 3/5;
        -> 0.60
0 で割った場合、NULL になります。
mysql> select 102/(1-1);
        -> NULL
演算結果が整数になる場合にだけ、 BIGINT を用いて割り算は計算されます。

7.4.3 ビット関数

これらは最大 64 ビットの範囲を持ちます。MySQLBIGINT (64-bit) 演算を使用するためです。

|
ビット演算 OR
mysql> select 29 | 15;
        -> 31
&
ビット演算 AND
mysql> select 29 & 15;
        -> 13
<<
左に longlong (BIGINT) number 分、ビットをシフトします
mysql> select 1 << 2
        -> 4
>>
右に longlong (BIGINT) number 分、ビットをシフトします
mysql> select 4 >> 2
        -> 1
~
Invert all bits.
mysql> select 5 & ~1
        -> 4
BIT_COUNT(N)
引数 N がいくつビットを持っているか(2進数表記したときの1の数)
mysql> select BIT_COUNT(29);
        -> 4

7.4.4 論理演算

全ての論理関数は 1 (TRUE) or 0 (FALSE) を返します。

NOT
!
論理否定。引数が 0 なら 1 を返し、そうでなければ 0 を返します。 例外: NOT NULLNULL を返します.
mysql> select NOT 1;
        -> 0
mysql> select NOT NULL;
        -> NULL
mysql> select ! (1+1);
        -> 0
mysql> select ! 1+1;
        -> 1
最後の例は 1 を返します。なぜなら、式の評価が (!1)+1 と同じだからです。
OR
||
論理和。引数のどれかが 0 または NULL でなければ 1 を返します。
mysql> select 1 || 0;
        -> 1
mysql> select 0 || 0;
        -> 0
mysql> select 1 || NULL;
        -> 1

AND
&&
論理積。全ての引数が 0 または NULL でなければ 1 を返します。
mysql> select 1 && NULL;
        -> 0
mysql> select 1 && 0;
        -> 0

7.4.5 比較演算子

1 (TRUE), 0 (FALSE) または NULL を返します。 これらの関数は数値と文字列の両方で働きます。 必要ならば、文字は自動的に数字に変換され、数字は文字に変換されます。 (Perlがおこなっているみたいに)

MySQL は以下の規則で比較を行います:

文字列の比較は、ケースに依存せず、標準のキャラクターセットに従って 行われます。(ISO-8859-1 Latin1 がデフォルトです。これは English です)

以下は、比較のために文字が数値へ変換されている例です:

mysql> SELECT 1 > '6x';
         -> 0
mysql> SELECT 7 > '6x';
         -> 1
mysql> SELECT 0 > 'x6';
         -> 0
mysql> SELECT 0 = 'x6';
         -> 1
=
等しい
mysql> select 1 = 0;
        -> 0
mysql> select '0' = 0;
        -> 1
mysql> select '0.0' = 0;
        -> 1
mysql> select '0.01' = 0;
        -> 0
mysql> select '.01' = 0.01;
        -> 1
<>
!=
等しくない
mysql> select '.01' <> '0.01';
        -> 1
mysql> select .01 <> '0.01';
        -> 0
mysql> select 'zapp' <> 'zappp';
        -> 1
<=
より小さいか等しい
mysql> select 0.1 <= 2;
        -> 1
<
より小さい
mysql> select 2 <= 2;
        -> 1
>=
より大きいか等しい
mysql> select 2 >= 2;
        -> 1
>
より大きい
mysql> select 2 > 2;
        -> 0
<=>
等しい(NULL 安全)
mysql> select 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
        -> 1 1 0
IS NULL
IS NOT NULL
値が NULL とであるかどうかのテスト
mysql> select 1 IS NULL, 0 IS NULL, NULL IS NULL:
        -> 0 0 1
mysql> select 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
        -> 1 1 0
expr BETWEEN min AND max
もし exprmin 以上、 max 以下なら 1を返します。 そうでないなら 0 を返します。 これは 全ての引数が同じ型ならば、(min <= expr AND expr <= max) と同じです。 最初の引数 (expr) はいかのように比較方法を決定します。
mysql> select 1 BETWEEN 2 AND 3;
        -> 0
mysql> select 'b' BETWEEN 'a' AND 'c';
        -> 1
mysql> select 2 BETWEEN 2 AND '3';
        -> 1
mysql> select 2 BETWEEN 2 AND 'x-3';
        -> 0
expr IN (value,...)
もし exprIN リストにある値のどれかならば、1 を返します。 そうでなければ 0 を返します。 もし全ての値が定数なら、すべての値が expr の型に従って評価され、 ソートされます。この検索にはバイナリサーチが使用されます。 これは IN リストに定数を与えた場合、IN が速くなることを意味します。 もし expr がケース依存の文字式なら、ケース依存のやり方で比較されます。
mysql> select 2 IN (0,3,5,'wefwf');
        -> 0
mysql> select 'wefwf' IN (0,3,5,'wefwf');
        -> 1
expr NOT IN (value,...)
NOT (expr IN (value,...)) と同じ。
ISNULL(expr)
exprNULL なら 1 を、そうでなければ 0 を返します。
mysql> select ISNULL(1+1);
        -> 0
mysql> select ISNULL(1/0);
        -> 1
NULL の値を = を使用して比較した場合は常に偽(false) となることに 注意してください!
COALESCE(list)
list 中の、最初に現れた 非-NULL 要素を返します。
mysql> select COALESCE(NULL,1);
        -> 1
mysql> select COALESCE(NULL,NULL,NULL);
        -> NULL
INTERVAL(N,N1,N2,N3,...)
もし N < N1 なら 0 を返します。 もし N < N2 なら 1 を返します。 全ての引数は整数として扱われます。 これは N1 < N2 < N3 < ... < Nnを正しく動作させるために 必要なことです。これはバイナリ検索が使用されます(速いです)
mysql> select INTERVAL(23, 1, 15, 17, 30, 44, 200);
        -> 3
mysql> select INTERVAL(10, 1, 10, 100, 1000);
        -> 2
mysql> select INTERVAL(22, 23, 30, 44, 200);
        -> 0

7.4.6 文字列比較関数

通常、比較される表現がケース依存でない場合、比較はケース非依存で行われます。

expr LIKE pat [ESCAPE 'escape-char']
SQL の簡単な正規表現比較です。1 (TRUE) または 0 (FALSE) を返します。 LIKE には2つのワイルドカードがあります:
% 任意の数の文字(0文字も含む)に適合します。
_ 厳密に1つの文字に適合します。
mysql> select 'David!' LIKE 'David_';
        -> 1
mysql> select 'David!' LIKE '%D%v%';
        -> 1
ワイルドカード文字のテストをするためには、エスケープ文字より先行しておこなって ください。 ESCAPE を指定しない場合は、文字 '\' が使われます:
\% 1つの % に適合します。
\_ 1つの _ に適合します。
mysql> select 'David!' LIKE 'David\_';
        -> 0
mysql> select 'David_' LIKE 'David\_';
        -> 1
違うエスケープ文字を指定するには、 ESCAPE 節を使用します:
mysql> select 'David_' LIKE 'David|_' ESCAPE '|';
        -> 1
LIKE は数値表現でも許されます! (これは MySQL の、ANSI SQL LIKE に対する拡張です) 注意: MySQL は文字列中に C のエスケープ文字を使用しているので(e.g., `\n'), LIKE の指定文字列として使用するには `\' を 二倍しなくてはなりません。 例えば、 `\n' を探すには、`\\n' と 記述します。 `\' を探すには、 `\\\\' (バックスラッシュは、 一つはパーサーに取り除かれ、パターンマッチが行われる際にもうひとつ 取り除かれ、一致を探すために残った一つのバックスラッシュが使用されます)
expr NOT LIKE pat [ESCAPE 'escape-char']
NOT (expr LIKE pat [ESCAPE 'escape-char']) と同じ
mysql> select 10 LIKE '1%';
        -> 1
expr REGEXP pat
expr RLIKE pat
パターン pat に対し、文字式 expr のパターンマッチを行います。 パターン pat は正規表現の拡張が使用できます。 「I MySQL の正規表現の文法について」節参照. もし exprpat にマッチするなら 1 を返し、 でなければ 0 を返します。 RLIKEREGEXP と同義で、mSQL 互換を提供します。 注意: MySQL は C エスケープ構文を文字中に使用しており(\n)、 REGEXP 中で使用される '\' 文字はすべて、二重に書かなければ なりません。 MySQL 3.23.4 REGEXP は、普通の文字 (not binary) はケース非依存です。
mysql> select 'Monty!' REGEXP 'm%y%%';
        -> 0
mysql> select 'Monty!' REGEXP '.*';
        -> 1
mysql> select 'new*\n*line' REGEXP 'new\\*.\\*line';
        -> 1
mysql> select "a" REGEXP "A", "a" REGEXP BINARY "A";
        -> 1  0
REGEXP and RLIKE は、文字の型を決定する場合、 カレントのキャラクターセットを使用します。 (ISO-8859-1 Latin1 がデフォルト)
expr NOT REGEXP pat
expr NOT RLIKE pat
NOT (expr REGEXP pat) と同じ.
STRCMP(expr1,expr2)
文字列が同じなら 0 を返します。そうでなければ、最初の引数がソート順で小 さければ -1 を返します。そうでなければ 1 を返します。
mysql> select STRCMP('text', 'text2');
        -> -1
mysql> select STRCMP('text2', 'text');
        -> 1
mysql> select STRCMP('text', 'text');
        -> 0

7.4.7 Cast operators

BINARY
BINARY 演算子は、これ以降に続く文字をバイナリにキャストします。 これはたとえフィールドが BINARYBLOB 定義でなくても、 ケース依存でフィールドを比較することが出来る簡単な方法です。
mysql> select "a" = "A";
        -> 1
mysql> select BINARY "a" = "A";
        -> 0
BINARYMySQL 3.23.0 で登場しました。

7.4.8 フロー制御関数

IFNULL(expr1,expr2)
expr1NULL でない場合は expr1 を、そうでなければ expr2 を返します。 IFNULL() はどの文脈で使用されたかにより数値か文字を返します。
mysql> select IFNULL(1,0);
        -> 1
mysql> select IFNULL(0,10);
        -> 0
mysql> select IFNULL(1/0,10);
        -> 10
mysql> select IFNULL(1/0,'yes');
        -> 'yes'
NULLIF(expr1,expr2)
expr1 = expr2 が真なら、expr1 を返し、そうでなければ NULL を返します。
mysql> select NULLIF(1,1);
        -> 1
mysql> select NULLIF(1,2);
        -> NULL
注意: 引数が等しい場合、expr1MySQL では2回評価されます。
IF(expr1,expr2,expr3)
expr1 が真 (expr1 <> 0 and expr1 <> NULL) の場合 expr2 を返し、そうでなければ expr3 を返します。 IF() はどの文脈で使用されたかにより数値か文字を返します。
mysql> select IF(1>2,2,3);
        -> 3
mysql> select IF(1<2,'yes','no');
        -> 'yes'
mysql> select IF(strcmp('test','test1'),'no','yes');
        -> 'no'
expr1INTEGER として評価されます。これは浮動小数点を使用する場合、 比較演算も使用すべきであることを意味します。
mysql> select IF(0.1,1,0);
        -> 0
mysql> select IF(0.1<>0,1,0);
        -> 1
上の最初の例では、 IF(0.1)0 を返します。なぜなら 0.1 は 整数値として変換され IF(0) になり、それをもとにしたテスト結果が 返るからです。 これはあなたの期待に添わないかもしれません。 二番目の場合、 比較は、元の浮動小数点値が非ゼロかどうかテストします。 比較結果は整数として使用されます。 IF() のデフォルトの戻り値型(一時テーブルに格納される時に問題となり ます)は MySQL 3.23 では次のように計算されます:
expr2 または expr3 が文字列を返す 文字列
expr2 または expr3 が浮動小数点値を返す 浮動小数点
expr2 または expr3 が整数を返す 整数
CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...] [ELSE result] END
CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END
最初の式は value=compare-value ならば result を返します。 二つ目の式では、最初の条件[condition] が真ならば、 result を返します。 もしマッチする result の値がなければ、 ELSE 以下の result が返ります。 もし ELSE 部分がなければ、 NULL が返ります。
mysql> SELECT CASE 1 WHEN 1 THEN "one" WHEN 2 THEN "two" ELSE "more" END;
       -> "one"
mysql> SELECT CASE WHEN 1>0 THEN "true" ELSE "false" END;
       -> "true"
mysql> SELECT CASE BINARY "B" when "a" then 1 when "b" then 2 END;
       -> NULL

7.4.9 数学関数

すべての数学関数はエラーの場合 NULL を返します。

-
符号。引数の符号を変更します。
mysql> select - 2;
        -> -2
このオペレーターが BIGINT とともに使用された場合、 返り値は BIGINT であることに注意してください! これは -2^63 の値を 持つかもしれない整数を、 - で使用してはならないことを意味します!
ABS(X)
Returns the absolute value of X.
mysql> select ABS(2);
        -> 2
mysql> select ABS(-32);
        -> 32
この関数は BIGINT 値とともに使用されると安全です。
SIGN(X)
X が負数、ゼロ、整数によって、 -1, 0 or 1 を 返します。
mysql> select SIGN(-32);
        -> -1
mysql> select SIGN(0);
        -> 0
mysql> select SIGN(234);
        -> 1
MOD(N,M)
%
剰余 ( C の % 演算子のような ). NM で割ったときの余りが返ります。
mysql> select MOD(234, 10);
        -> 4
mysql> select 253 % 7;
        -> 1
mysql> select MOD(29,9);
        -> 2
この関数は BIGINT 値でも安全に使用できます。
FLOOR(X)
X より大きくならない整数のうち、最大の整数値を返します.
mysql> select FLOOR(1.23);
        -> 1
mysql> select FLOOR(-1.23);
        -> -2
返り値は BIGINT に変換されていることに注意!
CEILING(X)
X より小さくならない整数のうち、最小の整数値を返します.
mysql> select CEILING(1.23);
        -> 2
mysql> select CEILING(-1.23);
        -> -1
返り値は BIGINT に変換されていることに注意!
ROUND(X)
X を整数に丸めた値(四捨五入)を返します。
mysql> select ROUND(-1.23);
        -> -1
mysql> select ROUND(-1.58);
        -> -2
mysql> select ROUND(1.58);
        -> 2
返り値は BIGINT に変換されていることに注意!
ROUND(X,D)
XD で指定した少数桁に丸めた値(四捨五入)を返します。 もし D0 なら, 結果は小数点無しになるか 少数部分になるでしょう。
mysql> select ROUND(1.298, 0);
        -> 1
EXP(X)
指数関数 : e (自然対数の底) の X 乗。
mysql> select EXP(2);
        -> 7.389056
mysql> select EXP(-2);
        -> 0.135335
LOG(X)
自然対数 X
mysql> select LOG(2);
        -> 0.693147
mysql> select LOG(-2);
        -> NULL
If you want the log of a number X to some arbitary base B, use the formula LOG(X)/LOG(B).
LOG10(X)
常用対数(10を底とした対数) X
mysql> select LOG10(2);
        -> 0.301030
mysql> select LOG10(100);
        -> 2.000000
mysql> select LOG10(-100);
        -> NULL
POW(X,Y)
POWER(X,Y)
XY 乗。
mysql> select POW(2,2);
        -> 4.000000
mysql> select POW(2,-2);
        -> 0.250000
SQRT(X)
X の非負の平方根を返します。
mysql> select SQRT(4);
        -> 2.000000
mysql> select SQRT(20);
        -> 4.472136
PI()
π
mysql> select PI();
        -> 3.141593
COS(X)
コサイン XX はラジアン。
mysql> select COS(PI());
        -> -1.000000
SIN(X)
サイン XX はラジアン。
mysql> select SIN(PI());
        -> 0.000000
TAN(X)
タンジェント XX はラジアン。
mysql> select TAN(PI()+1);
        -> 1.557408
ACOS(X)
X のアークコサインを返します。これはコサインが X である値で す。X-1 から 1 の範囲にない場合は NULL を 返します。
mysql> select ACOS(1);
        -> 0.000000
mysql> select ACOS(1.0001);
        -> NULL
mysql> select ACOS(0);
        -> 1.570796
ASIN(X)
X のアークサインを返します。これはサインが X である値です。 X-1 から 1 の範囲にない場合は NULL を返し ます。
mysql> select ASIN(0.2);
        -> 0.201358
mysql> select ASIN('foo');
        -> 0.000000
ATAN(X)
X のアークタンジェントを返します。これはタンジェントが X で ある値です。
mysql> select ATAN(2);
        -> 1.107149
mysql> select ATAN(-2);
        -> -1.107149
ATAN2(X,Y)
2つの変数 XY のアークタンジェントを返します。両方の引数 の符号が結果の象限を決定するために使用されることを除いて、Y / X の アークタンジェントの計算と同様です。
mysql> select ATAN(-2,2);
        -> -0.785398
mysql> select ATAN(PI(),0);
        -> 1.570796
COT(X)
X のコタンジェントを返します。
mysql> select COT(12);
        -> -1.57267341
mysql> select COT(0);
        -> NULL
RAND()
RAND(N)
0 から 1.0 間のランダムな浮動小数点数値を返します。 もし N に整数を与えた場合、シードとしてこの値が使用されます。
mysql> select RAND();
        -> 0.5925
mysql> select RAND(20);
        -> 0.1811
mysql> select RAND(20);
        -> 0.1811
mysql> select RAND();
        -> 0.2079
mysql> select RAND();
        -> 0.7888
RAND() 値を持つフィールドは ORDER BY 節で使用できません。 ORDER BY はフィールドを複数回評価するためです。 しかし MySQL 3.23 では, 次が可能です: SELECT * FROM table_name ORDER BY RAND() これは SELECT * FROM table1,table2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000 のセットからランダムなサンプルを得るのに便利です。 注意: WHERE 節の RAND()WHERE が実行する度に再評価 されます。
LEAST(X,Y,...)
二つ以上の引数を取り、引数中、最小の値を返します。 引数は以下の規則に従って比較されます:
mysql> select LEAST(2,0);
        -> 0
mysql> select LEAST(34.0,3.0,5.0,767.0);
        -> 3.0
mysql> select LEAST("B","A","C");
        -> "A"
3.22.5 以前の MySQL では、MIN()LEAST の代わりに使用できます。
GREATEST(X,Y,...)
二つ以上の引数を取り、引数中、最大の値を返します。 引数は LEAST の時と同じように比較されます。
mysql> select GREATEST(2,0);
        -> 2
mysql> select GREATEST(34.0,3.0,5.0,767.0);
        -> 767.0
mysql> select GREATEST("B","A","C");
        -> "C"
3.22.5 以前の MySQL では、MAX()GREATEST の代わりに使用できます。
DEGREES(X)
引数 X をラジアンから度に変換して返します。
mysql> select DEGREES(PI());
        -> 180.000000
RADIANS(X)
引数 X を度からラジアンに変換して返します。
mysql> select RADIANS(90);
        -> 1.570796
TRUNCATE(X,D)
少数点以下 D 桁で X を切り捨てた値を返します。 D0 の場合、結果は小数部や微小部を持ちません。
mysql> select TRUNCATE(1.223,1);
        -> 1.2
mysql> select TRUNCATE(1.999,1);
        -> 1.9
mysql> select TRUNCATE(1.999,0);
        -> 1

7.4.10 文字列関数

サーバー側のパラメター max_allowed_packet よりも結果の長さが大きい場合、 文字列関数は NULL を返します。 「12.2.3 サーバーパラメーターのチューニング」節参照.

文字の位置を扱う関数においては、一番最初の位置は数字の 1 です。

ASCII(str)
str の左端の文字の ASCII コード値を返します。 str が空文字の場合は 0 を返します。 strNULL の場合は NULL を返します。
mysql> select ASCII('2');
        -> 50
mysql> select ASCII(2);
        -> 50
mysql> select ASCII('dx');
        -> 100
See also the ORD() function.
ORD(str)
文字列 str の左端の文字がマルチバイト文字の場合、文字のASCII コード値を次 の形式で返すことにより、マルチバイト文字のコードを返します: ((first byte ASCII code)*256+(second byte ASCII code))[*256+third byte ASCII code...]. 左端の文字がマルチバイト文字でない場合は、ASCII() 関数と同じ値を返 します。
mysql> select ORD('2');
        -> 50
CONV(N,from_base, to_base)
数字を、進数の違う数字に変換します。 数 Nfrom_base 進数から to_base 進数に 変換した場合の、文字表現を返します。 もし引数が NULL なら NULL を返します。 引数 N は整数として解釈されますが、整数か文字列で指定します。 最小の進数は 2 で、最大は 36 です。 to_base が負数なら、N は符号付きの数になります。 CONV は 64-bit 精度で動作します。
mysql> select CONV("a",16,2);
        -> '1010'
mysql> select CONV("6E",18,8);
        -> '172'
mysql> select CONV(-17,10,-18);
        -> '-H'
mysql> select CONV(10+"10"+'10'+0xa,10,10);
        -> '40'
BIN(N)
N を二進数にした値を返します。N は longlong 数値です。 これは CONV(N,10,2) と同じです。 NNULL なら NULL を返します.
mysql> select BIN(12);
        -> '1100'
OCT(N)
N の8進数値を表す文字列を返します。N は longlong 数値です。 これは CONV(N,10,8) と同じです。NNULL の場合は NULL を返します。
mysql> select OCT(12);
        -> '14'
HEX(N)
N の16進数値を表す文字列を返します。N は longlong(BIGINT) 数値です。これは CONV(N,10,16) と同じです。 NNULL の場合は NULL を返します。
mysql> select HEX(255);
        -> 'FF'
CHAR(N,...)
引数の ASCII コード値によって与えられた文字からなる文字列を返します。 NULL は飛ばされます。
mysql> select CHAR(77,121,83,81,'76');
        -> 'MySQL'
mysql> select CHAR(77,77.3,'77.3');
        -> 'MMM'
CONCAT(str1,str2,...)
引数を結合した結果を返します。引数が NULL なら NULL を返します. 2個以上の引数を必要とします。 数値の引数は等価の文字列形式に変換されます。
mysql> select CONCAT('My', 'S', 'QL');
        -> 'MySQL'
mysql> select CONCAT('My', NULL, 'QL');
        -> NULL
mysql> select CONCAT(14.3);
        -> '14.3'
CONCAT_WS(separator, str1, str2,...)
CONCAT_WS() は区切り文字つき CONCAT (CONCAT With Separator) を意味 し、CONCAT() の特殊な形式です。最初の引数は、残りの引数の区切り文字 です。区切り文字は残りの引数と同じような文字列です。区切り文字が NULL の場合、結果は NULL になります。関数は区切り文字より後 の NULL と空文字列を飛ばします。区切り文字は結合される文字列の間に 追加されます。
mysql> select CONCAT_WS(",","First name","Second name","Last Name");
       -> 'First name,Second name,Last Name'
mysql> select CONCAT_WS(",","First name",NULL,"Last Name");
       -> 'First name,Last Name'
LENGTH(str)
OCTET_LENGTH(str)
CHAR_LENGTH(str)
CHARACTER_LENGTH(str)
文字列 str の長さ。
mysql> select LENGTH('text');
        -> 4
mysql> select OCTET_LENGTH('text');
        -> 4
注意: CHAR_LENGTH() については、マルチバイト文字は一度だけしかカウ ントされません。
LOCATE(substr,str)
POSITION(substr IN str)
str 内にある substr 文字列の位置を返します。最初の位置は 1 です。 str 内に substr がない時は 0 を返します。
mysql> select LOCATE('bar', 'foobarbar');
        -> 4
mysql> select LOCATE('xbar', 'foobar');
        -> 0
この関数はマルチバイトでも安全です。
LOCATE(substr,str,pos)
文字列 str 中に最初に顕れた substr 文字の位置を返します。 pos は検索を開始する位置です。 strsubstr がなければ 0 を返します。
mysql> select LOCATE('bar', 'foobarbar',5);
        -> 7
この関数はマルチバイトでも安全です。
INSTR(str,substr)
文字列 str 内の最初の文字列 substr の位置を返します。 これは引数が入れ替わっていることをのぞいて、 2つの引数を与えた LOCATE と同じです。
mysql> select INSTR('foobarbar', 'bar');
        -> 4
mysql> select INSTR('xbar', 'foobar');
        -> 0
この関数はマルチバイトでも安全です。
LPAD(str,len,padstr)
str の長さが len になるまで文字列 str の始めに padstr を埋めます。
mysql> select LPAD('hi',4,'??');
        -> '??hi'
RPAD(str,len,padstr)
str の長さが len になるまで文字列 str の終わりに padstr を埋めます。
mysql> select RPAD('hi',5,'?');
        -> 'hi???'
LEFT(str,len)
文字列 str の最初から len 個の文字を得ます。
mysql> select LEFT('foobarbar', 5);
        -> 'fooba'
この関数はマルチバイトでも安全です。
RIGHT(str,len)
文字列 str の最後から len 個の文字を得ます。
mysql> select RIGHT('foobarbar', 4);
        -> 'rbar'
この関数はマルチバイトでも安全です。
SUBSTRING(str,pos,len)
SUBSTRING(str FROM pos FOR len)
MID(str,pos,len)
strpos 位置から len 文字数分の文字列を返します。 FROM の違いは ANSI SQL 92 構文です。
mysql> select SUBSTRING('Quadratically',5,6);
        -> 'ratica'
この関数はマルチバイトでも安全です。
SUBSTRING(str,pos)
SUBSTRING(str FROM pos)
文字列 str の 位置 pos 以降の文字を返します。
mysql> select SUBSTRING('Quadratically',5);
        -> 'ratically'
mysql> select SUBSTRING('foobarbar' FROM 4);
        -> 'rbar'
この関数はマルチバイトでも安全です。
SUBSTRING_INDEX(str,delim,count)
str から、区切り文字 delimcount 個現れた位置から前の 文字列を返します。count が正の場合は文字列は左から検索され、 count が負の場合は文字列は右から検索されます。
mysql> select SUBSTRING_INDEX('www.mysql.com', '.', 2);
        -> 'www.mysql'
mysql> select SUBSTRING_INDEX('www.mysql.com', '.', -2);
        -> 'mysql.com'
この関数はマルチバイトでも安全です。
LTRIM(str)
文字列 str の最初から空白文字を削除します。
mysql> select LTRIM('  barbar');
        -> 'barbar'
RTRIM(str)
文字列 str の最後から空白文字を削除します。
mysql> select RTRIM('barbar   ');
        -> 'barbar'
TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)
全ての remstr プレフィックスまたはサフィックスを str から削除した 文字列を返します。BOTH, LEADING そして TRAILING が 使用されない場合、BOTH が適用されます。remstr が与えられないと、 空白が削除されます。
mysql> select TRIM('  bar   ');
        -> 'bar'
mysql> select TRIM(LEADING 'x' FROM 'xxxbarxxx');
        -> 'barxxx'
mysql> select TRIM(BOTH 'x' FROM 'xxxbarxxx');
        -> 'bar'
mysql> select TRIM(TRAILING 'xyz' FROM 'barxxyz');
        -> 'barx'
この関数はマルチバイトでも安全です。
SOUNDEX(str)
str からの soundex 文字列を返します。発音が``大体同じ''2つの文字列 は同じ soundex 文字列を持ちます。``標準の'' soundex 文字列は4文字長ですが、 SOUNDEX() 関数は任意の長さの文字列を返します。SUBSTRING() を 結果に使用して、``標準の'' soundex 文字列を得ることができます。与えられた 文字列中の非アルファベット文字は無視されます。A-Z の半以外のすべての国際的 なアルファベット文字は母音とみなされます。
mysql> select SOUNDEX('Hello');
        -> 'H400'
mysql> select SOUNDEX('Quadratically');
        -> 'Q36324'
SPACE(N)
N 個の空白文字を返します。
mysql> select SPACE(6);
        -> '      '
REPLACE(str,from_str,to_str)
文字列 str 内の全ての文字列 from_strto_str に 置き換えます。
mysql> select REPLACE('www.mysql.com', 'w', 'Ww');
        -> 'WwWwWw.mysql.com'
この関数はマルチバイトでも安全です。
REPEAT(str,count)
strcount 回繰り返します。count <= 0 の場合は 空の文字列を返します。str または countNULL または、LENGTH(str)*count > max_allowed_packet の場合は NULL を返します。
mysql> select REPEAT('MySQL', 3);
        -> 'MySQLMySQLMySQL'
REVERSE(str)
文字列 str を反転します。
mysql> select REVERSE('abc');
        -> 'cba'
この関数はマルチバイトでも安全です。
INSERT(str,pos,len,newstr)
str 中の pos 位置から len 長の文字列を newstr で置き換えます。str 内の最初の位置は1です。
mysql> select INSERT('Quadratic', 3, 4, 'What');
        -> 'QuWhattic'
この関数はマルチバイトでも安全です。
ELT(N,str1,str2,str3...)
N = 1 なら str1 を、N = 2 なら str2 を返します。 N1 より小さい場合、または引数の数より大きい場合は NULL が返されます。 ELT()FIELD() の逆です。
mysql> select ELT(1, 'ej', 'Heja', 'hej', 'foo');
        -> 'ej'
mysql> select ELT(4, 'ej', 'Heja', 'hej', 'foo');
        -> 'foo'
FIELD(str,str1,str2,str3,...)
str1, str2, str3, ... リスト内の str のインデックスを 返します。str が見つからなければ 0 を返します。 FIELD()ELT() の逆です。
mysql> select FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
        -> 2
mysql> select FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
        -> 0
FIND_IN_SET(str,strlist)
strstrlist 中にあれば、値 1 から N を返します。 strlist は、それぞれの異なる値が ',' で分割された文字列です。最初の 引数が定数文字列で2番目が SET 型のフィールドの場合FIND_IN_SET は ビット演算を使用して最適化されます! strlist が空文字なら 0 を返します。 どちらかの引数が NULL なら NULL を返します. この関数は最初の引数が ',' を含んだ場合、うまく動かないでしょう。
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
        -> 2
MAKE_SET(bits,str1,str2,...)
bits に指定されたビットに対応する文字列のセットを返します。 (文字列が複数の場合、 `,' で区切られます) str1 が ビット 0 に対応し、str2 が ビット 1 に対応し、 str3 が ビット 2 に対応し... となります。 str1, str2, ... 中に含まれている NULL 文字は 結果には追加されません。
mysql> SELECT MAKE_SET(1,'a','b','c');
        -> 'a'
mysql> SELECT MAKE_SET(1 | 4,'hello','nice','world');
        -> 'hello,world'
mysql> SELECT MAKE_SET(0,'a','b','c');
        -> ''
EXPORT_SET(bits,on,off,[separator,[number_of_bits]])
'bits' に与えられた数値に対し、 全てのセットされているビットを 'on' で指定された文字で表し、 リセットされているビットを 'off' で指定された文字で表した文字列を返します。 それぞれの文字は 'separator' (デフォルト',') で示された文字で区切られ、 'number_of_bits' (default 64) に与えられた桁数だけのビットを表示します。
mysql> SELECT EXPORT_SET(5,'Y','N',',',4);
        -> Y,N,Y,N 
LCASE(str)
LOWER(str)
str を現在のキャラクターセットマッピング (デフォルト ISO-8859-1 Latin1) にしたがって小文字に変換します。 この関数はマルチバイトでも安全です。
mysql> select LCASE('QUADRATICALLY');
        -> 'quadratically'
UCASE(str)
UPPER(str)
str を現在のキャラクターセットマッピング (デフォルト ISO-8859-1 Latin1) にしたがって大文字に変換します。
mysql> select UCASE('Hej');
        -> 'HEJ'
この関数はマルチバイトでも安全です。
LOAD_FILE(file_name)
ファイルを読み込み、ファイルの中身を文字として返します。 ファイルは サーバー上になくてはならず、ファイルをフルパスで指定しなければなりません。 そして、 file 権限がなければなりません。 ファイルは全員に 読み込み可能でなければならず、そして、 max_allowed_packet より 小さいサイズでなければなりません。 このうちどれかの理由で、もしファイルが存在しないか読み込めない場合、 この関数は NULL を返します。
mysql> UPDATE table_name
           SET blob_column=LOAD_FILE("/tmp/picture")
           WHERE id=1;

MySQL は必要とあらば数値を文字列に変換します。 逆も同様に行います:

mysql> SELECT 1+"1";
       -> 2
mysql> SELECT concat(2,' test');
       -> '2 test'

明示的に数値を文字列に変換したければ、CONCAT() に引数として渡して下 さい。

文字列関数は引数としてバイナリ文字列が与えられると、結果の文字列もバイナリ 文字列になります。文字列に変換された数値はバイナリ文字列とみなされます。こ れは比較にだけ影響します。

7.4.11 日付と時刻関数

それぞれの型がもつ値の範囲と日と時間の値が記述される有効な形式については 「7.3.6 日付と時間の型」節.

日付関数を使用する例: date_col が最新の30日である全てのレコードを選択します:

mysql> SELECT something FROM table
           WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;
DAYOFWEEK(date)
date の曜日を得ます (1 = 日曜日, 2 = 月曜日, ... 7 = 土曜日) これは ODBC 標準に従います。
mysql> select DAYOFWEEK('1998-02-03');
        -> 3
WEEKDAY(date)
date の曜日を得ます (0 = 日曜日, 1 = 月曜日, ... 6 = 土曜日)
mysql> select WEEKDAY('1997-10-04 22:23:00');
        -> 5
mysql> select WEEKDAY('1997-11-05');
        -> 2
DAYOFMONTH(date)
月の日を返します (1 - 31)
mysql> select DAYOFMONTH('1998-02-03');
        -> 3
DAYOFYEAR(date)
年の日を返します (1-366)
mysql> select DAYOFYEAR('1998-02-03');
        -> 34
MONTH(date)
月を返します (1 - 12)
mysql> select MONTH('1998-02-03');
        -> 2
DAYNAME(date)
曜日の名前を返します。
mysql> select DAYNAME("1998-02-05");
        -> 'Thursday'
MONTHNAME(date)
月の名前を返します。
mysql> select MONTHNAME("1998-02-05");
        -> 'February'
QUARTER(date)
date についての年の四半期を返します。範囲は 1 から 4 です。
mysql> select QUARTER('98-04-01');
        -> 2
WEEK(date)
WEEK(date,first)
引数が一つの場合、date についての週を返します。範囲は 0 から 53 (そう、53週の最初というのもありえます)で、日曜日が週の 最初の日です。引数が二つの形式の WEEK() は、週の開始を日曜日か月曜 日か指定できます。第2引数が 0 の場合、週の開始は日曜日です。第2引数 が 1 の場合、週の開始は月曜日です。
mysql> select WEEK('1998-02-20');
        -> 7
mysql> select WEEK('1998-02-20',0);
        -> 7
mysql> select WEEK('1998-02-20',1);
        -> 8
mysql> select WEEK('1998-12-31',1);
        -> 53
YEAR(date)
年を返します (1000 - 9999).
mysql> select YEAR('98-02-03');
        -> 1998
YEARWEEK(date)
YEARWEEK(date,first)
データの年と週を返します。第2引数は WEEK() の第2引数とまったく同じ ように働きます。注意: 年の最初と最後の週では、年が date 引数内の年とは異な ることがあります!

mysql> select YEARWEEK('1987-01-01');
        -> 198653
HOUR(time)
時を返します (0 - 23)
mysql> select HOUR('10:05:03');
        -> 10
MINUTE(time)
分を返します (0-59)
mysql> select MINUTE('98-02-03 10:05:03');
        -> 5
SECOND(time)
秒を返します (0 to 59)
mysql> select SECOND('10:05:03');
        -> 3
PERIOD_ADD(P,N)
N 月を期間 P (型 YYMM または YYYYMM) に追加 します。YYYYMM を返します。 注意: 期間引数 P は日付値ではありません
mysql> select PERIOD_ADD(9801,2);
        -> 199803
PERIOD_DIFF(P1,P2)
期間 P1P2 の差の月を返します。P1P2 は形 式 YYMM または YYYYMM です。 注意: 期間引数 P1P2 は日付値ではありません
mysql> select PERIOD_DIFF(9802,199703);
        -> 11
DATE_ADD(date,INTERVAL expr type)
DATE_SUB(date,INTERVAL expr type)
ADDDATE(date,INTERVAL expr type)
SUBDATE(date,INTERVAL expr type)
これら関数は日付の演算に使用します。 これらは MySQL 3.22 の 新しい機能です。 ADDDATE()SUBDATE()DATE_ADD() , DATE_SUB() と同義です。 MySQL 3.23 では, +-DATE_ADD() , DATE_SUB() の代わりに使用できます. (See example) date には、DATETIMEDATE 型の値を指定します。 この値から演算が開始されます。 expr には、date から増減させる値を指定します。 expr`-' から始まっていれば、負数を示します。 type はどれぐらいの期間かを示すキーワードです。 EXTRACT(type FROM date) 関数は、date から 'type' の部分を返します。 以下の表に、typeexpr の関連を示します:
type 意味 expr のフォーマット
SECOND SECONDS
MINUTE MINUTES
HOUR 時間 HOURS
DAY DAYS
MONTH MONTHS
YEAR YEARS
MINUTE_SECOND 分と秒 "MINUTES:SECONDS"
HOUR_MINUTE 時間と分 "HOURS:MINUTES"
DAY_HOUR 日 と時間 "DAYS HOURS"
YEAR_MONTH 年 と月 "YEARS-MONTHS"
HOUR_SECOND 時間と分 "HOURS:MINUTES:SECONDS"
DAY_MINUTE 日、時、分 "DAYS HOURS:MINUTES"
DAY_SECOND 日、時、分、秒 "DAYS HOURS:MINUTES:SECONDS"
MySQL は、 expr フォーマット内のいかなる句読点区切りをも許します。 上の表中の区切り文字は提案する区切り文字です。 もし date 引数が DATE 値で、YEAR, MONTH, DAY の部分のみを含む 計算をするなら、結果は DATE 値が返ります。 それ以外なら DATETIME 値が 返ります。
mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
        -> 1998-01-01 00:00:00
mysql> SELECT INTERVAL 1 DAY + "1997-12-31";
        -> 1998-01-01
mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND;
       -> 1997-12-31 23:59:59 
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
                       INTERVAL 1 SECOND);
        -> 1998-01-01 00:00:00
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
                       INTERVAL 1 DAY);
        -> 1998-01-01 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
                       INTERVAL "1:1" MINUTE_SECOND);
        -> 1998-01-01 00:01:00
mysql> SELECT DATE_SUB("1998-01-01 00:00:00",
                       INTERVAL "1 1:1:1" DAY_SECOND);
        -> 1997-12-30 22:58:59
mysql> SELECT DATE_ADD("1998-01-01 00:00:00",
                       INTERVAL "-1 10" DAY_HOUR);
        -> 1997-12-30 14:00:00
mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
        -> 1997-12-02
mysql> SELECT EXTRACT(YEAR FROM "1999-07-02");
       -> 1999
mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
       -> 199907
mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
       -> 20102
もしあなたの指定する interval 値が短すぎるなら( type キーワードから 類推される値を含んでいない場合)、 MySQL は interval 値の一番 左の部分を指定し忘れたものだと仮定します。 例えば、もし typeDAY_SECOND に指定した場合、 expr の値は 日、時、分、秒 からなる物と期待されます。 ここであなたが "1:10" のような値を指定していたなら、 MySQL は、日、時 の部分が忘れ去られて、分、秒 が与えられたと 推定します。 つまり、 "1:10" DAY_SECOND"1:10" MINUTE_SECOND で あると理解されるのです。 これは、MySQLTIME 値を時刻ではなく経過時間の表現と解釈 する方法に類似しています。 もし、不正な値が使用されたなら、結果は NULL です. もし MONTHYEAR_MONTHYEAR を足し算して、 結果となる日付が新しい月の最大日よりも大きい日になるようなら、 その日は、新しい月の最大日に修正されます。
mysql> select DATE_ADD('1998-01-30',Interval 1 month);
        -> 1998-02-28
例のように、INTERVALtype キーワードは ケース依存ではありません。
TO_DAYS(date)
日付 date を与えると、0年からの日数を返します。
mysql> select TO_DAYS(950501);
        -> 728779
mysql> select TO_DAYS('1997-10-07');
        -> 729669
TO_DAYS() はグレゴリオ歴の開始(1582)より前の値での使用を意図されて いません。歴が変更された時に失われた日を考慮に入れてないからです。
FROM_DAYS(N)
Given a daynumber N, returns a DATE value.
mysql> select FROM_DAYS(729669);
        -> '1997-10-07'
FROM_DAYS() はグレゴリオ歴の開始(1582)より前の値での使用を意図され ていません。歴が変更された時に失われた日を考慮に入れてないからです。
DATE_FORMAT(date,format)
date 値を format 文字列に従って整形します。次の指定が format 文字列で使用できます:
%M 月名 (January..December)
%W 曜日 (Sunday..Saturday)
%D 英語サフィックス付き月の日 (1st, 2nd, 3rd, etc.)
%Y 4桁の年
%y 2桁の年
%X 週の年。週の最初の日は日曜日。4桁の数値。'%V' と共に使用されます
%x 週の年。週の最初の日は月曜日。4桁の数値。'%v' と共に使用されます
%a 省略された曜日名 (Sun..Sat)
%d 月の日, 数値 (00..31)
%e 月の日, 数値 (0..31)
%m 月, 数値 (01..12)
%c 月, 数値 (1..12)
%b 省略された月名 (Jan..Dec)
%j 年の日 (001..366)
%H 時 (00..23)
%k 時 (0..23)
%h 時 (01..12)
%I 時 (01..12)
%l 時 (1..12)
%i 分, 数値 (00..59)
%r 時刻, 12時間 (hh:mm:ss [AP]M)
%T 時刻, 24時間 (hh:mm:ss)
%S 秒 (00..59)
%s 秒 (00..59)
%p AM or PM
%w 週の日 (0=Sunday..6=Saturday)
%U 週 (0..53), 週のはじまりを 日曜とした場合
%u 週 (0..53), 週のはじまりを 月曜とした場合
%V 週 (1..53), 週のはじまりは日曜日。'%X' と共に使用されます
%v 週 (1..53), 週のはじまりは月曜日。'%x' と共に使用されます
%% リテラル `%'
他の全ての文字は解釈されずに結果にコピーされます。
mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
        -> 'Saturday October 1997'
mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
        -> '22:23:00'
mysql> select DATE_FORMAT('1997-10-04 22:23:00',
                          '%D %y %a %d %m %b %j');
        -> '4th 97 Sat 04 10 Oct 277'
mysql> select DATE_FORMAT('1997-10-04 22:23:00',
                          '%H %k %I %r %T %S %w');
        -> '22 22 10 10:23:00 PM 22:23:00 00 6'
mysql> select DATE_FORMAT('1999-01-01', '%X %V');
        -> '1998 52'
MySQL 3.23 では、 % 文字はフォーマット文字の前に必ず必要とされます。 それより前のバージョンでは、 % 文字はオプションでした。
TIME_FORMAT(time,format)
これは上記の DATE_FORMAT() のように使用されますが、 format オプションでは、時,分,秒だけを操作できます。 他のオプションは NULL or 0 を与えます。
CURDATE()
CURRENT_DATE
今日の日付を返します。日付の形式は、CURDATE() が数値または文字列のどち らの文脈で使用されたかに依存して YYYYMMDD または 'YYYY-MM-DD' で返されます。
mysql> select CURDATE();
        -> '1997-12-15'
mysql> select CURDATE() + 0;
        -> 19971215
CURTIME()
CURRENT_TIME
現在の時刻を HHMMSS または 'HH:MM:SS' の形式で返します。こ れは CURTIME() が数値または文字列のどちらの文脈で使用されたかに依 存します。
mysql> select CURTIME();
        -> '23:50:26'
mysql> select CURTIME() + 0;
        -> 235026
NOW()
SYSDATE()
CURRENT_TIMESTAMP
現在の時刻を返します。数値または文字列のどちらの文脈で使用されたかに依存して YYYYMMDDHHMMSS または 'YYYY-MM-DD HH:MM:SS' 形式で返されます。
mysql> select NOW();
        -> '1997-12-15 23:50:26'
mysql> select NOW() + 0;
        -> 19971215235026
UNIX_TIMESTAMP()
UNIX_TIMESTAMP(date)
引数なしで呼び出された場合は、UNIX timestamp (GMT '1970-01-01 00:00:00' か らの秒数) です。通常は、TIMESTAMP フィールドを引数として呼び出し、フィールドの 値を秒数で返します。date はローカル時刻での DATE 文字列、DATETIME 文字列、または YYMMDD または YYYYMMDD 形式の数値です。
mysql> select UNIX_TIMESTAMP();
        -> 882226357
mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00');
        -> 875996580
UNIX_TIMESTAMPTIMESTAMP フィールドに使用された場合、 この関数は、暗黙の ``文字から UNIX タイムスタンプ'' 変換をすることなく、 値を得ます。
FROM_UNIXTIME(Unix_timestamp)
文脈(数値/文字列)に依存して、'YYYY-MM-DD HH:MM:SS' または YYYYMMDDHHMMSS 形式の timestamp 文字列を返します。
mysql> select FROM_UNIXTIME(875996580);
        -> '1997-10-04 22:23:00'
mysql> select FROM_UNIXTIME(875996580) + 0;
        -> 19971004222300
FROM_UNIXTIME(unix_timestamp,format)
format に従って整形された Unix timestamp 文字列を返します。 formatDATE_FORMAT() 関数のエントリに一覧されたのと同じ指 定子を含むことができます。
mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(),
                            '%Y %D %M %h:%i:%s %x');
        -> '1997 23rd December 03:43:30 x'
SEC_TO_TIME(seconds)
seconds 引数を時分秒に変換して返します。関数が文字列文脈または数値 文脈のどちらで使用されたかに依存して、'HH:MM:SS' または HHMMSS 形式で値を返します。
mysql> select SEC_TO_TIME(2378);
        -> '00:39:38'
mysql> select SEC_TO_TIME(2378) + 0;
        -> 3938
TIME_TO_SEC(time)
time を秒に変換します。
mysql> select TIME_TO_SEC('22:23:00');
        -> 80580
mysql> select TIME_TO_SEC('00:39:38');
        -> 2378

7.4.12 その他の関数

DATABASE()
現在のデータベース名を返します。
mysql> select DATABASE();
        -> 'test'
もしデータベースが選択されていないなら、DATABASE() は空文字を返します。
USER()
SYSTEM_USER()
SESSION_USER()
現在の MySQL ユーザ名を返します。
mysql> select USER();
        -> 'davida@localhost'
MySQL 3.22.11 以降では、この関数はユーザー名とクライアントのホスト名を含みます。 ユーザー名の部分だけ取り出すには次のようにします。 (これはホスト名が含まれていなくとも動くでしょう):
ysql> select substring_index(USER(),"@",1);
        -> 'davida'
PASSWORD(str)
プレーンテキストのパスワード str からパスワード文字列を計算します。 これは user 許可テーブルの Password フィールドに、 暗号化された MySQL パスワードを保存する際に使用されます。
mysql> select PASSWORD('badpwd');
        -> '7f84554057dd964b'
PASSWORD() 暗号は不可逆です。 PASSWORD() は UNIX のパスワードが暗号化するのと同じ方法で 暗号化を行うわけではありません。 UNIX のパスワードと MySQL のパスワードが同じと思ってはいけません。 UNIX のパスワードファイルに保存される値が PASSWORD() が返すと 考えてはいけません。 ENCRYPT() 参照。
ENCRYPT(str[,salt])
UNIX の crypt() システムコールで str を暗号化します。 salt は2文字の文字列です。 (MySQL 3.22.16 で, salt は2文字以上許されるようになりました。)
mysql> select ENCRYPT("hello");
        -> 'VxuFAJXVARROc'
システムで crypt() が利用できない場合は ENCRYPT() は常に NULL を返します。 少なくともいくつかのシステムでは、 ENCRYPT()str 文字中の最初の 8 文字以外は全て無視します。 これは crypt() システムコールの振る舞いによって決定づけられます。
ENCODE(str,pass_str)
パスワードとして pass_str を用いて str を暗号化します。結果 を復号化するには、DECODE()を使用します。 結果はバイナリ文字列です。フィールドにそれを保存したい場合は BLOB フィールド型を使用してください。
DECODE(crypt_str,pass_str)
暗号化された文字列 crypt_str をパスワードとして pass_str を 用いて復号化します。crypt_strENCODE() から返された文字列 であるべきです。
MD5(string)
文字列を MD5 チェックサムした結果を返します。 値は 32 桁の 16進表示です。 例えばハッシュキーとして使用できるように。
mysql> select MD5("testing")
        -> 'ae2b1fca515949e5d54fb22b8ed95575'
これは "RSA Data Security, Inc. MD5 Message-Digest Algorithm".
LAST_INSERT_ID([expr])
最後に AUTO_INCREMENT フィールドに挿入されて自動的に生成された値を返します。 「22.4.29 mysql_insert_id()」節参照.
mysql> select LAST_INSERT_ID();
        -> 195
最後の作成された ID はそれぞれのコネクション毎にサーバーに維持されます。 これは他のクライアントからは変更できないでしょう。 もし他の非マジック値をもつ AUTO_INCREMENT フィールド (値が NULL でも 0 でもないということ) を更新しても、これは 変更されません。 もし UPDATE 節内の LAST_INSERT_ID() の引数に expr を指定すると、 引数の値は LAST_INSERT_ID() の値として返ります。 これは シーケンス番号のシミュレーションに使用できます: 最初にテーブルを作成:
mysql> create table sequence (id int not null);
mysql> insert into sequence values (0);
そして以下のようにしてシーケンス番号を生成:
mysql> UPDATE sequence SET id=last_insert_id(id+1);
LAST_INSERT_ID() の呼び出し無しでシーケンス番号を生成することが可能 ですが、この方法でこの関数を使用するユーティリティは、ID 値が最後に自動的 に生成された値としてサーバに管理されます。MySQL 内の通常の任意の AUTO_INCREMENT 値を読み込んで新しい ID を取り出すことができます。例 えば、LAST_INSERT_ID() (引数無し) は新しい ID を返します。C API 関 数 mysql_insert_id() もこの値を得るために使用できます。
FORMAT(X,D)
'#,###,###.##' のような形式(小数部 X 桁)で数値 D を整形 します。 もし D0 なら, 結果にはいかなる 小数点も小数部も含まれません。
mysql> select FORMAT(12332.123456, 4);
        -> '12,332.1235'
mysql> select FORMAT(12332.1,4);
        -> '12,332.1000'
mysql> select FORMAT(12332.2,0);
        -> '12,332'
VERSION()
MySQL サーバのバージョンを返します。
mysql> select VERSION();
        -> '3.23.13-log'
注意: バージョンが -log で終わる場合はロギングが有効であることを意 味します。
CONNECTION_ID()
接続の接続 ID (thread_id) を返します。すべての接続は接続自身の一意 な ID を持ちます。
mysql> select CONNECTION_ID();
        -> 1
GET_LOCK(str,timeout)
timeout 秒のタイムアウトで、str と名付けられたロックの獲得を試み ます。ロックを獲得した場合は 1, タイムアウトの場合は 0, エラーの場合(メ モリ不足やスレッドが mysqladmin kill で殺された場合など)は NULL が返ります。RELEASE_LOCK の実行、新しい GET_LOCK の実行、 スレッドの終了の場合に、ロックは解放されます。この関数はアプリケーション ロックやレコードロックのシミュレートのために使用できます。 これは、同じ名前のロックを行おうとする他のクライアントからのリクエストを ブロックします; 与えられた名前のロックに応じているクライアントは、 協調してロッキングを行うために、その文字列を使用できます。
mysql> select GET_LOCK("lock1",10);
        -> 1
mysql> select GET_LOCK("lock2",10);
        -> 1
mysql> select RELEASE_LOCK("lock2");
        -> 1
mysql> select RELEASE_LOCK("lock1");
        -> NULL
2つ目の RELEASE_LOCK()NULL を返します。 なぜなら、 "lock1" は、2つ目の GET_LOCK() の呼び出し時点で、 自動的に解放されるからです。
RELEASE_LOCK(str)
GET_LOCK で獲得したロック str を解放します。ロックが解 放された場合は 1, このスレッドによってロックされていない場合は 0 (この場合、ロックは解放されません), strが存在しない場合は NULL が返ります。 もし、 GET_LOCK() をコールして得られなかった場合、 あるいは、既に解放されている場合は、ロックは存在しないでしょう。
BENCHMARK(count,expr)
BENCHMARK() 関数は expr で与えられた文を count 回 繰り返し実行します。 これは MySQL のその文の処理がどれぐらい 速いのか知るのに使用されるでしょう。 結果は常に 0 です。 想定している使用は、 mysql クライアントです。 あるクエリの実行時間を知るための使用です。
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
+----------------------------------------------+
| BENCHMARK(1000000,encode("hello","goodbye")) |
+----------------------------------------------+
|                                            0 |
+----------------------------------------------+
1 row in set (4.74 sec)
報告された時間は、クライアントでの経過時間です。 サーバー側の CPU 時間では ありません。BENCHMARK() を何回か実行して、サーバマシンの負荷の重さ を考慮して結果を解釈することを勧めます。
INET_NTOA(expr)
数値表現に対するネットワークアドレス(4 または 8 バイト) を返します。
mysql> select INET_NTOA(3520061480);
       ->  "209.207.224.40"
INET_NTOA(expr)
ネットワークアドレスに対する数値を表す整数を返します。アドレスは 4 または 8 バイトアドレスです。
mysql> select INET_ATON("209.207.224.40");
       ->  3520061480

7.4.13 GROUP BY 節の関数

GROUP BY 節なしで グループ関数を使用するなら、 これは全てのレコードをグループ化することになります。

COUNT(expr)
SELECT 文によって得られるレコード 中、値が 非NULL で あるレコードの数を返します。
mysql> select student.student_name,COUNT(*)
           from student,course
           where student.student_id=course.student_id
           GROUP BY student_name;

検索されたレコードの数が、レコード中に NULL 値を含むかどうかで、 COUNT(*) で返る値ははいくぶん異なります。 もし SELECT が一つのテーブルから検索し、かつ、 他のフィールドが検索されることもなく、かつ WHERE 節が無いならば、 COUNT(*) は速く答えるために最適化されます。 例えば:
mysql> select COUNT(*) from student;
COUNT(DISTINCT expr,[expr...])
異なる値の数のカウントを返します。
mysql> select COUNT(DISTINCT results) from student;
MySQL では、式のリストを与えることで、別個の式の組合せの数を得る ことができます。ANSI SQL では、すべての式を CODE(DISTINCT ..) 内で 結合する必要があります。
AVG(expr)
exprの平均値。
mysql> select student_name, AVG(test_score)
           from student
           GROUP BY student_name;
MIN(expr)
MAX(expr)
expr.の最小/最大値。 min()max() が文字列引数を取ると、最小/最大の文字列値を返します。
mysql> select student_name, MIN(test_score), MAX(test_score)
           from student
           GROUP BY student_name;
SUM(expr)
exprの合計. 注意: 結果セットが何もレコードを返さない場合は、これは NULL を返します!
STD(expr)
STDDEV(expr)
expt の標準誘導(standard derivative)。これは ANSI SQL に対する拡張です。 この関数の STDDEV() 形式は、Oracle 互換のために提供されました。
BIT_OR(expr)
expr 内の全てのビットの論理 OR。64 ビット(BIGINT)の精 度で計算されます。
BIT_AND(expr)
expr 内の全てのビットの論理 AND。64 ビット(BIGINT)の 精度で計算されます。

MySQLGROUP BY を拡張しています。SELECT 表現内で GROUP BY 部に現れないフィールドまたは計算を使用できます。これは このグルー プのための全ての可能な値 を表しています。この使用により、必要ないフィールドで のソートとグループが避けられるので、高い性能が得られます。例えば、次のク エリでは customer.name でグループする必要はありません:

mysql> select order.custid,customer.name,max(payments)
       from order,customer
       where order.custid = customer.custid
       GROUP BY order.custid;

ANSI SQL では、GROUP BY 節に customer.name を追加する必要があります。 MySQL では、ANSI モードで実行していない場合は、name は冗長です。

GROUP BY 部から省略したフィールドがグループ内で一意でない場合は、こ の機能を使用しないでください!

いくつかのケースでは、それが一意でない場合でも、MIN()MAX() を特定のフィールド値を獲得するために使用することができます。 次は、sort フィールド内の最小の値を含むレコードからの column の値を与えます:

substr(MIN(concat(sort,space(6-length(sort)),column),7,length(column)))

注意: MySQL 3.22 (またはそれ以前) を使用している場合、または ANSI SQL に従おうとしている場合は、GROUP BYORDER BY 節で 式を使用できません。式の別名を使用することでこの制限を回避できます:

mysql> SELECT id,FLOOR(value/100) AS val FROM tbl_name
           GROUP BY id,val ORDER BY val;

MySQL 3.23 では次を行なうことができます:

mysql> SELECT id,FLOOR(value/100) FROM tbl_name ORDER BY RAND();

7.5 CREATE DATABASE構文

CREATE DATABASE [IF NOT EXISTS] db_name

CREATE DATABASE は与えられた名前のデータベースを作ります。データベースの名前として許される命名規則は、 「7.1.5 データベース名、テーブル名、インデックス名、フィールド名、エイリアス名」節に依ります。 もし、データベースがすでに存在しているにもかかわらず IF NOT EXISTS を 指定していなかったら、エラーが発生します。

MySQLにおけるデータベースは、データベース内のテーブルに相当するファイルを含むディレクトリとして実装されます。初期作成後はデータベース内にテーブルは存在せず、CREATE DATABASEステートメントは、MySQLデータディレクトリ下にディレクトリを作成するだけです。

mysqladminでもデータベースを作成することができます。 「14.1 様々な MySQL プログラムの概要」節参照.

7.6 DROP DATABASE構文

DROP DATABASE [IF EXISTS] db_name

DROP DATABASEは、データベース内の全てのテーブルと共にデータベースを破棄します。このコマンドの使用には万全の注意を払って下さい!

DROP DATABASEは、データベースディレクトリから削除されたファイルの数を返します。それぞれのテーブルは`.MYD'ファイル/`.MYI'ファイル/`.frm'ファイルに相当することから、通常この値はテーブルの3倍の数となります。

MySQL 3.22以降では、データベースが存在しないことに起因するエラーを防ぐために、キーワード IF EXISTS を使用することができます。

mysqladminでもデータベースを破棄することができます。 「14.1 様々な MySQL プログラムの概要」節参照.

7.7 CREATE TABLE構文

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]
[table_options] [select_statement]

create_definition:
  col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT]
            [PRIMARY KEY] [reference_definition]
  or    PRIMARY KEY (index_col_name,...)
  or    KEY [index_name] (index_col_name,...)
  or    INDEX [index_name] (index_col_name,...)
  or    UNIQUE [INDEX] [index_name] (index_col_name,...)
  or    [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name,...)
            [reference_definition]
  or    CHECK (expr)

type:
        TINYINT[(length)] [UNSIGNED] [ZEROFILL]
  or    SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
  or    MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
  or    INT[(length)] [UNSIGNED] [ZEROFILL]
  or    INTEGER[(length)] [UNSIGNED] [ZEROFILL]
  or    BIGINT[(length)] [UNSIGNED] [ZEROFILL]
  or    REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
  or    DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
  or    FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
  or    DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL]
  or    NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL]
  or    CHAR(length) [BINARY]
  or    VARCHAR(length) [BINARY]
  or    DATE
  or    TIME
  or    TIMESTAMP
  or    DATETIME
  or    TINYBLOB
  or    BLOB
  or    MEDIUMBLOB
  or    LONGBLOB
  or    TINYTEXT
  or    TEXT
  or    MEDIUMTEXT
  or    LONGTEXT
  or    ENUM(value1,value2,value3,...)
  or    SET(value1,value2,value3,...)

index_col_name:
        col_name [(length)]

reference_definition:
        REFERENCES tbl_name [(index_col_name,...)]
                   [MATCH FULL | MATCH PARTIAL]
                   [ON DELETE reference_option]
                   [ON UPDATE reference_option]

reference_option:
        RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

table_options:
	TYPE = {ISAM | MYISAM | HEAP}
or	AUTO_INCREMENT = #
or	AVG_ROW_LENGTH = #
or	CHECKSUM = {0 | 1}
or	COMMENT = "string"
or	MAX_ROWS = #
or	MIN_ROWS = #
or	PACK_KEYS = {0 | 1}
or	PASSWORD = "string"
or	DELAY_KEY_WRITE = {0 | 1}
or      ROW_FORMAT= { default | dynamic | static | compressed }
or     RAID_TYPE= {1 | STRIPED | RAID0 } RAID_CHUNKS=#  RAID_CHUNKSIZE=#;

select_statement:
	[IGNORE | REPLACE] SELECT ...  (Some legal select statement)

CREATE TABLEはカレントデータベースに、与えられた名前のテーブルを 作成します。テーブルの名前として許される命名規則は、 「7.1.5 データベース名、テーブル名、インデックス名、フィールド名、エイリアス名」節参照に 依ります。 カレントデータベースが無い場合や、テーブルが既に存在している場合はエラーが 発生します。

MySQL 3.22 以降ではテーブル名は db_name.tbl_name という形で与える事もできます。 これはカレントデータベースがあるかどうかにに関係なく動作します。

MySQL 3.23 では、テーブル作成時に TEMPORARY キーワードを使用することが できます。 一時テーブルは、もし、コネクションが落ちた場合、自動で消去されます。 一時テーブルの名前はそれぞれの接続ごとです。 これは、二つの違う接続で、同じ名前の一時テーブルを 衝突することなく、使用できるという事です。 さらには、既に存在するテーブルと同名であっても、一時テーブルは使用できます。 (一時テーブルが削除されるまで、実在するテーブルは隠されます)

MySQL 3.23 以降では、 IF NOT EXISTS キーワードを使用できます。 これは、もしテーブルが既に存在していた場合、エラーを発生させません。 テーブルの構造が一意かどうかまでは検査しないことに注意。

それぞれのテーブルは、データベースディレクトリにおける以下の複数の ファイルで表されます。これは MyISAM 型 のテーブル場合:

ファイル 目的
tbl_name.frm テーブル定義(書式)ファイル
tbl_name.MYD データファイル
tbl_name.MYI インデックスファイル

フィールドに対する種々の型属性の詳細は、 「7.3 フィールド型」節を参照のこと。

7.7.1 暗黙のフィールド定義変更

いくつかのケースにおいてMySQLは、CREATE TABLEステートメントで与えられたフィールド定義を暗黙の内に変更します (これは ALTER TABLE で起きるかもしれません)

もし MySQL がフィールドの型をあなたが指定したものと違うものにしたかどうかを 知りたい場合、テーブルの作成、alter 後に、 DESCRIBE tbl_name 構文 を発行します。

myisampackを使用してテーブルを圧縮した場合、別のフィールド定義変更がある程度起こることがあります。 「8.1.2.3 Compressed table characteristics」節参照.

7.8 ALTER TABLE構文

ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...]

alter_specification:
        ADD [COLUMN] create_definition [FIRST | AFTER column_name ]
  or    ADD [COLUMN] (create_definition, create_definition,...)
  or    ADD INDEX [index_name] (index_col_name,...)
  or    ADD PRIMARY KEY (index_col_name,...)
  or    ADD UNIQUE [index_name] (index_col_name,...)
  or    ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
  or    CHANGE [COLUMN] old_col_name create_definition
  or    MODIFY [COLUMN] create_definition
  or    DROP [COLUMN] col_name
  or    DROP PRIMARY KEY
  or    DROP INDEX index_name
  or    RENAME [AS] new_tbl_name
  or    table_options

ALTER TABLEは、既存のテーブルの構造変更を可能にします。 例えば、フィールドの追加や削除、インデックスの作成や破棄、既存のフィールド属性の変更、及びフィールドやテーブルそのものの名前の変更です。 また、テーブルのコメントやテーブルの型式を変更することも可能です。 「7.7 CREATE TABLE構文」節参照.

もし ALTER TABLE でフィールド定義を変えても DESCRIBE tbl_name が フィールドを変更していないと示すなら、これは MySQL が 「7.7.1 暗黙のフィールド定義変更」節. に述べている理由の一つで変更していない可能性が あります。 例えば、 VARCHAR フィールドを CHAR にしようとすると, MySQL はそのテーブルに他の可変長のフィールドがあるかぎり、 VARCHAR のままにしようとします。

ALTER TABLEはオリジナルのテーブルの一時的なコピーを作成することにより動作します。 コピーへの変更作業が完了すると、オリジナルのテーブルは削除され新しく作られた方の名前が変更されます。これは全ての変更が自動的に新しいテーブルに対して実施されることにより、誤った変更無しに完了します。ALTER TABLEが実行されている間、オリジナルのテーブルは他のクライアントから読みだしが可能です。このテーブルへの更新や書き込みは、新しいテーブルが準備完了となるまで遅らされます。

以下は、ALTER TABLEの使用例を表す例です。 次に示すように作成されたテーブルt1から始めます:

mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));

テーブルt1の名前をt2に変更するには:

mysql> ALTER TABLE t1 RENAME t2;

フィールド aINTEGER から TINYINT NOT NULL に (名前は同じままで)変更し、 bCHAR(10) から CHAR(20) に変更しつつ、 名前を b から cに変更するには:

mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);

TIMESTAMPを追加し、名前をdとするには:

mysql> ALTER TABLE t2 ADD d TIMESTAMP;

フィールドdにインデックスを追加し、フィールドaをプライマリ・キーとするには:

mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);

フィールドcを削除するには:

mysql> ALTER TABLE t2 DROP COLUMN c;

c という名前の NULL を許可しない AUTO_INCREMENT 整数 フィールドを追加し、作成するには:

mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
           ADD INDEX (c);

ここで我々が c をインデックス指定したのは、 AUTO_INCREMENT フィールドは インデックスであるべきだからで、 cNOT NULL 指定しているのは インデックスフィールドは NULL にできないからです。

AUTO_INCREMENT フィールドを追加した場合、フィールドの値は 自動的にシーケンス番号で埋められます。

See also 「20.19 Problems with ALTER TABLE.」節参照.

7.9 DROP TABLE構文

DROP TABLE [IF EXISTS] tbl_name [, tbl_name,...]

DROP TABLEは、1つ又は1つ以上のテーブルを破棄します。テーブルの全てのデータとテーブル定義は破棄されますので、このコマンドの使用は慎重に行ってください!

MySQL 3.22以降では、テーブルが存在しないことに起因するエラーを防ぐために、キーワード IF EXISTS を使用することができます。

7.10 OPTIMIZE TABLE構文

OPTIMIZE TABLE tbl_name

OPTIMZE TABLEは、テーブルの大部分を削除したり、可変長となっているテーブル(VARCHARBLOBもしくはTEXTフィールドを持つテーブル)に多くの変更を加えた場合に使用すべきです。 削除されたレコードはリンクリストで維持され、次のINSERT操作は、古いレコード位置を再利用します。 未使用領域を再生するためにOPTIMIZE TABLEを使用することができます。

OPTIMIZE TABLEは、オリジナルのテーブルの一時的なコピーを作成することにより動作します。 古いテーブルは新しいテーブルに(未使用レコードを除いて)コピーされ、 元のテーブルが削除されてから新しいテーブルの名前が変更されます。 OPTIMIZE TABLEが実行されている間、オリジナルのテーブルは他のクライアントから読みだしが可能です。 このテーブルへの更新や書き込みは、新しいテーブルが準備完了となるまで遅らされます。 これは全ての変更が自動的に新しいテーブルに対して実施されることにより、誤った変更無しに完了します。

7.11 CHECK TABLE 構文

CHECK TABLE tbl_name[,tbl_name...] [TYPE = QUICK]

テーブルのエラーをチェックします。このコマンドは次のフィールドを持つテーブ ルを返します:

Table テーブル名
Op 常に 'check'
Msg_type status, error, info, warning の一つ。
Msg_text メッセージ。

注意: チェックされた各テーブルに対する情報の多くのレコードが得られます。最 後の1レコードは Msg_type status になり、通常は OK であるべ きです。OK が得られない場合は、テーブルの修復を通常通り実行すべきで す。 「15.1 テーブルのメンテナンス、クラッシュからの修復のための myisamchk 使用」節参照。

TYPE=QUICK が与えられた場合は、MySQL は固定長レコードテー ブルのレコードを走査しません。

CHECK TABLEMyISAM テーブルだけで動作し、テーブルに対する myisamchk -m table_name の実行と同じことです。

7.12 REPAIR TABLE 構文

REPAIR TABLE tbl_name[,tbl_name...] [TYPE = QUICK]

REPAIR TABLEMyISAM テーブルだけで動作します。テーブルに myisamchk -r table_name を実行することと同じです。

壊れたテーブルを修復します。コマンドは次のフィールドを含むテーブルを返しま す:

Table テーブル名
Op 常に 'repair'
Msg_type status, error, info, warning のどれか
Msg_text メッセージ

注意: 修復された各テーブルの情報の多くのレコードを得ることがあります。最後 の1レコードは Msg_type status になり、通常は OK であるべき です。OK が得られなければ、myisamchk -o でテーブルの修復を試 みるべきです。REPAIR TABLE はまだ myisamchk のすべてのオプショ ンを実装していないためです。近い将来、我々はこれをより柔軟にする予定です。

If TYPE=QUICK is given then MySQL will try to do a REPAIR of only the index tree.

7.13 DELETE構文

DELETE [LOW_PRIORITY] FROM tbl_name
    [WHERE where_definition] [LIMIT rows]

DELETEは、tbl_nameより、where_definitionにて与えられた条件を満たすレコードを削除し、削除されたレコード数を返します。

WHERE節を指定することなしにDELETEを発行した場合、全てのレコードが削除されます。 MySQLは、これを空テーブルを再作成することで実現しており、これは、全てのレコードを実際に削除するよりもかなり早く動作します。 この場合DELETEは、影響のあったレコード数として0を返します。 (再作成は、元のデータが格納されているファイルをオープンすることなく実施されますから、MySQLは実際に削除されたレコード数を返すことができません。 たとえデータファイルやインデックスファイルが乱されたとしても、テーブル定義ファイル`tbl_name.frm'が有効である限り、このような方法でテーブルの再作成が可能となります。)

もし全てのレコードを削除している時に、いくつのレコードが消され、いくつのレコードが スピードを犠牲にしているのか、本当に知りたいならば、 DELETE 構文を以下のように使用します:

mysql> DELETE FROM tbl_name WHERE 1>0;

これは DELETE FROM tbl_nameWHERE 節なしで行うよりも、 とても遅いです。なぜなら一度で消そうとするからです。

キーワードLOW_PRIORITYを指定した場合、そのテーブルを読んでいるクライアントがいなくなるまでDELETEの実行は遅らせられます。

削除されたレコードはリンクリストで維持され、次のINSERT操作は、古いレコード位置を再利用します。 ファイルをより小さくしたい場合は、OPTIMIZE TABLEステートメントかテーブルの再編成のためにmyisamchkユティリティを使用してください。 OPTIMIZE TABLEの方が簡単ですが、myisamchkの方が早く動作します。 「7.10 OPTIMIZE TABLE構文」節参照, と 「15.6.3 テーブルの最適化」節.

MySQL-特化 DELETELIMIT rows オプションは サーバーに消す最大のレコード数をつげます。これは DELETE コマンドが あまりに多くの時間を取らないために使用されます。 LIMIT 値よりも affected row の数が少なくなるまで、 単純に DELETE コマンドを繰り返すだけです。

7.14 SELECT構文

SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
       [HIGH_PRIORITY]
       [DISTINCT | DISTINCTROW | ALL]
    select_expression,...
    [INTO {OUTFILE | DUMPFILE} 'file_name' export_options]
    [FROM table_references
        [WHERE where_definition]
        [GROUP BY {unsigned_integer | col_name | formula}]
        [HAVING where_definition]
        [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] ,...]
        [LIMIT [offset,] rows]
        [PROCEDURE procedure_name] ]

SELECTは通常、1つまたは1つ以上のテーブルからレコードを検索して抽出するのに使用されます。 select_expression は取り出したいフィールドを示します。 SELECTはまた、テーブルの参照なしに計算によって求められたレコードを取り出すために使用されます。例:

mysql> SELECT 1 + 1;
         -> 2

全てのキーワードの使用は、上記に示すような順序で正確に与えられる必要があります。例えば、HAVING節は必ずGROUP BY節の後、ORDER BY節の前でなければなりません。

INTO OUTFILE の代わりに INTO DUMPFILE を使用すると、 MySQL はファイルに1レコードだけを書きます。フィールドや行の終端 とすべてのエスケープを含みません。これはファイル内に BLOB を格納したい場合 に便利です。

7.15 JOIN 構文

MySQLは、以下に示すSELECTステートメントにおけるJOIN構文をサポートします:

table_reference, table_reference
table_reference [CROSS] JOIN table_reference
table_reference INNER JOIN table_reference
table_reference STRAIGHT_JOIN table_reference
table_reference LEFT [OUTER] JOIN table_reference ON conditional_expr
table_reference LEFT [OUTER] JOIN table_reference USING (column_list)
table_reference NATURAL LEFT [OUTER] JOIN table_reference
{ oj table_reference LEFT OUTER JOIN table_reference ON conditional_expr }

Where table_reference is defined as

table_name [[AS] alias] [USE INDEX (key_list)] [IGNORE INDEX (key_list)]

上に示す最後のLEFT OUTER JOIN構文は、ODBCとの互換性のためだけに存在します。

例:

mysql> select * from table1,table2 where table1.id=table2.id;
mysql> select * from table1 LEFT JOIN table2 ON table1.id=table2.id;
mysql> select * from table1 LEFT JOIN table2 USING (id);
mysql> select * from table1 LEFT JOIN table2 ON table1.id=table2.id
           LEFT JOIN table3 ON table2.id=table3.id;
mysql> select * from table1 USE INDEX (key1,key2) WHERE key1=1 and key2=2 AND
       key3=3;
mysql> select * from table1 IGNORE INDEX (key3) WHERE key1=1 and key2=2 AND
       key3=3;

12.5.4 MySQL はどのように LEFT JOIN を最適化するか?」節参照.

7.16 INSERT構文

    INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name [(col_name,...)]
        VALUES (expression,...),(...),...
or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name [(col_name,...)]
        SELECT ...
or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name
        SET col_name=expression, col_name=expression, ...

INSERTは、既存のテーブルに新しいレコードを挿入します。 INSERT ... VALUES書式は、値の明示指定を基本としてレコードを挿入します。 INSERT ... SELECT書式は、他の表(複数可)から抽出したレコードを挿入します。 複数の値リストを用いるINSERT ... VALUES書式は、MySQL 3.22.5以降でサポートされています。 col_name=expression構文は、MySQL 3.22.10以降でサポートされています。

tbl_nameは、レコードを挿入するテーブルです。フィールド名リストは、後続の値定義ステートメントのフィールドを指し示します。

多重の値リストを持つ INSERT ... SELECT ... 又は INSERT ... VALUES() ステートメントを使用する場合、クエリーに関する情報を得るために C API関数 mysql_info() を使用することができます。 その情報の書式は以下に示す文字列のようになります:

Records: 100 Duplicates: 0 Warnings: 0

Duplicatesは、既に存在するユニークインデックスの値と重複することにより、挿入できなかったレコード数を表します。 Warningsは、挿入されたフィールドが何らかの疑わしい値であったという数を表します。警告は、次のような条件の下で発生します:

INSERT 構文の DELAYED オプションは MySQL 独自の オプションで、これは INSERT が完全に終了することを待てない クライアントを持つ場合に、とても役立ちます。 これは、ロギングのために MySQL を使用する時の一般的な問題で、完了 に長い時間がかかる SELECT ステートメントも定期的に実行できます。 DELAYEDMySQL 3.22.15 で導入されました。 これは ANSI SQL92 に対する MySQL 拡張です。

INSERT DELAYED を使用する時、クライアントは一度 ok となり、テーブル が他のスレッドで使用中でない時にレコードが挿入されます。

INSERT DELAYED を使用して得られるほかの利益は、 多くのクライアントからの insert が同時に束ねられ、一つのブロックで 書かれることです。 これは多くの別々の insert を実行するより とても速くなります。

現在、キューイングされたレコードは、それらがテーブルに代入されるまで メモリーに保持されているだけです。 これは、もし mysqld を 強引な方法 (kill -9) でキルしたり、 mysqld が予期せず 死んだ場合、キューイングされているレコードはディスクに書かれず失われます!

DELAYED オプションを INSERTREPLACE で使用する場合、 以下のことがおきます。 ここで ``スレッド'' とは INSERT DELAYED コマンドを受けたスレッドをさし、 ``ハンドラー'' とは特定のテーブルのための全ての INSERT DELAYED 構文を操作するスレッドを指します。

注意: INSERT DELAYED は、テーブルが使用中でない場合、通常の INSERT よりも遅くなります。INSERT DELAYED を使用する各テーブルにつ いて別のスレッドを操作するサーバの、追加のオーバーヘッドもあります。これは、 確実にそれを必要とする時にだけ INSERT DELAYED を使用すべきことを意 味します!

7.17 REPLACE構文

    REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tbl_name [(col_name,...)]
        VALUES (expression,...)
or  REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tbl_name [(col_name,...)]
        SELECT ...
or  REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tbl_name
          SET col_name=expression, col_name=expression,...

REPLACEは、テーブル中の古いレコードがユニークインデックス上の 新しいレコードと同じ値を持つ場合に、新しいレコードを挿入する前に、 古いレコードを削除するということを除けば、INSERTと全く同じように 動作します。 「7.16 INSERT構文」節参照.

7.18 LOAD DATA INFILE構文

LOAD DATA [LOW_PRIORITY] [LOCAL] INFILE 'file_name.txt' [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [FIELDS
        [TERMINATED BY '\t']
        [OPTIONALLY] ENCLOSED BY '']
        [ESCAPED BY '\\' ]]
    [LINES TERMINATED BY '\n']
    [IGNORE number LINES]
    [(col_name,...)]

LOAD DATA INFILEステートメントは、テキストファイルからテーブルへと、 レコードを高速に読み込みます。 LOCAL キーワードが指定されれば、ファイルは クライアント・ホストから読み込まれます。 LOCALが指定されなければ、ファイルはサーバに位置する必要があります (LOCALは、MySQL 3.22.6以降で利用できます)。

セキュリティ上の理由から、サーバからテキストファイルを読み出す時は、 ファイルがデータベースディレクトリに存在するか、 全てに読み込み権限がある必要があります。 また、サーバファイルで LOAD DATA INFILE を使用するには、 データベースの file 権限も持たなければなりません。 「6.6 MySQL が提供する権限」節参照.

もし LOW_PRIORITY を指定した場合、LOAD DATA 構文は そのテーブルから他のクライアントが読み込みを行っている間、 遅らされます。

LOCAL 使用をすると、クライアント・ホストからサーバ・ホストへ ファイルの内容が転送される分、多少遅くなるでしょう。 いうならば、ローカルのファイルを読み込むのに、 file 権限は必要ないということです。

mysqlimportユティリティは、データファイルの読み込みに使用することができます。; これは、サーバにLOAD DATA INFILEコマンドを送信することによって処理を実現しています。 --localオプションは、mysqlimportに、クライアント・ホストからデータファイルを読み込ませます。 クライアントとサーバが圧縮プロトコルをサポートしていれば、低速なネットワークでより良いパフォーマンスを得るために、--compressオプションを指定することができます。

サーバ・ホストにファイルを置く場合、サーバは、以下のルールを使用します:

これらのルールは、ファイルが `myfile.txt' のように与えられれば データベースディレクトリからファイルが読み出され、 `./myfile.txt' のように与えられれば、現在選択しているデータベースのデータディレクトリから ファイルが読み出されるという意味であることに注意して下さい。

例えば、以下の LOAD DATA 文は、`data.txt' ファイルを db1 データベースディレクトリから読みます。 なぜなら、db1 は 現在選択されているデータベースだからです。 たとえ、db2 データベース のテーブルに、ファイルから読み込んだデータを挿入するとしても。:

以下に示すような構文では、ファイルは db1 データベースディレクトリ から読まれます。db2 ではありません:

mysql> USE db1;
mysql> LOAD DATA INFILE "data.txt" INTO TABLE db2.my_table; 

REPLACEIGNORE キーワードは、すでに存在するユニークキーに 重複しているレコードの入力に対する制御です。 REPLACE 指定の場合、同じユニークキーを持つ既存のレコードは新しいレコードで 置き換えられます。 IGNORE 指定の場合、既存のレコードのユニークキーと重複するキーをもつ新しいレコードは 飛ばされます。 もし、どちらも指定しなかった場合、重複したキーが見つかった場合 エラーが発生し、テキストファイルは無視されます。

LOCAL キーワードを使用してデータをローカルからロードする場合、 サーバーは操作の途中で転送をとめる方法を知りません。 それでデフォルトの動作としては IGNORE が指定されたのと 同じになります。

LOAD DATA INFILEは、SELECT ... INTO OUTFILEの逆です。 「7.14 SELECT構文」節参照. データベースからファイルへデータを書き込むには、SELECT ... INTO OUTFILEを使用します。 ファイルからデータベースに読み戻すには、LOAD DATA INFILEを使用します。 FIELDSLINES節の構文は両方のコマンドとも同じです。 どちらの節もオプションですが、両方を指定する場合は、FIELDSは、LINESより先に指定しなければなりません。

FIELDS節を指定した場合、その段落(TERMINATED BY[OPTIONALLY] ENCLOSED BY及びESCAPED BY)は、少なくとも1つを指定しなければならないことを除いて、それらもまたオプションとなります。

FIELDS節を指定しなかった場合、初期値は以下のように記述したのと等価となります:

FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'

LINES節を指定しなかった場合、初期値は以下のように記述したのと等価となります:

LINES TERMINATED BY '\n'

言い換えると、LOAD DATA INFILE の初期値は、出力へ書き込む際に以下のように振舞います:

逆に、LOAD DATA INFILEの初期値は、入力を読み込む際に以下のように振舞います:

FIELDS ESCAPED BY '\\'と書いた場合、単一のバックスラッシュとして読み出される値とするために、2つのバックスラッシュを指定しなければならないことに注意して下さい。

IGNORE number LINES オプションはファイルの先頭にあるレコードを無視するのに 使用されます:

mysql> LOAD DATA INFILE "/tmp/file_name" into table test IGNORE 1 LINES;

データベースからファイルへデータを書き、それから後でそのファイルからデータベースへデータを読み戻すために、SELECT ... INTO OUTFILEと対にLOAD DATA INFILEを使う場合、双方のフィールドとレコードの取扱いに関するオプションは、一致しなければなりません。さもなければ、LOAD DATA INFILEは適切にファイルを処理しないでしょう。 フィールドをコンマで区切ってファイルへ書き出すために、SELECT ... INTO OUTFILEを使用するとすれば:

mysql> SELECT * FROM table1 INTO OUTFILE 'data.txt'
           FIELDS TERMINATED BY ','
           FROM ...

コンマ区切りファイルから読み戻すため、正しいステートメントはこうなるでしょう:

mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2
           FIELDS TERMINATED BY ',';

その代わりとして次に示すようなステートメントでファイルを読み込もうとしても、正しく動作しないでしょう。なぜなら、これは、LOAD DATA INFILEに対してフィールドの間にタブを探すよう指示するからです:

mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2
           FIELDS TERMINATED BY '\t';

おそらく、それぞれの入力行は単一のフィールドとして処理されるでしょう。

LOAD DATA INFILEは外部ソースからもファイルを読み出すことができます。 例えば、dBASEフォーマットのファイルは、フィールドをコンマで区切られ、ダブルクォーテーションで囲まれています。 レコードが改行文字で区切られているとしたら、次に示すフィールド及びレコードの取扱オプションを指定したコマンドが、このようなファイルを読み込むのに使用できます。

mysql> LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
           FIELDS TERMINATED BY ',' ENCLOSED BY '"'
           LINES TERMINATED BY '\n';

いくつかのフィールド及びレコードの取扱オプションに、空文字列('')を指定することがあります。空でないなら、FIELDS [OPTIONALLY] ENCLOSED BYFIELDS ESCAPED BYの値は単一の文字でなければなりません。FIELDS TERMINATED BYLINES TERMINATED BYは2つ以上の文字となるでしょう。例えば、リターン文字と改行文字のペアで区切られたレコードを書き込んだり、このようなレコードを含んだファイルを読み込んだりするには、LINES TERMINATED BY '\r\n'節を指定します。

FIELDS [OPTIONALLY] ENCLOSED BYは、フィールドの引用符を制御します。出力の際(SELECT ... INTO OUTFILE)、OPTIONALLY語を省いたなら、全てのフィールドはENCLOSED BY文字で囲まれます。このような出力(フィールド区切りにコンマを使用)の例を次に示します:

"1","a string","100.20"
"2","a string containing a , comma","102.20"
"3","a string containing a \" quote","102.20"
"4","a string containing a \", quote and comma","102.20"

OPTIONALLYを指定すれば、ENCLOSED BY文字は、 CHARフィールドとVARCHARフィールドのみ囲むのに使用されます:

1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a \" quote",102.20
4,"a string containing a \", quote and comma",102.20

フィールド値の中におけるENCLOSED BY文字の出現は、ESCAPED BY文字をその前に置くことによりエスケープされることに注意して下さい。ESCAPED BY値に空を指定すると、LOAD DATA INFILEにより正しく読み込めない出力を生成するでしょう。例えば、このようにエスケープ文字を空にした場合、以下に示すような出力となります。4行目の2つ目のフィールドに、(誤って)フィールドを区切るかのようなクォートに続くコンマを含んでいることに注視して下さい:

1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a " quote",102.20
4,"a string containing a ", quote and comma",102.20

入力において、ENCLOSED BY文字が指定されており、それがフィールド値の両端に現れた場合、その文字は取り去られます。(これは、OPTIONALLYが指定されたかどうかに拘らず、当てはまります;OPTIONALLYは入力解析には効果がありません。) ESCAPED BY文字を前置きされたENCLOSED BY文字の出現は、現在のフィールド値の一部として処理されます。具体的には、あるフィールドがそれ自身、たENCLOSED BY文字で始まっている場合、フィールドらの内部で発生する2重のENCLOSED BY文字は、単一のENCLOSED BY文字として処理されます。 例えば、ENCLOSED BY '"'が指定されると、引用符は以下のように操作されます:

"The ""BIG"" boss"  -> The "BIG" boss
The "BIG" boss      -> The "BIG" boss
The ""BIG"" boss    -> The ""BIG"" boss

FIELDS ESCAPED BYは、特殊文字をどのように書き込んだり読み込んだりするかを制御します。 FIELDS ESCAPED BY文字が空でない場合、出力において次のような文字(文字列)のプリフィックスに使用されます:

FIELDS ESCAPED BY文字が空であれば、どの文字もエスケープされません。 特に、フィールド値が上に示した文字を含んでいるならば、エスケープ文字に空を指定するのはあまり良い考えとは言えないでしょう。

入力において、FIELDS ESCAPED BY文字が空でない場合、この文字の出現は取り去られ、後続の文字はフィールド値の一部としてそのまま受け取られます。 例外は、エスケープされた`0'`N'です(例えば、エスケープ文字が`\'である時の\0\N)。 これらのシーケンスは、ASCII 0('ゼロ値'バイト) 、NULLとして処理されます。NULL操作の規則は下を参照して下さい。

`\'-escape syntaxに関するこれ以外の情報は、 「7.1 リテラル:文字列と数値をどのように書くか?」節参照。

フィールドとレコード操作オプションが確実に相互作用する事例:

FIELDSLINESオプションによるNULL値の多様な取扱い:

キーワードREPLACEIGNOREは、ユニーク・キー値が重複するレコードが存在する入力レコードの取扱いを制御します。 REPLACEを指定した場合、同じユニーク・キー値を持つ新しいレコードは、既に存在する同じユニーク・キーであるレコードを置き換えます。 IGNOREを指定した場合、既に存在するレコードのユニーク・キー値と重複する入力レコードは、スキップされます。 いずれのオプションも指定していない場合、重複キーが発見された時点でエラーが発生し、テキストファイルの残りは無視されます。

LOAD DATA INFILEでサポートされないケース:

次の例は、persondataテーブルの全てのフィールドを読み込みます:

mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;

フィールドリストが指定されていませんから、LOAD DATA INFILEは、入力レコードがテーブルのそれぞれのフィールドを含むものと想定します。 FIELDSLINESの初期値が使用されます。

テーブルの一部のフィールドのみ読み込みたい場合、フィールドリストを指定します:

mysql> LOAD DATA INFILE 'persondata.txt'
           INTO TABLE persondata (col1,col2,...);

テーブル内のフィールド順と入力ファイルのフィールド順が異なる場合にも、MySQLにテーブルのフィールドと入力フィールドの対応を教えるために、フィールドリストを指定しなければなりません。

入力レコードのフィールド数の方が少ない場合、入力フィールド値が与えられないフィールドは、初期値が設定されます。 初期値の割当てについては、 「7.7 CREATE TABLE構文」節. で述べられています。

空のフィールド値は変換されます:

TIMESTAMP フィールドは、フィールド値に NULL 値が指定されていた場合もしくは、 フィールドリストが指定されている時に TIMESTAMP フィールドがそのリストから除外されていた場合 (最初のTIMESTAMPフィールドのみ)、現在時刻が設定されるだけです。

入力レコードのフィールド数の方が多い場合、余分なフィールドは無視され、警告の数が増やされます。

LOAD DATA INFILEは全ての入力を文字列と文字列とみなすことから、INSERTステートメントでできるようなENUMフィールドやSETフィールドへの数値の指定はできません。全てのENUM及びSET値は文字列として与えられなければいけません!

LOAD DATA INFILEクエリの終了時、クエリの情報を得るためにC API関数mysql_info()を使用することができます。情報の書式は以下に示すようなものです:

Records: 1  Deleted: 0  Skipped: 0  Warnings: 0

LOAD DATA INFILE が、入力レコードのフィールド数の過不足があった時にも 警告を引き起こす事を除けば、INSERT ステートメント ( 「7.16 INSERT構文」節参照. ) により値が挿入される時に 警告が発生するのと同じ状況下で、警告が発生します。 警告はどこにも保存されません; 警告の数は全てうまくいった場合にだけ 使用できます。 もし警告を知りたい、その警告の理由を知りたいのなら、 一つ方法があります。 SELECT ... INTO OUTFILE を使用して 他のファイルに落とし、オリジナルのファイルと比べます。

INSERTと比較したLOAD DATA INFILEの効率やLOAD DATA INFILEの高速化についてのより詳しい情報は、 「12.5.6 INSERT クエリの速度」節参照を参照のこと。

7.19 UPDATE 構文

UPDATE [LOW_PRIORITY] [IGNORE] tbl_name SET col_name1=expr1,col_name2=expr2,...
    [WHERE where_definition] [LIMIT #]

UPDATE はテーブルに存在するレコードのフィールドを、新しい値に更新します。 SET 節はどのフィールドをどういった値にすべきかを示します。 WHERE 節が与えられた場合、更新すべきレコードを特定することになります。 それ以外は、全てのレコードを更新します。

LOW_PRIORITY キーワードを指定した場合、UPDATE の実行は、 テーブルを読んでいるクライアントがなくなるまで、遅らされます。

IGNORE キーワードを指定した場合は、update ステートメントは、 update 中に二重キーのエラーを得たとしても、異常終了しません。

表記中の tbl_name からのフィールドをアクセスすると、UPDATE は現在のフィールド値を使用します。例えば、次のステートメントは age フィールドにその現在値より1大きい値を設定します:

mysql> UPDATE persondata SET age=age+1;

UPDATE は左から右に評価されます。例えば、以下の文は age フィールドを 2倍にし、そのあと1増やします:

mysql> UPDATE persondata SET age=age*2, age=age+1;

もしフィールドに現在もっている値を指定した場合、MySQL はそれを通知し、 値は更新しません。

UPDATE は変更されたレコード数を返します。 MySQL 3.22 以上では、C API 関数 mysql_info() が マッチし更新されたレコード数を返します。また UPDATE 中に起きた ワーニングの数も返します。

MySQL 3.23 では、 LIMIT # で指定した数だけレコードを変更 できます。

7.20 USE 構文

USE db_name

USE db_name 構文は、 MySQLdb_name データベースを この後のクエリのデフォルトのデータベースにするように指示します。 指定されたデータベースは、セッションの最後まで、あるいは、他の USE 構文 が発行されるまで残ります:

mysql> USE db1;
mysql> SELECT count(*) FROM mytable;      # selects from db1.mytable
mysql> USE db2;
mysql> SELECT count(*) FROM mytable;      # selects from db2.mytable

USE 構文で特定のデータベースをカレントにしても、 他のデータベースのテーブルからアクセスすることを妨げません。 以下は db1 データベースの author テーブルと、 db2 データベースの editor テーブルにアクセスする例です:

mysql> USE db1;
mysql> SELECT author_name,editor_name FROM author,db2.editor
           WHERE author.editor_id = db2.editor.editor_id;

USE 構文は Sybase の互換のために提供されています。

7.21 FLUSH 構文 (キャッシュのクリア)

FLUSH flush_option [,flush_option]

FLUSH コマンドで MySQL が使用している内部キャッシュの いくつかをきれいに消すことができます。 FLUSH を実行するには、 reload 権限がなければなりません。

flush_option には以下の内一つが指定できます:

HOSTS ホストキャッシュテーブルを空にします。あなたのホストの IP アドレスを変えたり、Host ... is blocked というエラーメッセージが 出る場合はホストテーブルキャッシュを一度空にしなくてはなりません。 (指定したホストに対して max_connect_errors 以上の接続エラーが出る場合、 MySQL は何か起きたと 推定し、そのホストからのいかなる接続要求も拒否します。ホストテーブルキャッシュの消去は、 再び接続を許すようにします。 「20.2.3 Host '...' is blocked エラー」節参照.) mysqld-O max_connection_errors=999999999 開始し、このエラーメッセージを 回避できます
LOGS 標準のログファイルと更新ログファイルを 一度閉じて再び開きます。 もし更新ログファイルを拡張子無しで指定している場合、新しい更新ログファイルの 拡張子の番号は、一つ前のファイルより 1 増やした数になります。 ファイル名に拡張を使用した場合、MySQL は更新ログファイルを閉じて開きます。 「21.3 更新ログ」節参照.
PRIVILEGES mysql データベースの許可テーブルから、 権限情報を再読込します。
TABLES 全ての開いているテーブルを閉じます。
STATUS ほとんどのステータス変数を 0 にします。

上に示したコマンドは、mysqladmin を使用しても実行できます。 mysqladmin の引数はそれぞれ、 flush-hosts, flush-logs, reload, flush-tables と なります。

FLUSH コマンドを実行するには、reload 権限がなければなりません。

7.22 KILL 構文

KILL thread_id

thread_id には、mysqld に接続して走っているスレッドの ID を 空白で区切って指定します。 SHOW PROCESSLIST コマンドで走っているスレッドを知ることができ、 KILL thread_id コマンドでスレッドを KILL できます。

もし process 権限があるなら、全てのスレッドを確認し、KILL 出来ます。 そうでなければ、自分のスレッドだけを、 確認し、KILL する事ができます。

mysqladmin processlistmysqladmin kill をスレッドの 検査と KILL に使用できます。

7.23 SHOW 構文 (テーブルやフィールドなどについての情報を得る)

   SHOW DATABASES [LIKE wild]
or SHOW TABLES [FROM db_name] [LIKE wild]
or SHOW COLUMNS FROM tbl_name [FROM db_name] [LIKE wild]
or SHOW INDEX FROM tbl_name [FROM db_name]
or SHOW STATUS [LIKE wild]
or SHOW VARIABLES [LIKE wild]
or SHOW [FULL] PROCESSLIST
or SHOW TABLE STATUS [FROM db_name] [LIKE wild]
or SHOW GRANTS FOR user

SHOW はデータベース、テーブル、フィールド、サーバーについての情報を与えます。 LIKE wild が使用された場合、wild 文字列は通常の SQL ワイルドカード (`%'`_') です。

tbl_name FROM db_name の代わりに、db_name.tbl_name が使用できます。 これら二つは同じです:

mysql> SHOW INDEX FROM mytable FROM mydb;
mysql> SHOW INDEX FROM mydb.mytable;

SHOW DATABASESMySQL サーバー上のデータベースを示します。 mysqlshow コマンドでも同じ情報が得られます。

SHOW TABLES は指定されたデータベースのテーブルを一覧表示します。 mysqlshow db_name コマンドでも同じ情報が得られます。

NOTE: もしユーザーにテーブルに対する権限が無い場合、 テーブルは SHOW TABLESmysqlshow db_name の要求で 表示されません。

SHOW COLUMNS は与えられたテーブルのフィールドを表示します。 もしそのフィールドの型が、あなたが CREATE TABLE 構文実行時に与えたものと 違う場合は、 MySQL は、フィールドの型をときおり変更することが あることに注意してください。 「7.7.1 暗黙のフィールド定義変更」節参照.

DESCRIBE 文は SHOW COLUMNS と似たような情報を提供します。 「7.25 DESCRIBE 構文 (フィールドについての情報を得る)」節参照.

SHOW TABLE STATUS (バージョン 3.23 の新機能) は SHOW STATUS のようですが、それぞれのテーブルについてより多くの情報を提供します。 mysqlshow --status db_name コマンドを実行しても同じものが得られます。 以下の項目が返ってきます:

項目 意味
Name テーブル名
Type テーブルの種類 (BDB, ISAM, MyISAM or HEAP)
Row_format レコードの保存形式 (Fixed, Dynamic, or Compressed)
Rows レコード数
Avg_row_length レコードの平均長
Data_length データファイルの大きさ
Max_data_length データファイルの最大値
Index_length インデックスファイルの大きさ
Data_free 割り当てられたが使用されていないバイト数
Auto_increment 次の autoincrement 値
Create_time テーブル作成時刻
Update_time 一番最後に更新された時刻
Check_time 一番最後にチェックされた時刻
Create_options CREATE TABLE で使用された拡張オプション
Comment テーブル作成時につけられたコメント (あるいは、なぜこのテーブルにMySQL がアクセスできないかのいくつかの情報).

SHOW FIELDSSHOW COLUMNS の別名として使用され、 SHOW KEYSSHOW INDEX の別名として使用されます。 テーブルのフィールドやインデックスは mysqlshow db_name tbl_namemysqlshow -k db_name tbl_name でも見れます。

SHOW INDEX は ODBC でいう SQLStatistics に近い形式で、インデックスの情報を表示します。 以下の項目が返ります:

項目 意味
Table テーブル名
Non_unique インデックスが重複を含まないなら 0
Key_name インデックス名
Seq_in_index インデックスの項目番号。1 から始まります。
Column_name フィールド名。
Collation いかにこのフィールドがインデックス中でソートされるか. MySQL では, これは A (Ascending) か NULL (Not sorted) になります。
Cardinality インデックス中のユニークな値の数。 これは isamchk -a の実行で更新されます。
Sub_part もしこのフィールドがインデックスに一部分だけ使用している場合、そのインデックスに使用しているキャラクター数をしめす。 もしキー全体がインデックスされているなら NULL

SHOW STATUSmysqladmin extended-status と同様に、サーバからのステー タス情報を与えます。出力は次とは異なるかもしれません:

+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| Aborted_clients          | 0      |
| Aborted_connects         | 0      |
| Connections              | 17     |
| Created_tmp_tables       | 0      |
| Delayed_insert_threads   | 0      |
| Delayed_writes           | 0      |
| Delayed_errors           | 0      |
| Flush_commands           | 2      |
| Handler_delete           | 2      |
| Handler_read_first       | 0      |
| Handler_read_key         | 1      |
| Handler_read_next        | 0      |
| Handler_read_rnd         | 35     |
| Handler_update           | 0      |
| Handler_write            | 2      |
| Key_blocks_used          | 0      |
| Key_read_requests        | 0      |
| Key_reads                | 0      |
| Key_write_requests       | 0      |
| Key_writes               | 0      |
| Max_used_connections     | 1      |
| Not_flushed_key_blocks   | 0      |
| Not_flushed_delayed_rows | 0      |
| Open_tables              | 1      |
| Open_files               | 2      |
| Open_streams             | 0      |
| Opened_tables            | 11     |
| Questions                | 14     |
| Slow_launch_threads      | 0      |
| Slow_queries             | 0      |
| Threads_connected        | 1      |
| Threads_running          | 1      |
| Uptime                   | 149111 |
+--------------------------+--------+

上に示したステータス変数は以下に示すの意味を持ちます:

Aborted_clients クライアントが接続を閉じる前に死んでしまったために中断されたコネクション数。
Aborted_connects MySQL サーバーに接続を試みて失敗した数
Bytes_received クライアントから受信したバイト数
Bytes_sent クライアントに送信したバイト数
Cached_threads スレッドキャッシュ内のスレッド数
Connections MySQL サーバーに接続を試みた数
Created_tmp_tables ステートメント実行中に暗黙のうちに作成された一時テーブルの数
Delayed_insert_threads 使用中の delayed insert ハンドラースレッドの数
Delayed_writes INSERT DELAYED で書かれたレコード数
Delayed_errors INSERT DELAYED で書かれたレコードでなんらかのエラーのあったレコード数 (たぶん duplicate key).
Flush_commands FLUSH コマンドの実行回数
Handler_delete テーブルからレコードを削除するためのリクエスト数
Handler_read_first テーブル中の最初のレコードを読むためのリクエスト数。
Handler_read_key キーに基づいてレコードを読むためのリクエスト数。
Handler_read_next キー順で次のレコードを読むためのリクエスト数。
Handler_read_rnd 固定位置に基づいてレコードを読むためのリクエスト数。
Handler_read_rnd_next データファイルの次のレコードを読む要求の数。 多くのテーブルスキャンを行なう場合、これは高くなります - 通常、これはテー ブルが正しくインデックスされていないか、存在するインデックスを有利に使うよ うにクエリが書かれていないことを示唆します。
Handler_update テーブルのレコードを更新するための要求数
Handler_write テーブルにレコードを挿入するためのリクエスト数
Key_blocks_used キーキャッシュ中で使用されたブロック数
Key_read_requests キャッシュからキーブロックを読み込んだリクエスト数
Key_reads Disk から物理的にキーブロックを読んだ回数
Key_write_requests キャッシュにキーブロックを書き込んだリクエスト数
Key_writes Diskに物理的にキーブロックを書き込んだ回数
Max_used_connections 最大同時接続数
Not_flushed_key_blocks キーキャッシュ中にあるキーブロックで、変更されたもののいまだDiskに書き出されていないキーブロック数
Not_flushed_delayed_rows INSERT DELAY クエリで書き出しを待っているレコード数
Open_tables オープンされているテーブル数
Open_files オープンされているファイル数
Open_streams 開いているストリーム数 (主にログに使用される)
Opened_tables オープンされたテーブル数
Questions サーバーに送られたクエリの数
Slow_launch_threads 接続に slow_launch_time 以上を要したスレッド数
Slow_queries long_query_time 以上に時間のかかったクエリの数
Threads_connected 現在開いている接続数
Threads_running スリープしていないスレッドの数
Uptime サーバーが走っている秒数

上についてのいくつかコメント:

SHOW VARIABLESMySQL システム変数のいくつかの値を示します。 mysqlshow variables コマンドでも同じ情報が得られます。 もし標準値が適さないなら、ほとんどの変数を mysqld 起動時に コマンドラインのオプションとして与えることにより、変更できます。 出力は以下のようになりますが、フォーマットや数はいくぶん違うでしょう:

+------------------------+--------------------------+
| Variable_name          | Value                    |
+------------------------+--------------------------+
| back_log               | 5                        |
| connect_timeout        | 5                        |
| basedir                | /my/monty/               |
| datadir                | /my/monty/data/          |
| delayed_insert_limit   | 100                      |
| delayed_insert_timeout | 300                      |
| delayed_queue_size     | 1000                     |
| join_buffer_size       | 131072                   |
| flush_time             | 0                        |
| interactive_timeout    | 28800                    |
| key_buffer_size        | 1048540                  |
| language               | /my/monty/share/english/ |
| log                    | OFF                      |
| log_update             | OFF                      |
| long_query_time        | 10                       |
| low_priority_updates   | OFF                      |
| max_allowed_packet     | 1048576                  |
| max_connections        | 100                      |
| max_connect_errors     | 10                       |
| max_heap_table_size    | 16777216                 |
| max_delayed_threads    | 20                       |
| max_join_size          | 4294967295               |
| max_sort_length        | 1024                     |
| max_tmp_tables         | 32                       |
| net_buffer_length      | 16384                    |
| port                   | 3306                     |
| protocol-version       | 10                       |
| record_buffer          | 131072                   |
| skip_locking           | ON                       |
| slow_launch_time       | 2                        |
| socket                 | /tmp/mysql.sock          |
| sort_buffer            | 2097116                  |
| table_cache            | 64                       |
| thread_stack           | 131072                   |
| tmp_table_size         | 1048576                  |
| tmpdir                 | /machine/tmp/            |
| version                | 3.23.0-alpha-debug       |
| wait_timeout           | 28800                    |
+------------------------+--------------------------+

12.2.3 サーバーパラメーターのチューニング」節参照.

SHOW PROCESSLIST はどのスレッドが走っているかを表示します。 mysqlshow processlist コマンドでも同じ情報が得られます。 もし process 権限があるなら、全てのスレッドがみれます。 しかし権限がないなら、自分のスレッドしか見れません。 「7.22 KILL 構文」節参照. FULL オプションを使用しない場合、各クエリの最初の100文字だけが表示 されます。

SHOW GRANTS FOR user はユーザの許可を複製するために発行する必要があ る grant コマンドをリストします。

mysql> SHOW GRANTS FOR root@localhost;
+---------------------------------------------------------------------+
| Grants for root@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+

7.24 EXPLAIN 構文 (SELECTについての情報を得る)

    EXPLAIN tbl_name
or  EXPLAIN SELECT select_options

EXPLAIN tbl_name は、 DESCRIBE tbl_nameSHOW COLUMNS FROM tbl_name と同義です。

もし EXPLAIN をともなって SELECT 構文を実行した場合、 MySQL はこの SELECT がいかに動作するかを説明し、 いかにテーブルが結合されるかの情報を与えます。

EXPLAIN の情報を元に、インデックスを使用した速い SELECT を 得るためにテーブルにインデックスを加えなくてはならないという事がわかります。 テーブル結合の最適化もオプションによって見ることができます。 SELECT 構文での結合を強制的に最適化するには STRAIGHT_JOIN 節を加えます。

単純ではない join のために、EXPLAINSELECT 文で使用されている それぞれのテーブルの情報を返します。 テーブルは読まれる順に表示されます。MySQL は one-sweep multi-join method を用いた全ての join を解決します。これは MySQL は最初のテーブルから 一レコード読み込み、二つ目のテーブルからマッチしたレコードを探し、そして三番目を探すということです。 全てのテーブルが処理される時、選択されたフィールドを出力し、テーブルの一覧は よりマッチするレコードをもつテーブルを見つけるまで back-track されます。 次のレコードはこのテーブルから読まれ、次のテーブルから処理を続けます。

EXPLAIN の出力は以下のフィールドを含みます:

table
出力レコードが参照されるテーブル
type
 join タイプ. 様々なタイプの説明は後述します
possible_keys
possible_keys 項目は、MySQL がテーブルからレコードを見つけるために どのインデックスを使用する事ができたかを示します。 注意: このフィールドはテーブルの順にまったく依存しません。これは、 possible_keys 内のいくつかのキーは、生成されたテーブル順での実行に使用でき ないことを意味します。 この項目が空なら、関連した インデックスは無いということです。この場合、あなたは WHERE 節を 調べることによって、クエリの性能を向上させることができるかもしれません。 もしそれがインデックスに適合したフィールドを参照しているならば。 仮にそうだとすると、適切なインデックスを作成し、 EXPLAIN でクエリを もう一度チェックしてみてください。 テーブルがどんなインデックスを持っているかみるには、SHOW INDEX FROM tbl_name とします。
key   
key 項目は、 MySQL が使用すると実際に決めたキーを示します。 どのインデックスも選ばれなかったならば、キーは NULL です。 MySQL が間違ったインデックスを選択する場合、たいていは MySQL に他のインデックスを使用するように強制することができます。 myisamchk --analyze の使用、 「15.2 myisamchk 起動構文」節参照、または USE INDEX/IGNORE INDEX の使用によって。 「7.15 JOIN 構文」節参照。
key_len
key_len 項目は、MySQL が使用すると決めたキーの長さを示します。 もし keyNULL なら、長さは NULL です。 注意: これはMySQL がマルチパートキーのいくつのパートを実際に使用 するかを示します。
ref   
ref 項目は、テーブルからレコードを select するために、どのフィールドや定数が key と共に使用されたかを示します。
rows   
rows フィールドは、MySQL がクエリを実行するために検査する 必要があると考えているレコードの数を示します。
Extra 
インデックスツリー(index tree)のからの情報だけが、 テーブルの情報を検索するために使用されたことを意味します。 通常、これは全てのテーブルを走査するより速いはずです。 Extra 項目に where used という字句が含まれる場合、 次のテーブルにマッチするレコードを限定するために、 あるいはクライアントに送られるレコードを限定するために、 WHERE 節が使用されたことを意味します。

join type は以下のものがあります。良い物から順に書いています:

system
テーブルが一レコードだけ持っている (= system table). これは const join type の特別な場合です。
const
テーブルは、最もマッチするレコードを1つもっており、これはクエリの 最初に読まれます。 1 つのレコードであるため、このレコード中のフィールドの値は オプティマイザーによって常数としてみなされます。 1回だけ読まれるので、const テーブルはとても速いです!
eq_ref
前のテーブルのそれぞれのレコードと結合する際、このテーブルから1レコード読まれます。 これは join では const よりも良い形です。 インデックスの全てのパートが join で使用され、かつ、インデックスが UNIQUEPRIMARY KEY であるときに、これは使用されます。
ref   
インデックスの値に合ったすべてのレコードは、前のテーブルからレコードと結合するために、 このテーブルから読まれるでしょう。 もしその join がキーの一番左の接頭部分だけを使用するならば、 あるいは、 もしそのキーが UNIQUEPRIMARY KEY でなければ (言い換えるなら、もし join がキーの値を元に一つだけの、レコードを選択できなければ)、 ref は使用されます。 もしそのキーがいくつかのマッチするレコードに使用されるだけなら、 join は良い形です。
range
示された範囲内にあるレコードのみが検索されます。 ref 項目はどのインデックスが使用されているか示します。
index
ALL と同じですが、インデックスツリーが走査される場合のみを除きます。 これは、インデックスファイルはデータファイルよりも小さいため、通常 ALL より速いです。
ALL
前のテーブルのレコードとのそれぞれの結合において、全テーブルが走査されます。 もしそのテーブルが最初のテーブルで const 状態ではないなら、通常 これは良くありません。他の状態ではとても悪くなります。 これは普通、レコードががより早いテーブルからから定数値に基づいて検索することができるように、 インデックスを追加することにより ALL を避けることが可能です。

EXPLAIN 出力の rows フィールド内のすべての値を増やすことによ り、join がどのように良くなるかの良い表示を得ることができます。これは、 MySQL がクエリ実行の検査をする必要があるレコードのおおよその数を 知らせます。この数は max_join_size 変数でのクエリを制限する時にも使 用します。 「12.2.3 サーバーパラメーターのチューニング」節参照.

以下の例は、EXPLAIN が提供する情報を元に、いかに JOIN が最適化 できるかの例です。

以下のような EXPLAIN で検査する SELECT 構文があるとします:

EXPLAIN SELECT tt.TicketNumber, tt.TimeIn,
            tt.ProjectReference, tt.EstimatedShipDate,
            tt.ActualShipDate, tt.ClientID,
            tt.ServiceCodes, tt.RepetitiveID,
            tt.CurrentProcess, tt.CurrentDPPerson,
            tt.RecordVolume, tt.DPPrinted, et.COUNTRY,
            et_1.COUNTRY, do.CUSTNAME
        FROM tt, et, et AS et_1, do
        WHERE tt.SubmitTime IS NULL
            AND tt.ActualPC = et.EMPLOYID
            AND tt.AssignedPC = et_1.EMPLOYID
            AND tt.ClientID = do.CUSTNMBR;

この例では、以下のように仮定します:

最初、いかなる最適化も行われていない状態では、EXPLAIN 構文は 以下の情報を提示します:

table type possible_keys                key  key_len ref  rows  Extra
et    ALL  PRIMARY                      NULL NULL    NULL 74
do    ALL  PRIMARY                      NULL NULL    NULL 2135
et_1  ALL  PRIMARY                      NULL NULL    NULL 74
tt    ALL  AssignedPC,ClientID,ActualPC NULL NULL    NULL 3872
      range checked for each record (key map: 35)

それぞれのテーブルで、typeALL になっています。 これは MySQL が全てのテーブルを全結合することを示します! それぞれのテーブル内の行数分から作った物が調べられるので、とても長い時間がかかります! この場合、74 * 2135 * 74 * 3872 = 45,268,558,720 行調べることになります。 テーブルが肥大化したときにかかる時間を考えてください....

一つ問題があります。(まだ) MySQL がフィールドのインデックスを効果的に 使用できていません。 この例の場合では、VARCHARCHAR は、それらが同じ長さで定義されていれば、 変わりがありません。 tt.ActualPCCHAR(10) と定義されており、 et.EMPLOYIDCHAR(15) です。これらの長さは違います。

この不釣り合いを修正するにあたり、ALTER TABLE を使って ActualPC の長さを 10 文字から 15 文字にします:

mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR(15);

これで tt.ActualPC and et.EMPLOYID は両方とも VARCHAR(15) になりました。 EXPLAIN 構文を実行し直すと、以下を提示します:

table type   possible_keys   key     key_len ref         rows    Extra
tt    ALL    AssignedPC,ClientID,ActualPC NULL NULL NULL 3872    where used
do    ALL    PRIMARY         NULL    NULL    NULL        2135
      range checked for each record (key map: 1)
et_1  ALL    PRIMARY         NULL    NULL    NULL        74
      range checked for each record (key map: 1)
et    eq_ref PRIMARY         PRIMARY 15      tt.ActualPC 1

まだ完全ではありませんが、よりよくなっています(rows 値の 生成量は 74 より小さくなります)。この場合、実行は数秒でしょう。

tt.AssignedPC = et_1.EMPLOYIDtt.ClientID = do.CUSTNMBR の比較において、フィールドの長さの違いを排除することができます:

mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15),
                      MODIFY ClientID   VARCHAR(15);

これで EXPLAIN は以下を出力します:

table type   possible_keys   key     key_len ref            rows     Extra
et    ALL    PRIMARY         NULL    NULL    NULL           74
tt    ref    AssignedPC,ClientID,ActualPC ActualPC 15 et.EMPLOYID 52 where used
et_1  eq_ref PRIMARY         PRIMARY 15      tt.AssignedPC  1
do    eq_ref PRIMARY         PRIMARY 15      tt.ClientID    1

これは ``ほとんど'' 最良に近いです。

残る問題は、デフォルトでは、MySQLtt.ActualPC フィールド内の値が まんべんなく分布していると想定しており、この tt テーブルの場合には適合しません。 幸運にも、これを MySQL に教えるのはとても簡単です:

shell> myisamchk --analyze PATH_TO_MYSQL_DATABASE/tt
shell> mysqladmin refresh

これで join は ``完璧'' です。 EXPLAIN は以下の結果を示します:

table type   possible_keys   key     key_len ref            rows    Extra
tt    ALL    AssignedPC,ClientID,ActualPC NULL NULL NULL    3872    where used
et    eq_ref PRIMARY         PRIMARY 15      tt.ActualPC    1
et_1  eq_ref PRIMARY         PRIMARY 15      tt.AssignedPC  1
do    eq_ref PRIMARY         PRIMARY 15      tt.ClientID    1

EXPLAIN の出力中の rows 項目は、 MySQL JOIN オプティマイザー による、``推測'' です; クエリの最適化のために、この数値が実際に近いかどうかをチェックすべきです。 そうでなければ、SELECT ステートメントで STRAIGHT_JOIN を使用 し、FROM 節に異なる順でテーブルを並べることで、良いパフォーマンスを 得られます。

7.25 DESCRIBE 構文 (フィールドについての情報を得る)

{DESCRIBE | DESC} tbl_name {col_name | wild}

DESCRIBE はフィールドについての情報を与えます。 col_name はフィールドはフィールド名または文字列です。 文字列は SQL `%',`_' ワイルドカードを含めます。

もしフィールドの型があなたが CREATE TABLE 文で与えた物と違っているなら、 これは MySQL がフィールドの型を変更していることに注意してください。 「7.7.1 暗黙のフィールド定義変更」節参照.

このコマンドは Oracle の互換のためにあります。

SHOW 構文は似たような情報を提供します。 「7.23 SHOW 構文 (テーブルやフィールドなどについての情報を得る)」節参照.

7.26 COMMIT/ROLLBACK 構文

デフォルトでは MySQLautocommit モードで動作します。こ れは、更新を実行するとすぐに MySQL が更新をディスクに格納すること を意味します。

もし BDB 型のテーブルを使用するなら, 以下のコマンドで MySQL を autocommit モードではない状態にすることができます:

SET AUTOCOMMIT=0

この後、ディスクに変更を格納するためには COMMIT を使用し、また、変 更を無視するためには ROLLBACK する必要があります。

注意: トランザクション安全テーブルを使用していない場合は、autocommit モー ドのステータスには依存せずに、変更はすぐに格納されます。 「8 MySQL table types」節参照.

7.27 LOCK TABLES/UNLOCK TABLES 構文

LOCK TABLES tbl_name [AS alias] {READ | [READ LOCAL] | [LOW_PRIORITY] WRITE}
             [, tbl_name {READ | [LOW_PRIORITY] WRITE} ...]
...
UNLOCK TABLES

LOCK TABLES はカレントのスレッドのためにテーブルをロックします。 UNLOCK TABLES はこのスレッドの全てのロックを解除します。 カレントスレッドによってロックされた全てのテーブルは、 スレッドが他の LOCK TABLES を発行した場合やサーバーが接続を閉じた場合、 自動で解除されます。

スレッドがテーブルに READ ロックを持つ場合、そのスレッド(と他の全てのスレッド)は テーブルからの読み込みだけができます。スレッドがテーブルに WRITE ロックを持つ場合、 このスレッドだけがテーブルの READWRITE ができます。 他のスレッドはブロックされます。

READ LOCALREAD の違いは、READ LOCAL は、ロックが 保持されている間にコンフリクトしない INSERT ステートメントを実行で きることです。ただし、これはロックを保持している間に MySQL の外で データベースファイルを操作しようとする場合は使用できません。

それぞれのスレッドはそれらが全てのロックを得るまで待ちます(タイムアウト無し)。

WRITE ロックは普通、できる限り更新を行わせるため、 READ ロックよりも優先順位が高くなっています。 これはあるスレッドが READ ロックをかけ、それ以外のスレッドが WRITE を 要求した場合、 READ は、WRITE スレッドがロックをし、それを解除するまで 待つということです。 LOW_PRIORITY WRITE を使用すれば、 WRITE ロックを待っているスレッドに READ ロックを得させることができます。 LOW_PRIORITY WRITEREAD ロックをしているスレッドが一つもないと わかっている場合に使用すべきです。

LOCK TABLES を使用するとき、使用しようとする全てのテーブルをロッ クすべきです! そしてクエリで使用しようとしているのと同じエイリアスを使わなければなりません! もしクエリで並列に複数回テーブルを使用するなら(alias をともなって)、 それぞれの alias をロックすべきです! このポリシーはテーブルロックをデッドロックフリーにすることを確かにします。

INSERT DELAYED で使用しているいかなるテーブルも、ロックすべきではありません。 この場合 INSERT は別のスレッドで行なわれるからです。

通常、全ての単一の UPDATE 構文においては、テーブルをロックする必要はありません; スレッドは、他のスレッドが現在実行している SQL 文に干渉することができません。 これらはテーブルをロックした方がよい、まれな場合です:

増加更新 (UPDATE customer SET value=value+new_value) または LAST_INSERT_ID() 関数の使用により、多くの場合 LOCK TABLES を回避 できます。

いくつかの場合、ユーザレベルロック: GET_LOCK()RELEASE_LOCK() の使用 によっても解決できます。これらのロックはサーバ内のハッシュテーブル内に保 持され、高速のため pthread_mutex_lock() で実装されました。 「7.4.12 その他の関数」節参照.

ロックポリシーのさらなる情報については 「12.2.8 MySQL はどのようにテーブルをロックするか」節 を見てくださ い。

7.28 SET OPTION 構文

SET [OPTION] SQL_VALUE_OPTION= value, ...

SET OPTION はサーバやクライアントの操作に影響する様々なオプションを設定します. 現在のセッションが終わるか,またはあなたが異なった値にオプションを設定するまで, 設定されたオプション値は残っています.

CHARACTER SET character_set_name | DEFAULT
これは指定されたマッピングに従って、すべての文字列をクライアントからクライアントにマップします. 現在、character_set_name に指定できるオプションは cp1251_koi8 だけですが, MySQL のソース中にある `sql/convert.cc' ファイルを編集することによって, 容易に新しいマッピングを加えることができます. 標準のマッピングに戻すには、 character_set_nameDEFAULT を指定します。 CHARACTER SET オプションを設定するための構文は、 他のオプションを設定する構文と異なっていることに注意してください.
PASSWORD = PASSWORD('some password')
現在のユーザのパスワードを設定します。いかなる非匿名のユーザも、 自分自身パスワードを変えることができます!
PASSWORD FOR user = PASSWORD('some password')
現在ログインしているホストの特定ユーザのパスワードを設定します。 mysql データベースにアクセスができるユーザーだけが実行できます。 ユーザは user@hostname 形式で与えなくてはなりません。 ここで userhostname は、mysql.user テーブルの User, Host フィールドに登録されていなくてはなりません。 例えば、UserHost フィールドが 'bob''%.loc.gov' ならば、以下のようにします:
mysql> SET PASSWORD FOR bob@"%.loc.gov" = PASSWORD("newpass");

または

mysql> UPDATE mysql.user SET password=PASSWORD("newpass") where user="bob' and host="%.loc.gov";
SQL_AUTO_IS_NULL = 0 | 1
1 (デフォルト) を設定すると、次のようにして、auto_increment レコー ドを持つテーブルで、最後に挿入されたレコードを見つけることができます: WHERE auto_increment_column IS NULL。これは、Access のようないくつ かの ODBC プログラムによって使用されます。
SET AUTOCOMMIT= 0 | 1
1 を設定すると、テーブルへのすべての変更はすぐに行なわれます。 0 を設定すると、そのトランザクションを許可/破棄するために、 COMMIT / ROLLBACK を使用する必要があります。 「7.26 COMMIT/ROLLBACK 構文」節参照。 注意: 非 AUTOCOMMIT モードから AUTOCOMMIT モードに変更する時、 MySQL はすべてのオープントランザクションを自動的に COMMIT します。
SQL_BIG_TABLES = 0 | 1
0 の場合、全ての一時テーブルはメモリーではなくディスクに書き出されます。 これは少し遅くなりますが、多くの一時テーブルを必要とする大きな SELECT を 実行しても、The table tbl_name is full エラーが出なくなります。 新しい接続におけるこの値のデフォルト値は 1 (メモリーに一時テーブルを作る) です。
SQL_BIG_SELECTS = 0 | 1
1 の場合、とても時間のかかる SELECT が実行された場合、 MySQL はそれを中止します。 これはあまり芳しくない(間違った) WHERE 構文が発行されたときに役立ちます。 max_join_size 行以上を検討するような SELECT が 大きなクエリと定義されます。 新しい接続におけるこの値のデフォルト値は 0 です。 (全ての SELECT 構文を許します)
SQL_BUFFER_RESULT = 0 | 1
SQL_BUFFER_RESULT は一時ファイルに置かれる SELECT からの結果 を強制的に置きます。これは MySQL がテーブルロックを早く解放する手 助けをし、クライアントへ結果セットを送信するために長い時間が掛かる場合に役 立ちます。
SQL_LOW_PRIORITY_UPDATES = 0 | 1
1 の場合、全ての INSERT, UPDATE, DELETE, LOCK TABLE WRITE構文は、 対象となるテーブルを処理中の SELECTLOCK TABLE READ がなくなるまで待ちます。
SQL_MAX_JOIN_SIZE = value | DEFAULT
おそらく value よりも多いレコードの組合せを試験する必要があるような SELECT を許可しません。この値を設定することで、キーが使用されないで あろう SELECT と長い時間が掛かるであろう SELECT を捕捉できま す。これを DEFAULT 以外の値に設定すると、SQL_BIG_SELECTS フ ラグをリセットします。SQL_BIG_SELECTS フラグを再び設定すると、 SQL_MAX_JOIN_SIZE 変数は無視されます。-O max_join_size=#mysqld を起動することで、この変数のデフォルト値を設定できます。
SQL_SAFE_MODE = 0 | 1
1 に設定すると、WHERE 節内でキーや LIMIT を使用しない で UPDATE または DELETE を行なおうとした場合に MySQL がアボートします。これは、手で SQL コマンドを生成する時の間 違った更新の捕捉を可能にします。
SQL_SELECT_LIMIT = value | DEFAULT
SELECT 構文から返されるレコードの最大値。 もし SELECTLIMIT 節を使用している場合、LIMITSQL_SELECT_LIMIT の値より優先されます。 新しい接続におけるこの値の標準値は ``unlimited''. もしリミットを変えているならば、SQL_SELECT_LIMITDEFAULT を指定することにより、標準値に戻すことができます。
SQL_LOG_OFF = 0 | 1
この値が 1 の場合、もしクライアントが process 権限を持っているならば、 このクライアントのログが行われません。 これは更新ログに影響しません!
SQL_LOG_UPDATE = 0 | 1
0 の場合、もしクライアントが process 権限を持っているならば、 このクライアントの更新ログの記録は行われません。 これは通常のログには影響しません!
TIMESTAMP = timestamp_value | DEFAULT
クライアントに時間を設定します。 もしレコードのリストアに更新ログを使用する場合、オリジナルのタイムスタンプを得るために使用します。
LAST_INSERT_ID = #
LAST_INSERT_ID() からの返り値を設定します。 テーブルを更新するコマンド中に LAST_INSERT_ID() を使用した場合、 これは更新ログに保存されます。
INSERT_ID = #
AUTO_INCREMENT 値を挿入する時、 INSERT コマンドに従って使用される値をセットします。 これは更新ログによって使用されます。

7.29 GRANTREVOKE 構文

GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...]
    ON {tbl_name | * | *.* | db_name.*}
    TO user_name [IDENTIFIED BY 'password']
        [, user_name [IDENTIFIED BY 'password'] ...]
    [WITH GRANT OPTION]

REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...]
    ON {tbl_name | * | *.* | db_name.*}
    FROM user_name [, user_name ...]

GRANTMySQL 3.22.11 以上で実装されています; 前の MySQL バージョンでは、GRANT ステートメントは何も行ないま せん。

GRANTREVOKE コマンドセットの主な目的は、システム管理者 が MySQL ユーザに次の4つの権限レベルの権利を与えたり取り消すこ とをできるようにすることです:

Global レベル
Global 権限は与えられたサーバ上の全てのデータベースに適用します。これらの権限は mysql.user テーブル内に格納されます。
Database レベル
Database 権限は与えられたデータベース内の全てのテーブルに適用します。こ れらの権限は mysql.db テーブルと mysql.host テーブル内に格納されます。
Table レベル
Table 権限は与えられたテーブル内の全てのフィールドに適用します。これらの権限は mysql.tables_priv テーブル内に格納されます。
Column レベル
Column 権限は与えられたテーブル内の一つのフィールドに適用します。これらの権限は mysql.column_priv テーブル内に格納されます。

GRANT の動作例は → 「6.12 新しいユーザ権限を MySQL へ追加」節.

GRANTREVOKE ステートメントにおいて priv_type には 以下が指定できます:

ALL PRIVILEGES      FILE                RELOAD
ALTER               INDEX               SELECT
CREATE              INSERT              SHUTDOWN
DELETE              PROCESS             UPDATE
DROP                REFERENCES          USAGE

ALLALL PRIVILEGES の同義語です. REFERENCES はまだ実行されません。 USAGE は ``no privileges'' と同義です. これはなんの権限も持たないユーザーを作る場合に使用します.

ユーザーから権限許可を取り除くには、GRANT OPTION オプションの値に priv_type を指定します:

REVOKE GRANT OPTION ON ... FROM ...;

テーブルに対する許可のために指定できる priv_type は次のフィールドだけです: SELECT,INSERT, UPDATE, DELETE, CREATE, DROP, GRANT, INDEX, ALTER.

フィールドに対する許可のために指定できる priv_type は次のフィールドだけです (これは column_list 節を使用する場合に適用されます): SELECT, INSERT, UPDATE.

WITH GRANT OPTION 節は、GRANT 構文を使用して 他のユーザーに権限を与えることができるようにします。

ON *.* を使用してグローバル権限を設定できます。 ON db_name.* を使用してデータベース権限を設定できます。ON * を 指定すると、現在のデータベースの権限を設定できます。 (警告: 現在のデータベースを持たない状態で ON * を指定した場合、 global 権限に影響します!)

ユーザへの権利の供与を他のホストから適応するために、MySQLuser_name の値を user@host の形で書けるようにしています。 特殊文字(`%' のような)で user_name の値を指定したい場合、 ユーザやホスト名をクォートできます; (例えば 'test-user'@'test-hostname')。

ホスト名にワイルドカードを使用できます。例えば、user@"%.loc.gov"loc.gov ドメインの全てのホストの user を与え、 user@"144.155.166.%"144.155.166 クラスCサブネットの あらゆるホストの user となります。

単に user と書くと user@"%" と同じです. 注意: もし匿名ユーザーからの MySQL サーバーへの接続を 許す場合(デフォルトです)、全てのローカルユーザー username@localhost を加えるべきです。 なぜなら、匿名ユーザーは同じマシンから MySQL サーバーに入ろうとした場合に 使用されるからです! 匿名ユーザーは mysql.user ユーザーテーブルに、 User='' として登録されています。 これを確認するには、以下のようにします:

mysql> SELECT Host,User FROM mysql.user WHERE User='';

さしあたり, GRANT はホスト名、テーブル名、データベース名、フィールド名に 最大60文字まで使用できます。ユーザー名は最大16文字までです。

テーブル/フィールドの権限は global(ユーザとデータベース)権限と GRANT 権限と OR されます。例えば、ユーザが mysql.user テーブル内の global select 権限を持っている場合、 これはデータベースやテーブル/フィールドレベル内のエントリでは拒否できません。

フィールドの権利は次のように計算できます:

global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges

多くの場合、異なる権限レベルの一つでユーザに権利を与えるので、人生は通常 上述のようには複雑ではありません。:) アクセス制限のチェックの詳細は→ 「6 MySQL のユーザー権限はどのように動くか?」節.

ユーザへの権利の供与を他のホストから適応するために、MySQL はユー ザ名が形式 user@host で指定できることをサポートします。簡単な形 式 useruser@% の同義語です。特殊文字(. のよう な)でホスト名を指定したい場合、"user"@"hostname" 構文を使用でき ます。

ユーザとホスト名の組が存在しない場合、エントリは mysql.user テー ブルに追加され、DELETE コマンドで削除されるまでそこに残ります。 いうならば GRANTuser テーブルの登録を作りますが、 REVOKE はそれらを削除できません; そうするには DELETE を使用しなくてはなりません。

MySQL 3.22.12 以上では、 新しいユーザーが作成された場合、あるいは、あなたがグローバルな権限を許可されている場合、 ユーザーのパスワードは IDENTIFIED BY 節を使用して設定できます。 すでにユーザーにパスワードがある場合、新しく設定されたパスワードに置き換えられます。

警告: もし新しいユーザーを作っても IDENTIFIED BY 節を指定しなければ、 そのユーザーはノーパスワードです。 これは危険です。

パスワードは SET PASSWORD コマンドでも設定できます。 「7.28 SET OPTION 構文」節参照.

データベースに権限を GRANT する場合、mysql.db テーブル内の エントリは必要な場合に生成されます。全てのデータベース権限が REVOKE で削除された時、このエントリは削除されます。

ユーザがテーブルに何も権限を持っていない場合、テーブルの一覧要求時(例え ば、SHOW TABLES ステートメントで)には、テーブルは現れません。

WITH GRANT OPTION 節は、他のユーザーに、自分が持っている権限を与えることができます。 権限許可を他に与える場合は注意してください。 あなたと許可を与えるユーザーが違う権限を持っている場合、 与えられる権限の許可は、二つを合わせた物になります!

自分自身が持っていない権限を他のユーザーに与えることはできません; 権限許可はあなたが所有する権限の許可だけを与えることができます。

あなたがユーザーに格別の権限レベルを与えた場合、既にユーザーが持っているいかなる権限 (あるいは 将来持つ権限) はそのユーザーによっても許可が与えられます。 あなたがデータベースに対する insert 許可をあるユーザーに与えたと仮定します。 もし、データベースに対する select 権限を与えたり、 WITH GRANT OPTION を行うと、ユーザーは select 権限だけでなく insert も得ることになります。 もし update 権限をユーザーに与えると、そのユーザーは insert, select, update が可能です。

alter 権限を一般ユーザに与えるべきではありません。この場合 ユーザはテーブルをリネームでき、この方法で権限を回ることを試みることがで きます!

注意:もし table/column 権限を一人のユーザーにだけ与えた場合、 MySQL は全てのユーザーに対してテーブルとフィールドの承認権限を検討します。 これは MySQL を少し遅くします。

mysqld 開始時、全ての権限はメモリに読み込まれます。データベース、 テーブル、フィールド権限は一度効果を得ます。ユーザレベル権限はユーザ再接続時に 効果を得ます。 これらの許可テーブルを GRANTREVOKE を使って変更しても サーバーにはすぐに反映されません。 もしこれらの許可テーブルを手動で変更した場合(INSERT, UPDATE, 等で変更した場合)、 FLUSH PRIVILEGES 構文を実行するか、mysqladmin flush-privileges を実行して サーバーに許可テーブルの再読み込みを行わせなくてはなりません。 「6.10 いつ権限の変更が反映されるか」節参照.

ANSI SQL GRANTMySQL GRANT との大きな違いは:

7.30 CREATE INDEX 構文

CREATE [UNIQUE] INDEX index_name ON tbl_name (col_name[(length)],... )

CREATE INDEX 構文は MySQL 3.22 より以前のバージョンではなにもしません。 3.22 以降で、CREATE INDEX はインデックスの作成のために ALTER TABLE を呼びだしています。 「7.8 ALTER TABLE構文」節参照.

通常、テーブル内の全てのインデックスは CREATE TABLE で テーブルを作るときに一度に作成されます。 「7.7 CREATE TABLE構文」節参照. CREATE INDEX は既に存在するテーブルに対し、インデックスを追加します。

フィールドを (col1,col2,...) として指定すると、複数フィールドインデックスを作成します。 インデックスの値は、与えられたフィールドの値を連結して、構成されます。

CHARVARCHAR フィールドでは、インデックスはフィールドの一部分だけを使用して 作成されます。これは col_name(length) 構文を使用します。 (BLOBTEXT 節では length が必要です)。 最初の10文字をインデックスとして使用するには、この構文は以下のようにして使用します(name フィールドにインデックスを作ります):

mysql> CREATE INDEX part_of_name ON customer (name(10));

フィールドの一部分だけをインデックスに使用すれば、インデックスファイルをはるかに小さくすることができます。 ほとんどの名前が最初の10文字において通常異なるので、 このインデックスは name フィールド全部を使用して創り出したインデックスに比べて 遅くなることはありません。また、多くのディスクスペースを節約でき、 INSERT を速くするのです!

MySQL version 3.23.2 以上で MyISAM 型のテーブルを使用している場合、 NULL 値をもつフィールドや、 BLOB/TEXT フィールドに対して インデックスを張ることが可能です。

MySQL がどのようにしてインデックスを使用するかは →   「12.4 MySQL はどのようにインデックスを使用するか?」節.

7.31 DROP INDEX 構文

DROP INDEX index_name ON tbl_name

DROP INDEXindex_name という名前のインデックスをテーブル tbl_name から破棄します。 DROP INDEXMySQL 3.22 より以前のバージョンではなにもしません。 3.22 以降で、DROP INDEX はインデックスの破棄のために ALTER TABLE を呼びだしています。 「7.8 ALTER TABLE構文」節参照.

7.32 コメント 構文

MySQL# 行末まで , -- 行末まで そして /* 行中または複数行 */ コメント書式をサポートします:

mysql> select 1+1;     # このコメントは行末まで続く
mysql> select 1+1;     -- このコメントは行末まで続く
mysql> select 1 /* これは行中コメント */ + 1;
mysql> select 1+
/*
これは
複数行コメント
*/
1;

-- コメントスタイルは -- の後ろに最低一つのスペースが 必要であることに注意!

サーバーはコメント構文を理解しますが、 mysql クライアントが /* ... */ コメントを分析するにはいくつか制限があります:

これらの制限は mysql を対話モードで実行している場合と、 mysql にファイルを読み込ませている場合 ( mysql < some-file ) の 両方で現れます。

MySQL は ANSI SQL コメントの `--' をサポートしません。 「5.4.7 コメント開始としての `--'」節参照.

7.33 CREATE FUNCTION/DROP FUNCTION 構文

CREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|REAL|INTEGER}
       SONAME shared_library_name

DROP FUNCTION function_name

ユーザー定義関数 (UDF : user-definable functions) は MySQL に新しい関数を持たせれる拡張方法です。 これは MySQL のネイティブ(埋め込み)関数 (ABS(), CONCAT() のような)と同じように動作します。

AGGREGATEMySQL 3.23 の新しいオプションです。 AGGREGATE 関数は、SUMCOUNT() のようなネイティブな MySQL GROUP 関数のように正確に動作します。

CREATE FUNCTION は、関数名、型、共有ライブラリ名を、 mysql.func システムテーブルに、保存します。 関数の作成、破棄を行うには、 mysql データベースに対して、 insert , delete 権限がなければなりません。

全ての関数はサーバーの起動時に読み込まれます。 ただし --skip-grant-tables オプションを mysqld につけていなければ。 この場合、UDF の初期化は飛ばされ、UDF で作った関数は使用できません。 (関数は CREATE FUNCTION でロードされ、 DROP FUNCTION で削除されます)

ユーザー定義関数に関するさらなる情報は → 「16 MySQL への新しい関数の追加」節. UDF メカニズムで動かすためには、関数は C か C++ で書かれていなければなりません。 かつ、あなたのオペレーティングシステムがダイナミックローディングを サポートしていなければなりません。さらに mysqld はスタティックではなく ダイナミックでコンパイルされていなければなりません。

7.34 Is MySQL picky about reserved words?

共通の問題は、フィールドの名前を、 TIMESTAMP とか GROUP とかの MySQL に埋め込まれているデータ型や関数名と同名にして、 テーブルを作った場合に起こります。 このようなことは行えます(例えば ABS はフィールド名にできます)。 しかし、関数として使用する場合、 この名前がフィールド名として使用されているなら、 関数名と `(' の間の空白は許されません。

以下の語は MySQL に予約されています。 これらのほとんどは、 ANSI SQL92 によって、 テーブル、フィールド名としての使用は禁止されています。(例えば group)。 またいくつかの語は MySQL が必要とし、 yacc パーサーで 使用しているので予約されています。

action add aggregate all
alter after and as
asc avg avg_row_length auto_increment
between bigint bit binary
blob bool both by
cascade case char character
change check checksum column
columns comment constraint create
cross current_date current_time current_timestamp
data database databases date
datetime day day_hour day_minute
day_second dayofmonth dayofweek dayofyear
dec decimal default delayed
delay_key_write delete desc describe
distinct distinctrow double drop
end else escape escaped
enclosed enum explain exists
fields file first float
float4 float8 flush foreign
from for full function
global grant grants group
having heap high_priority hour
hour_minute hour_second hosts identified
ignore in index infile
inner insert insert_id int
integer interval int1 int2
int3 int4 int8 into
if is isam join
key keys kill last_insert_id
leading left length like
lines limit load local
lock logs long longblob
longtext low_priority max max_rows
match mediumblob mediumtext mediumint
middleint min_rows minute minute_second
modify month monthname myisam
natural numeric no not
null on optimize option
optionally or order outer
outfile pack_keys partial password
precision primary procedure process
processlist privileges read real
references reload regexp rename
replace restrict returns revoke
rlike row rows second
select set show shutdown
smallint soname sql_big_tables sql_big_selects
sql_low_priority_updates sql_log_off sql_log_update sql_select_limit
sql_small_result sql_big_result sql_warnings straight_join
starting status string table
tables temporary terminated text
then time timestamp tinyblob
tinytext tinyint trailing to
type use using unique
unlock unsigned update usage
values varchar variables varying
varbinary with write when
where year year_month zerofill

以下は ANSI SQL ではフィールド、テーブル名としての使用を禁止されていますが、 MySQL では許可されています。 これは、これらの名前は凄く自然な名前で、多くの人がこれらを既に名前として 使用しているからです。


Go to the first, previous, next, last section, table of contents.