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

# 6 MySQL Language Reference

MySQL はとても複雑ですが、直感的で、SQL インタフェースを学ぶのに 簡単です。この章は、MySQL を効率よく効果的に使用するために知って おく必要がある様々なコマンド、型、関数について説明します。この章は、 MySQL に含まれているすべての機能へのリファレンスも提供します。こ の章を効果的に使用するため、様々なインデックスを参照して便利に見つけられま す。

## 6.1 Language Structure

### 6.1.1 文字列と数値をどのように書くか？

この節は MySQL で文字列と数値を記述するさまざまな方法を説明します。 MySQL でのこれらの基本型の取り扱い時に、出会うであろうさまざまな ニュアンスと ``了解'' もカバーします。

#### 6.1.1.1 文字列

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

    'a string'
    "another string"

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

`\0`
  ASCII 0 (`NUL`) 文字。
`\'`
  引用符(``''`)。
`\"`
  二重引用符(``"'`)。
`\b`
  バックスペース文字。
`\n`
  改行文字。
`\r`
  リターン文字。
`\t`
  タブ文字。
`\z`
  ASCII(26) (Control-Z)。この文字は、ASCII(26) が Windows では END-OF-FILE であるという問題を回避するために、コード化できます。(ASCII(26) は `mysql database < filename` を使用しようとする場合に問題になります)。
`\\`
  バックスラッシュ(``\'`)文字。
`\%`
  ``%'` 文字。これは ``%'` がワイルドカード文字として解釈される文脈 で、``%'` そのものを検索するために使用されます。 「6.3.2.1 文字列比較関数」節参照.
`\_`
  `_` 文字。これは ``_'` がワイルドカード文字として解釈される文脈 で、`_` そのものを検索するために使用されます。 「6.3.2.1 文字列比較関数」節参照.

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

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

- ``''` で括られる文字列中の ``''` は ``'''` として書くことができ ます。
- ``"'` で括られる文字列中の ``"'` は ``""'` として書くことができ ます。
- 引用符の前にエスケープ文字 (``\'`) を置くことができます。
- ``"'` で括られた文字列中の ``''` は特別扱いの必要はなく、二重にし たり、エスケープする必要はありません。同じように、``''` で括られた文 字列中の ``"'` は特別扱いの必要はありません。

次の `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()` を使用できます。 「8.4.2 C API 関数概要」節参照. Perl では、`DBI` パッケージの `quote` メソッドを使 用して、特殊文字を適当なエスケープシーケンスに変換できます。 「8.2.2 The `DBI` Interface」節参照.

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

#### 6.1.1.2 数値

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

正当な数値の例:

    1221
    0
    -32

有効な浮動小数点の例：

    294.42
    -32032.6809e+10
    148.00

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

#### 6.1.1.3 16進法の値

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

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

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

#### 6.1.1.4 `NULL` 値

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

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

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

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

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

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

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

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

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

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

- 名前は、現在の文字セットのアルファベットと数字文字から成り、``_'` と ``$'` も含みます。デフォルト文字セットは ISO-8859-1 Latin1 ですが、 これは `mysqld` に `--default-character-set` オプションを 与えることで変更できます. (3.23.14 以上の場合のみ。 それ以前のバージョンでは MySQL 再コンパイルが必要) 「4.6.1 データとソートに使用されるキャラクターセット」節参照.
- 名前は、名前として正しい任意の文字で始めることができます。特に、名前は数 字で始めることができます(これは他の多くのシステムと異なります！)。しかし、 数字だけの名前にする事はできません。
- 名前の中に ``.'` 文字を使用することはできません。フィールドを参照できるよう に形式を拡張するために使用されるためです(後述)。

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

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

### 6.1.3 名前のケース依存性

MySQL では、データベースとテーブルは、ディレクトリと そのディレクトリ中のファイルに対応します。そのため、下で動作するオペレー ティングシステムのケース依存性は、データベースとテーブル名のケース依存性を決定します。 データベース名とテーブル名は UNIX ではケース依存で、Windows ではケース非依 存です。 「1.4.1 MySQL の ANSI SQL92 に対する拡張」節参照.

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

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

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

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

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

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

テーブル名に使用されたケースを覚えておくことに問題があるなら、常にデータベー スとテーブルに小文字の名前をつけるというような、一貫した慣習を採用してくだ さい。

この問題を回避する一つの方法は、`mysqld` を `-O lower_case_table_names=1` をつけて起動することです。デフォルトではこのオプ ションは Windows では 1 で UNIX では 0 です。

`lower_case_table_names` が 1 の場合、MySQL はディスク上のす べてのテーブル名を小文字に変換して検索します。注意: このオプションを変更し た場合、`mysqld` を起動する前に、最初に古いテーブル名を小文字に変換す ることが必要です。

### 6.1.4 ユーザー変数

MySQL は、`@variablename` 構文でスレッド固有の変数をサポー トします。変数名は現在の文字セットのアルファベットと数字、それに ``_'`、``$'`、``.'` 文字からなります。デフォルト文字セットは ISO-8859-1 Latin1 です。 これは `mysqld` に `--default-character-set` オプションを 与えることで変更できます. (3.23.14 以上の場合のみ。 それ以前のバージョンでは MySQL 再コンパイルが必要) 「4.6.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` の値になるからです。

### 6.1.5 コメント 構文

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

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

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

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

- シングルクウォートとダブルクオート文字は引用文字列のトークンの開始を 示します。たとえコメントの中であっても。 もしコメントの中でクオートが二つ目のクオートにマッチしなかった場合、 パーサーはコメントが終了していないと認識します。 `mysql` を対話モードで実行している場合、 プロンプトが `mysql>` から `'>` か `">` に変わります。
- セミコロンは SQL 構文の終了を示し、これに続く文字は次の構文の開始と なります。

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

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

### 6.1.6 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`

The following symbols (from the table above) are disallowed by ANSI SQL but allowed by MySQL as column/table names. This is because some of these names are very natural names and a lot of people have already used them.

- `ACTION`
- `BIT`
- `DATE`
- `ENUM`
- `NO`
- `TEXT`
- `TIME`
- `TIMESTAMP`

## 6.2 フィールド型

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

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

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

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

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

`TINYINT[(M)] [UNSIGNED] [ZEROFILL]`
  とても小さい整数。符号つきの範囲は `-128`〜`127`。符号なしの範囲は `0`〜`255`。
`SMALLINT[(M)] [UNSIGNED] [ZEROFILL]`
  小さい整数。符号つきの範囲は `-32768`〜`32767`。 符号なしの範囲は `0`〜`65535`。
`MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]`
  中間の整数。符号ありの範囲は `-8388608`〜`8388607`。 符号なしの範囲は `0`〜`16777215`
`INT[(M)] [UNSIGNED] [ZEROFILL]`
  通常の整数。符号ありの範囲は `-2147483648`〜`2147483647`。符号なしの範 囲は `0`〜`4294967295`
`INTEGER[(M)] [UNSIGNED] [ZEROFILL]`
  これは、`INT`の同義語です。
`BIGINT[(M)] [UNSIGNED] [ZEROFILL]`
  大きい整数。 符号ありの範囲は `-9223372036854775808`〜`9223372036854775807`。 符号なしの範囲は `0`〜`18446744073709551615`。 `BIGINT` フィールドについて意識すべきことのいくつか:
  - 全ての演算は符合付き `BIGINT` または `DOUBLE` で行われるため、 符合無しの `9223372036854775807` (63 bits) よりも大きな整数を ビット関数以外で使用すべきではありません！ それを行なうと、結果の最後の桁のいくつかは不正になるでしょう `BIGINT` を `DOUBLE` に変換する時の丸めエラーのためです。
  - 文字列として格納することで `BIGINT` フィールドの正確な整数値を常に格 納することができます。この場合、double 表現を介在しません。
  - `-`、`+`及び`*`は、両方の引数が`INTEGER`値の時、 `BIGINT`演算を使うことに注意して下さい！ これは、２つの大きな整数の かけ算を行なう(又は整数を返す関数の結果が大きな整数である)時、 結果が`9223372036854775807`よりも大きい場合に予期しない結果を 受け取ることがあるということを意味しています。
`FLOAT(precision) [ZEROFILL]`
  浮動小数点数。符号なしにはできません。単精度浮動小数点数では `precision` が `<=24` で、倍精度浮動小数点数では 25〜53 の間です。 これらの型は次で述べる`FLOAT`や`DOUBLE`型に似ています。 `FLOAT(X)`は、`FLOAT`及び`DOUBLE`型に一致する同じ範囲を持っていま すが、 表示サイズや小数点以下桁数が定義されません。 MySQL バージョン 3.23 では、これは正しい浮動小数点です。前の MySQL バージョンでは, `FLOAT(precision)` は常に小数部は2桁で した。 注意: `FLOAT` の使用は、MySQL での全ての演算が double 精度で行 なわれるため、いくつかの予期しない問題が起こり得ます。 「A.5.6 Solving Problems with No Matching Rows」節参照. この構文は ODBC 互換です。
`FLOAT[(M,D)] [ZEROFILL]`
  小さい浮動小数点数。符号なしにはできません。 範囲は `-3.402823466E+38`〜`-1.175494351E-38`、 `0`、 `1.175494351E-38`〜`3.402823466E+38`です。 M は表示幅で D は小数部桁数です。引数が無いか引数が24以下の `FLOAT` は単精度浮動小数点数を意味します。
`DOUBLE[(M,D)] [ZEROFILL]`
  通常の浮動小数点数。符号なしにはできません。 範囲は `-1.7976931348623157E+308`〜`-2.2250738585072014E-308` 、 `0`、`2.2250738585072014E-308`〜`1.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`フィールドのように振 舞います。`パック無し'は、数値が文字列として格納されることを意味し、数値のそれぞ れの桁、小数点、及び負数での``-'`符号に１文字使用します。 `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` フィールドへの値の割当ては、文字列もしくは数値のいずれかの使用が許されます。 「6.2.2.2 `DATETIME`, `DATE`, `TIMESTAMP` 型」節参照.
`DATETIME`
  日付と時刻の組み合わせ。サポートされる範囲は`'1000-01-01 00:00:00'`〜 `'9999-12-31 23:59:59'`です。MySQLは`DATETIME`値を `'YYYY-MM-DD HH:MM:SS'`という書式で表示しますが、`DATETIME`フィールド への値の割当ては、文字列もしくは数値のいずれかの使用が許されます。 「6.2.2.2 `DATETIME`, `DATE`, `TIMESTAMP` 型」節参照.
`TIMESTAMP[(M)]`
  タイムスタンプ。範囲は`'1970-01-01 00:00:00'`〜`2037`年末までです。 MySQL は`TIMESTAMP`値を`YYYYMMDDHHMMSS`、`YYMMDDHHMMSS`、 `YYYYMMDD`又は`YYMMDD`という書式で表示し、それは`M`に`14`(もし くは誤ってそれ以上の値を指定した時)、`12`、`8`又は`6`のいずれが指 定されたかに依存します。しかしながら`TIMESTAMP`フィールドへの値の割当ては、 文字列もしくは数値のいずれかの使用が許されます。 `TIMESTAMP`フィールドは、最後に操作された時刻を自動的に設定するので、 `INSERT`や`UPDATE`操作の時刻を記録するのに役立ちます。 `NULL`値を与えることによっても、現在時刻を設定できます。 「6.2.2 日付と時間の型」節参照. `TIMESTAMP` は常に 4 バイトで格納されます。`M` 引数は `TIMESTAMP` フィールドがどのように表示されるかだけに影響します。 注意: X が 8 または 14 である `TIMESTAMP(X)` フィールドは数値として報 告されます。他の `TIMESTAMP(X)` フィールドは文字列として報告されます。 これは、これらの型を持ったテーブルを確実にダンプとリストアできるようにする ためです！ 「6.2.2.2 `DATETIME`, `DATE`, `TIMESTAMP` 型」節参照.
`TIME`
  時間。範囲は`'-838:59:59'`〜`'838:59:59'`です。 MySQL は`TIME`値を`'HH:MM:SS'`という書式で表示しますが、`TIME` フィールドへの値の割当ては、文字列もしくは数値のいずれかの使用が許されます。 「6.2.2.3 `TIME` 型」節参照.
`YEAR[(2|4)]`
  年。2桁または4桁形式(デフォルトは4桁)。許される値は、4桁形式では `1901`〜`2155`, `0000` で、2桁形式(70〜69)では 1970〜2069 です。MySQL は `YEAR` 値を `YYYY` 形式で表示しますが、 `YEAR` フィールドへの値の割り当ては文字列と数字のどちらでも使用できま す。(`YEAR` は MySQL バージョン 3.22 での新しい型です。) 「6.2.2.4 `YEAR` 型」節参照.
`[NATIONAL] CHAR(M) [BINARY]`
  固定長文字列で、格納時には必ず指定された長さまで右側に空白を埋めます。 `M`の範囲は 1 から 255 文字です。後続の空白は値の取り出し時に削除され ます。`BINARY` キーワードが与えられない場合、`CHAR` 値のソートと 比較は、デフォルト文字セットに従ってケース非依存の方法で行なわれます。 `NATIONAL CHAR` (短い形式は `NCHAR`) は、ANSI SQL で、CHAR フィー ルドがデフォルト文字セットを使用することを定義する方法です。これは MySQL ではデフォルトです。 `CHAR` は `CHARACTER` の略記です。 MySQL は `CHAR(0)` 型のフィールドの生成を許します。これは主 に、実際にはもう値が使われていないフィールドが存在することに依存しているよ うないくつかの古いアプリケーションに対応する必要がある時に便利です。２つの 値だけを取ることができるフィールドを必要とする時にもとても良いことです: `NOT NULL` として定義されていない `CHAR(0)` は1ビットだけを占有 し、２つの値だけを取ることができます: `NULL` または `""`。 「6.2.3.1 `CHAR` 型と `VARCHAR` 型」節参照.
`BIT`
`BOOL`
`CHAR`
  These three are synonyms for `CHAR(1)`.
`[NATIONAL] VARCHAR(M) [BINARY]`
  可変長文字列。 注意: 後続の空白は格納時に削除されます(これは ANSI SQL 仕様と異なります)。 `M`の範囲は 1 から 255 文字です。 `BINARY` キーワードが与えられない場合、ソートと比較はケースに依存しません。 「6.5.3.1 暗黙のフィールド定義変更」節参照. `VARCHAR` は `CHARACTER VARYING` の略記です。 「6.2.3.1 `CHAR` 型と `VARCHAR` 型」節参照.
`TINYBLOB`
`TINYTEXT`
  最大長 255 (2^8 - 1) 文字の `TEXT`/`BLOB`。 「6.5.3.1 暗黙のフィールド定義変更」節参照. 「6.2.3.2 `BLOB` と `TEXT` 型」節参照.
`BLOB`
`TEXT`
  最大長 65535 (2^16 - 1) 文字の `TEXT`/`BLOB`。 「6.5.3.1 暗黙のフィールド定義変更」節参照. 「6.2.3.2 `BLOB` と `TEXT` 型」節参照.
`MEDIUMBLOB`
`MEDIUMTEXT`
  最大長 16777215 (2^24 - 1) 文字の `TEXT`/`BLOB`。 「6.5.3.1 暗黙のフィールド定義変更」節参照. 「6.2.3.2 `BLOB` と `TEXT` 型」節参照.
`LONGBLOB`
`LONGTEXT`
  最大長 4294967295 (2^32 - 1) 文字の `TEXT`/`BLOB`。 「6.5.3.1 暗黙のフィールド定義変更」節参照。注意: サーバ／クライアントプロトコルと MyISAM テーブルは、通信パケット単位 / テーブルレコードで、現在 16M の制限 があるため、この型の範囲全体はまだ使用できません。 「6.2.3.2 `BLOB` と `TEXT` 型」節参照。
`ENUM('value1','value2',...)`
  列挙。 対象となる文字列は、値を一つだけ持ち、値リスト`'value1', 'value2',...`(又は `NULL`)から選ばれます。`ENUM`は最大65535個の固有値を持つことができます 。 「6.2.3.3 `ENUM` 型」節参照.
`SET('value1','value2',...)`
  組。 対象となる文字列は0以上の値を持ち、それぞれ値リスト`'value1', 'value2',...` から選ばれなければなりません。 `SET`は、最大 64個の要素を持つことができます。 「6.2.3.4 `SET` 型」節参照.

### 6.2.1 数値型

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

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

        salary DECIMAL(9,2)

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

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

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

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

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

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

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

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

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

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

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

### 6.2.2 日付と時間の型

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

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

- MySQLは、標準形式で与えられた日付や時間から値を抽出しますが、与えられた 多様な形式の値(例えば、指定された値を日付や時間型に割り当てたり、比較したり)を解 釈しようと試みます。 それでも、次節で述べる形式だけがサポートされます。 それは、正当な値が与えられることを期待し、他の形式の値を使用されるような事態が起 こると、どのような結果となるか予想できません。
- MySQL はいくつかの形式に値を変えてくれますが、 常に年の部分と日にちの部分は左から与えられていると期待しています。 日付は 年-月-日 の順(例えば、`'98-09-04'`)でなくてはなりません。 月-日-年 や 日-月-年 の様などこでも使われているような形であってはなりません。 (例えば、`'09-04-98'`や`'04-09-98'`).
- MySQL は、もし数値の文脈で日付と時間の型が使用されると、 自動的に日付と時間を数値に直します。逆も行います。
- MySQL が範囲外の誤った値を日付と時間型として受け取った場合 (このセクションの最初をみてください)、その値は ``ゼロ'' に変換されます。 (例外は、範囲外の`TIME`値が適切な`TIME`の範囲の限界値に切り詰められる ことです。) 以下に、それぞれの型の `ゼロ' の形式を示します：

  フィールドタイプ | `ゼロ'値
  `DATETIME` | `'0000-00-00 00:00:00'`
  `DATE` | `'0000-00-00'`
  `TIMESTAMP` | `00000000000000` (長さは表示サイズに依存し ます)
  `TIME` | `'00:00:00'`
  `YEAR` | `0000`

- `ゼロ'値は特別ですが、表に示された値を明示的に使用して、格納したり参照したりでき ます。 この値は、 `'0'` 又は `0` を使用することにより、より簡潔に書くこともで きます。
- MyODBC 内で使用されている `ゼロ' の日付と時間は、 MyODBC 2.50.12 以上では自動的に `NULL` に変換されます。 これは ODBC がこれらの値を扱えないからです。

#### 6.2.2.1 西暦２０００年問題とデータ型

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

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

- `00-69` の範囲の年は `2000-2069` に変換。
- `70-99` の範囲の年は `1970-1999` に変換。

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

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

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

#### 6.2.2.2 `DATETIME`, `DATE`, `TIMESTAMP` 型

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

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

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

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

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

- そのフィールドが明示的に `INSERT` または `LOAD DATA INFILE` 文で指定さ れていないとき。
- そのフィールドが明示的に `UPDATE` 文で指定されず、かつ、他のフィールドの値 が変わった場合。 (もともとフィールドに入っていた値と同じ値に更新しようとする `UPDATE` 文は `TIMESTAMP` フィールドを更新しないことに注意。なぜならあるフィールドを現在 と同じ値に変えようとしても MySQL は効率のためにそれを無視するからです。)
- 明示的に `TIMESTAMP` フィールドを `NULL` にした場合。

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

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

- MySQL にレコードが生成されたときにそのフィールドをセットさせる。これで 現在日時に初期化される。
- 以降の他のフィールドに対する更新時に `TIMESTAMP` フィールドをそれ自体が今持 っている値に明示的に更新する。

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

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

MySQL が `TIMESTAMP` 値を取り出したり表示するのに使うフォーマット は以下の表 に示すようにその表示サイズに依存します。「目一杯の」 `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` 値は以下の共通フォーマットセット のいずれかを使って指定できます：

- 文字列で `'YYYY-MM-DD HH:MM:SS'` か `'YY-MM-DD HH:MM:SS'` の形式。 "柔軟な"書き方を許しています -- 日付や時刻の区切り文字として、いかなる句読記号 も使用できます。例えば、`'98-12-31 11:30:45'`, `'98.12.31 11+30+45'`, `'98/12/31 11*30*45'`, `'98@12@31 11^30^45'` は等価です。
- 文字列で `'YYYY-MM-DD'` か `'YY-MM-DD'` の形式。 これも"柔軟な"書き方ができます。 例えば, `'98-12-31'`,`'98.12.31'`, `'98/12/31'`, `'98@12@31'` は 等価です。
- 文字列 `'YYYYMMDDHHMMSS'` または `'YYMMDDHHMMSS'` フォーマット。 「緩やかな」文法が認められていて、句読記号は日付、時刻部分の区切り として使えます。例えば `'98-12-31 11:30:45'`, `'98.12.31 11+30+45'`, `'98/12/31 11*:30*:45'`, `'98@12@31 11^30^45'` は全て等価です。
- 文字列 `'YYYY-MM-DD'` または `'YY-MM-DD'` フォーマット。 これも「緩やかな」文法が認められています。例えば `'98-12-31'`, `'98.12.31'`, `'98/12/31'`, `'98@12@31'`は全て等価です。
- 区切り文字なしの文字列 `'YYYYMMDDHHMMSS'` または `'YYMMDDHHMMSS'` フォ ーマットで日時として意味のあるもの。 例えば `'19970523091528'` および `'970523091528'` は `'1997-05-23 09:15:28'` と解釈されます。しかし `'971122129015'` は無効で (時と分の部分がおかしい)、 `'0000-00-00 00:00:00'` になります。
- 区切り文字なしの文字列 `'YYYYMMDD'` または `'YYMMDD'` フォーマットで、 日付として意味のあるもの。 例えば `'19970523'` および `'970523'` は `'1997-05-23'` と解釈 されます。 しかし `'971332'` は無効で(月と日の部分がおかしい)、 `'0000-00-00'` になります。
- `YYYYMMDDHHMMSS` または `YYMMDDHHMMSS` のフォーマットの数値で、日時と して意味のあるもの。例えば `19830905132800` および `830905132800` は `'1983-09-05 13:28:00'` と解釈されます。
- `YYYYMMDD` または `YYMDD` のフォーマットの数値で日付として意味のある もの。 例えば `19830905` および `830905` は `'1983-09-05'` として解釈さ れます。
- `NOW()` や `CURRENT_DATE` のように `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 は「ゼロ」日付 をテーブルに挿入します。これは年と月の部分は `99` と `03` ですが日の部 分が欠けている(ゼロ)ために値が有効な日付でないために起こります。

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

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

- 列の型がTIMESTAMP(4)であってもTIMESTAMP(2)であっても常に年月日を指定 すること。そうでなければ値は無効で0が格納されます。
- もし短い形式の `TIMESTAMP` を `ALTER TABLE` を使って拡張しようとした場 合、拡張前には「隠れていた」情報が現れます。
- 同様に `TIMESTAMP` フィールドを縮めた場合も、値が表示された時により少ない情 報しか現れないという点を除いて、情報は失われません。
- `TIMESTAMP` 値は最高精度の時間分解能で格納されますが、内部的に格納され た値を直接操作できる関数は `UNIX_TIMESTAMP()` のみです。他の関数はフォーマ ットされて取り出された値について操作します。つまり、 `HOUR()` や `SECOND()` などの関数は `TIMESTAMP` 値の対応する部分がフォーマットされた 値で含まれないと使うことができません。例えば `TIMESTAMP` 列の `HH` の部分は 表示サイズが少なくとも10以上ないと表示されないので、それより短い `TIMESTAMP` 値 に `HOUR()` の操作を行っても無意味な値しか得られません。

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

- `DATE` の値を `DATETIME` か `TIMESTAMP` の物に与えた場合、 時刻の部分は `'00:00:00'` になります。これは `DATE` 値が 時刻の情報を持っていないからです。
- `DATETIME` か `TIMESTAMP` の値を `DATE` の物に与えた場合、 時刻の部分は削られます。これは `DATE` 値が 時刻の情報を持っていないからです。
- `DATETIME`, `DATE`, `TIMESTAMP` 値は同じフォーマットのセットを使 って表現できますが、どの型も同じ値の範囲を持っているわけではないことを覚えておい てください。例えば `TIMESTAMP` 値は `1970` 年より前や `2037` 年よ り後の値にはできません。つまり `'1968-01-01'` という値は `DATETIME` や `DATE` の値としては有効ですが `TIMESTAMP` の値としては無効で、 そのようなオブジェクトを指定した場合は `0` に変換されます。

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

- 文字列として指定される値の柔軟なフォーマットに騙されないよう。例え ば `'10:11:12'` は ``':''` を区切り文字とする時刻のように見えますが、日 付のコンテキストで使われるとこれは `'2010-11-12'` と解釈されます。 `'10:45:15'` は `'45'` が有効な月ではないので `'0000-00-00'` に 変換されます。
- 2桁で表される年は世紀の部分が不明なので曖昧です。 MySQL は以下のルール で2桁の年を解釈します。
  - `00-69` の範囲にある年の値は `2000-2069` 年とする。
  - `70-99` の範囲にある年の値は `1970-1999` 年とする。

#### 6.2.2.3 `TIME` 型

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

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

- 文字列で `'D HH:MM:SS.fraction'` というフォーマット。 (MySQLはまだこの fraction を time フィールドに保存できません)。 以下の ``柔軟な'' 文法が使用できます： `HH:MM:SS.fraction`, `HH:MM:SS`, `HH:MM`, `D HH:MM:SS`, `D HH:MM`, `D HH` または `SS`。 ここで、`D` は 0〜33 の間の日です。
- 文字列で `'HHMMSS'` というように区切りのないフォーマットで時刻として有効 なもの。例えば `'101112'` は `'10:11:12'` と解釈されますが `'1097 12'` は無効で(分の部分が無意味) `'00:00:00'` になります。
- 数値で `HHMMSS` のフォーマットで時刻として有効なもの。 例えば `101112` は `'10:11:12'` と解釈されます。 次の別の形式も解釈できます: `SS`, `MMSS`,`HHMMSS`, `HHMMSS.fraction`。注意: MySQL はまだ fraction 部を保存でき ません。
- 例えば `CURRENT_TIME` のように `TIME` のコンテキストで受け付けられる値 を返す関数の結果。

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

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

#### 6.2.2.4 `YEAR` 型

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

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

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

- `'1901'` から `'2155'` の範囲にある4桁の文字列
- `1901` から `2155` の範囲にある4桁の数値。
- `'00'` から `'99'` の範囲にある2桁の文字列。 `'00'` から `'69'` までおよび `'70'` から `'99'` までの範囲はそれぞれ `2000` から `2069` まで および `1970` から `1999` までの範囲の YEAR型に変換されます。
- `1` から `99` の範囲にある2桁の数値。`1` から `69` まで および `70` から `99` までの範囲は それぞれ `2001` から `2069` までおよび `1970` から `1999` まで の範囲の `YEAR` 型に変換されます。 2桁の数値の場合は2桁の文字列の場合と若干異なっている点に注意してください。 なぜなら0を数値として指定し、それを2000年として解釈させることができないからです。 その場合は文字列で `'0'` または `'00'` を指定しなければ なりません。そうでなければ数値0は無効なYEAR値を示す `0000` に変換されます。
- 例えば `NOW()` のように `YEAR` コンテキストで受け入れられる値を返す関 数の結果。

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

### 6.2.3 文字列型

文字列型は`CHAR`, `VARCHAR`, `BLOB`, `TEXT`, `ENUM`, `SET` です。このセクションは、それらの型がどのように動作 するかと、要求されるサイズと、クエリ内での使用方法を説明します。

#### 6.2.3.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)` および `VARCHA R(4)` に様々な文字列値を格納した結果を示すことで表しています。

値 | `CHAR(4)` | 必要な格納域 | @code {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` であると指定された フィールドが式の中にあると式全体が `BINARY` の値として比較されるのです。

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

#### 6.2.3.2 `BLOB` と `TEXT` 型

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

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

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

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

- MySQL バージョン 3.23.2 以上では、`BLOB` と `TEXT` 項に インデックスを持つことが出来ます。それ以前のバージョンでは インデックスをもつことが出来ません。
- `VARCHAR` フィールドで行っているようには、`BLOB` と `TEXT` フィー ルドの値の後ろについている連続した空白文字は切り落とされません。
- `BLOB` と `TEXT` 項は `DEFAULT` 値を持つことが出来ません。

`MyODBC` は `BLOB` を `LONGVARBINARY` として、 `TEXT` を `LONGVARCHAR` として定義します。

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

- もし `GROUP BY` か `ORDER BY` を `BLOB` フィールドや `TEXT` フィールドで使用したいなら、フィールドの値を固定長のものに変換しなくてはなりま せん。標準的な方法は、 `SUBSTRING` 関数を使用することです。 たとえば：

      mysql> select comment from tbl_name,substring(comment,20) as substr
             ORDER BY substr;

  もしこれをしない場合、フィールドの最初の `max_sort_length` バイトが ソート時に使用されます。 `max_sort_length` のデフォルト値は 1024; この値は `mysqld` サーバー起動時に `-O` オプションを使用することで 変更できます。 フィールドの位置を指定することによってか、エイリアスを使用することによって、 `BLOB` や `TEXT` の値で group 化できます。

      mysql> select id,substring(blob_col,1,100) from tbl_name
                 GROUP BY 2;
      mysql> select id,substring(blob_col,1,100) as b from tbl_name
                 GROUP BY b;

- `BLOB` または `TEXT` オブジェクトの最大長はその型により決定されますが、 あなたがクライアントとサーバの間で実際に送ることができるは最大長は、 利用可能なメモリ量とコミュニケーションバッファのサイズによって決定されます。 メッセージバッファサイズを変えることができますが、その場合、サーバーとクライアン ト、両方共に変更しなければなりません。 「5.5.2 サーバーパラメーターのチューニング」節参照.

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

#### 6.2.3.3 `ENUM` 型

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

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

- もし `ENUM` に無効な値 (列挙されている値の中に含まれない文字) を 代入した場合、 そのエラーになる文字の代わりに空文字が挿入されます。
- もし `ENUM` が `NULL` と定義された場合, `NULL` はそのフィールドで 許可される値となり、デフォルト値が `NULL` になります。 もし `ENUM` が `NOT NULL` と定義されたならば、 デフォルト値は、 列挙リストの最初の値になります。

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

- 列挙リストの要素は 1 から付番されます。
- 空文字エラーのインデックス値は 0 。 これは不正な `ENUM` 値が与えられているレコードを見つけるために 以下のような `SELECT` 構文が使用できることを意味します：

      mysql> SELECT * FROM tbl_name WHERE enum_col=0;

- `NULL` のインデックス値は `NULL`.

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

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

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

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

もし `ENUM` を数値の文脈で検索した場合、そのメンバーを前から数えた 時の順番が数値で返ってきます。 たとえば、`ENUM` フィールドから次のようにして数値を取り出すことができ ます:

    mysql> SELECT enum_col+0 FROM tbl_name;

もし `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` 定義を分析します。

#### 6.2.3.4 `SET` 型

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

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

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

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

MySQL は `SET` の値を数値として代入します。代入された 値の最下位のビットが最初のメンバーに対応します。もし `SET` 値を 数値の文脈で検索した場合、検索される値はフィールドの値に対応します。 たとえば、`SET` フィールドから次のようにして数値を取り出すことができ ます:

    mysql> SELECT set_col+0 FROM tbl_name;

もし数値が `SET` フィールドに代入された場合、 二進数で表される数値のビットによって、メンバーが決定されます。 `SET("a","b","c","d")` とフィールドが定義されたとします。 メンバーは以下の２進数の値を持ちます：

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

もしこのフィールドに `9` を与えた場合、これは２進数で `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` 値の前にソートされます。

通常、`LIKE` か `FIND_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` とし、 ２番目にあらわされる `SET` 定義を分析します。

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

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

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

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

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

ほかのベンダーから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 の型を用いて テーブルを構成したことを告げます。

### 6.2.6 各フィールド型の所要容量

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

#### 6.2.6.1 数値タイプの保存容量

フィールドタイプ | 所要容量
`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)` | D > 0 の場合 `M+2`, D = 0 の場合 `M+1` bytes (`M < D` の場合 `D`+2)
`NUMERIC(M,D)` | D > 0 の場合 `M+2`, D = 0 の場合 `M+1` bytes (`M < D` の場合 `D`+2)

#### 6.2.6.2 日付と時間タイプの保存容量

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

#### 6.2.6.3 文字列タイプの保存容量

フィールドタイプ | 所要容量
`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 )

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

`BLOB`と`TEXT`型は、フィールド値の長さを記録するのに、１、２、３、又は ４バイト必要とし、型のとり得る最大の長さに依存します。 「6.2.3.2 `BLOB` と `TEXT` 型」節参照.

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

`ENUM`オブジェクトのサイズは、異なる列挙値の数によって決められます。 列挙する数が255以内では、１バイトが使用されます。 列挙する数が65535以内では、２バイトが使用されます。 「6.2.3.3 `ENUM` 型」節参照.

`SET`オブジェクトのサイズは、異なる要素の数によって決められます。 組のサイズを`N`とすると、オブジェクトは`(N+7)/8`バイトを占有し、 １、２、３、４又は８バイトに切上げられます。 １つの`SET`は、最大６４要素を持つことができます。 「6.2.3.4 `SET` 型」節参照.

## 6.3 `SELECT` と `WHERE` 節で使用する関数

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

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

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

`mysqld` に `--ansi` をつけて起動するか、 `CLIENT_IGNORE_SPACE` を `mysql_connect()` に使用すれば、 MySQL が関数名の後の空白を許すようになりますが、その場合、すべて の関数名が予約語になります。 「1.4.3 ANSI モードでの MySQL の実行」節参照。

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

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

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

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

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

### 6.3.1 Non-Type-Specific Operators and Functions

#### 6.3.1.1 Parenthesis

    ( ... )

Use parenthesis to force the order of evaluation in an expression. For example:

    mysql> select 1+2*3;
            -> 7
    mysql> select (1+2)*3;
            -> 9

#### 6.3.1.2 比較演算子

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

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

- どちらかまたは両方の引数が `NULL` の場合は、比較結果は `NULL` です。`<=>` 演算子を除きます。
- 比較操作の両方の引数が文字列の場合、文字列として比較されます。
- 両方の引数が整数の場合、整数として比較されます。
- 16進数の値は、もし数値と比較されないのであれば、文字列として扱われます。
- 引数の一方が `TIMESTAMP` または `DATETIME` フィールドで、他の引数が 定数の場合は、定数は比較前に timestamp に変換されます。これはより ODBC フレンドリにするためです。
- 他の場合は全て浮動小数点(real)として比較されます。

文字列の比較は、ケースに依存せず、標準のキャラクターセットに従って 行われます。(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;
              -> 0

`>=`
  より大きいか等しい:

      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`
  もし `expr` が `min` 以上、 `max` 以下なら `1`を返します。 そうでないなら `0` を返します。 これは 全ての引数が同じ型ならば、`(min <= expr AND expr <= max)` と同じです。 最初の引数 (`expr`) はいかのように比較方法を決定します。
  - もし `exor` が `TIMESTAMP`, `DATE`, `DATETIME` フィー ルドなら、最小と最大はそれらが定数の場合と同じフォーマットになります。
  - もし `expr` が文字式なら、ケース非依存で比較が行われます。
  - もし `expr` がバイナリ文字なら、ケース依存で比較が行われます。
  - もし `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,...)`
  もし `expr` が `IN` リストにある値のどれかならば、`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)`
  `expr` が `NULL` なら `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

If you are comparing case sensitive string with any of the standard operators (`=`, `<>`..., but not `LIKE`) end space will be ignored.

    mysql> select "a" ="A ";
            -> 1

#### 6.3.1.3 論理演算

全ての論理関数は `1` (TRUE) か `0` (FALSE) か `NULL` を返します。 (unknown は多くの場合 FALSE と同じです)：

`NOT`
`!`
  論理否定。引数が `0` なら `1` を返し、そうでなければ `0` を返しま す。 例外: `NOT NULL` は `NULL` を返します:

      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

#### 6.3.1.4 フロー制御関数

`IFNULL(expr1,expr2)`
  `expr1` が `NULL` でない場合は `expr1` を、そうでなければ `expr2` を返します。 `IFNULL()` はどの文脈で使用されたかにより数値か文字を返します:

      mysql> select IFNULL(1,0);
              -> 1
      mysql> select IFNULL(NULL,10);
              -> 10
      mysql> select IFNULL(1/0,10);
              -> 10
      mysql> select IFNULL(1/0,'yes');
              -> 'yes'

`NULLIF(expr1,expr2)`
  `expr1 = expr2` が真なら、`NULL` を返し、そうでなければ `expr1` を返します。 これは `CASE WHEN x = y THEN NULL ELSE x END` と同じです:

      mysql> select NULLIF(1,1);
              -> NULL
      mysql> select NULLIF(1,2);
              -> 1

  注意: 引数が等しい場合、`expr1` は MySQL では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'

  `expr1` は `INTEGER` として評価されます。これは浮動小数点を使用する 場合、比較演算も使用すべきであることを意味します:

      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 では次のように計算されます:

  Expression | Return value
  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

戻り値の型(`INTEGER`, `DOUBLE`, `STRING`)は最初に返される値 (最初の `THEN` の後の式)の型と同じです。

### 6.3.2 文字列関数

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

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

`ASCII(str)`
  `str` の左端の文字の ASCII コード値を返します。 `str` が空文字の場合は `0` を返します。 `str` が `NULL` の場合は `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)`
  数字を、進数の違う数字に変換します。 数 `N` を `from_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)` と同じです。 `N` が `NULL` なら `NULL` を返します:

      mysql> select BIN(12);
              -> '1100'

`OCT(N)`
  `N` の8進数値を表す文字列を返します。`N` は longlong 数値です。 これは `CONV(N,10,8)` と同じです。`N` が `NULL` の場合は `NULL` を返します:

      mysql> select OCT(12);
              -> '14'

`HEX(N)`
  `N` の16進数値を表す文字列を返します。`N` は longlong(`BIGINT`) 数値です。これは `CONV(N,10,16)` と同じです。 `N` が `NULL` の場合は `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` は検索を開始する位置です。 `str` に `substr` がなければ `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` を埋めます。 `str` が `len` よりも長い場合は、`len` 文字に短くされます。

      mysql> select LPAD('hi',4,'??');
              -> '??hi'

`RPAD(str,len,padstr)`
  `str` の長さが `len` になるまで文字列 `str` の終わりに `padstr` を埋めます。 `str` が `len` よりも長い場合は、`len` 文字に短くされます。

      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)`
  `str` の `pos` 位置から `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);
              -> 'barbar'

  この関数はマルチバイトでも安全です。
`SUBSTRING_INDEX(str,delim,count)`
  `str` から、区切り文字 `delim` が `count` 個現れた位置から前の 文字列を返します。`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'

  This function is multi-byte safe.
`SOUNDEX(str)`
  `str` からの soundex 文字列を返します。発音が``大体同じ''２つの文字列 は同じ 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_str` を `to_str` に 置き換えます:

      mysql> select REPLACE('www.mysql.com', 'w', 'Ww');
              -> 'WwWwWw.mysql.com'

  この関数はマルチバイトでも安全です。
`REPEAT(str,count)`
  `str` を `count` 回繰り返します。`count <= 0` の場合は 空の文字列を返します。`str` または `count` が `NULL` または、`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` を 返します。 `N` が `1` より小さい場合、または引数の数より大きい場合は `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)`
  `str` が `strlist` 中にあれば、値 `1` から `N` を返します。 `strlist` は、それぞれの異なる値が ',' で分割された文字列です。最初の 引数が定数文字列で２番目が `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'

  This function is multi-byte safe.
`UCASE(str)`
`UPPER(str)`
  `str` を現在のキャラクターセットマッピング (デフォルト ISO-8859-1 Latin1) にしたがって大文字に変換します:

      mysql> select UCASE('Hej');
              -> 'HEJ'

  This function is multi-byte safe.
`LOAD_FILE(file_name)`
  ファイルを読み込み、ファイルの中身を文字として返します。 ファイルは サーバー上になくてはならず、ファイルをフルパスで指定しなければなりません。 そして、 file 権限がなければなりません。 ファイルは全員に 読み込み可能でなければならず、そして、 `max_allowed_packet` より 小さいサイズでなければなりません。 このうちどれかの理由で、もしファイルが存在しないか読み込めない場合、 この関数は `NULL` を返します:

      mysql> UPDATE table_name
                 SET blob_column=LOAD_FILE("/tmp/picture")
                 WHERE id=1;

MySQL 3.23 を使用していない場合、あなたのアプリケーション内部でファ イルを読み込んで、ファイル情報でデータベースを更新するための `INSERT` ステートメントを生成する必要があります。これを行なう一つの方 法は、MySQL++ ライブラリを使用する場合、 http://www.mysql.com/documentation/mysql++/mysql++-examples.html で 見つけられます。

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

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

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

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

#### 6.3.2.1 文字列比較関数

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

`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

  次の２つのステートメントは、オペランドの一つがバイナリ文字列でなければ、文 字列比較がケース非依存であることを示しています:

      mysql> select 'abc' LIKE 'ABC';
              -> 1
      mysql> SELECT 'abc' LIKE BINARY 'ABC';
              -> 0

  `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'])` と同じ
`expr REGEXP pat`
`expr RLIKE pat`
  パターン `pat` に対し、文字式 `expr` のパターンマッチを行います。 パターン `pat` は正規表現の拡張が使用できます。 「I MySQL の正規表現の文法について」節参照. もし `expr` が `pat` にマッチするなら `1` を返し、 でなければ `0` を返します。 `RLIKE` は `REGEXP` と同義で、`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
      mysql> select "a" REGEXP "^[a-d]";
              -> 1

``
  `REGEXP` and `RLIKE` は、文字の型を決定する場合、 カレントのキャラクターセットを使用します。 (ISO-8859-1 Latin1 がデフォルト)
`expr NOT REGEXP pat`
`expr NOT RLIKE pat`
  `NOT (expr REGEXP pat)` と同じ.
`STRCMP(expr1,expr2)`
  `STRCMP()` 文字列が同じなら `0` を返します。そうでなければ、最初の引数がソート順で小 さければ `-1` を返します。そうでなければ `1` を返します:

      mysql> select STRCMP('text', 'text2');
              -> -1
      mysql> select STRCMP('text2', 'text');
              -> 1
      mysql> select STRCMP('text', 'text');
              -> 0

`MATCH (col1,col2,...) AGAINST (expr)`
  `MATCH ... AGAINST()` は全文検索に使用され、妥当性を返します。フィー ルド `(col1,col2,...)` 内のテキストとクエリ `expr` との間の類似 点を評価します。妥当性は正の浮動小数点数です。妥当性 0 は類似点なしを意味 します。`MATCH ... AGAINST()` が動作するためには、最初に FULLTEXT インデックスが作成する必要があります。 「6.5.3 `CREATE TABLE` 構文」節参照。 `MATCH ... AGAINST()` は MySQL 3.23.23 以上のバージョンで有 効です。詳細と使用例は 「6.8 MySQL Full-text Search」節参照.

#### 6.3.2.2 Case Sensitivity

``BINARY``
  `BINARY` 演算子は、これ以降に続く文字をバイナリにキャストします。 これはたとえフィールドが `BINARY` や `BLOB` 定義でなくても、 ケース依存でフィールドを比較することが出来る簡単な方法です:

      mysql> select "a" = "A";
              -> 1
      mysql> select BINARY "a" = "A";
              -> 0

  `BINARY` は MySQL 3.23.0 で登場しました。 注意: いくつかの文脈では、インデックスされたフィールドを `BINARY` に キャストした時、MySQL はインデックスを効率よく使用できません。

BLOB をケース非依存で比較したい場合、比較を行なう前に BLOB を常に大文字に 変換します:

    SELECT 'A' LIKE UPPER(blob_col) FROM table_name;

より柔軟に文字列を比較するために、我々は間もなく異なる文字セット間のキャス トを導入する予定です。

### 6.3.3 Numeric Functions

#### 6.3.3.1 算術演算

普通の算術演算が有効です。 `-`, `+`, `*` は、二つの引数が正数ならば `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` を用いて割り算は計算されます。

#### 6.3.3.2 数学関数

すべての数学関数はエラーの場合 `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 の `%` 演算子のような ). `N` を `M` で割ったときの余りが返ります:

      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

  引数が２つの整数間の半分時の `ROUND()` の振る舞いは、C ライブラリの実 装に依存します。いくつかは、近い偶数値、常に上、常に下、または常に０方向に 丸めます。丸めの種類の一つを必要とする場合は、`TRUNCATE()` または `FLOOR()` のようなはっきりと定義された関数を代わりに使用すべきです。
`ROUND(X,D)`
  `X` を `D` で指定した少数桁に丸めた値(四捨五入)を返します。 もし `D` が `0` なら, 結果は小数点無しになるか 少数部分になるでしょう:

      mysql> select ROUND(1.298, 1);
              -> 1.3
      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

  任意の底 `B` に対する `X` の対数を得たければ、公式 `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)`
  `X` の `Y` 乗:

      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()`
  π の値を返します。デフォルトの表示桁数は 5 ですが、MySQL 内部で は π に完全な倍精度を使用します。

      mysql> select PI();
              -> 3.141593
      mysql> SELECT PI()+0.000000000000000000;
              -> 3.141592653589793116

`COS(X)`
  コサイン `X`。`X` はラジアン:

      mysql> select COS(PI());
              -> -1.000000

`SIN(X)`
  サイン `X`。`X` はラジアン:

      mysql> select SIN(PI());
              -> 0.000000

`TAN(X)`
  タンジェント `X`。`X` はラジアン:

      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

`ATAN(Y,X)`
`ATAN2(Y,X)`
  ２つの変数 `X` と `Y` のアークタンジェントを返します。両方の引数 の符号が結果の象限を決定するために使用されることを除いて、`Y / X` の アークタンジェントの計算と同様です:

      mysql> select ATAN(-2,2);
              -> -0.785398
      mysql> select ATAN2(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,...)`
  二つ以上の引数を取り、引数中、最小の値を返します。 引数は以下の規則に従って比較されます：
  - 値が `INTEGER` を使用しているなら、あるいは、全ての引数が 整数値ならば、整数として比較します。
  - 値が `REAL` として使用されているか、全ての引数が実数ならば、 実数として比較します。
  - いかなる引数もケース依存の文字ならば、引数はケース依存文字として比較されます。
  - そのほかの場合、引数はケース非依存文字として比較されます:

      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` を切り捨てた値を返します。 `D` が `0` の場合、結果は小数部や微小部を持ちません:

      mysql> select TRUNCATE(1.223,1);
              -> 1.2
      mysql> select TRUNCATE(1.999,1);
              -> 1.9
      mysql> select TRUNCATE(1.999,0);
              -> 1

  注意: コンピュータでは小数点数は正確な数値としては格納されず、double 値と して格納されます。次の結果によってだまされるでしょう:

      mysql> select TRUNCATE(10.28*100,0);
             -> 1027

  上記は 10.28 は実際には 10.2799999999999999 のようなものとして格納さえるた めに発生します。

### 6.3.4 日付と時刻関数

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

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

    mysql> SELECT something FROM table
               WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;

`DAYOFWEEK(date)`
  Returns the weekday index `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`): `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)`
  期間 `P1` と `P2` の差の月を返します。`P1` と `P2` は形 式 `YYMM` または `YYYYMM` です。 注意: 期間引数 `P1` と `P2` は日付値ではありません。

      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` には、`DATETIME` か `DATE` 型の値を指定します。 この値から演算が開始されます。 `expr` には、date から増減させる値を指定します。 `expr` が ``-'` から始まっていれば、負数を示します。 `type` はどれぐらいの期間かを示すキーワードです。 `EXTRACT(type FROM date)` 関数は、date から 'type' の部分を返します。 以下の表に、`type` と `expr` の関連を示します：

  `type` value | Expected `expr` format
  `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

  もしあなたの指定する interval 値が短すぎるなら( `type` キーワードから 類推される値を含んでいない場合)、 MySQL は interval 値の一番 左の部分を指定し忘れたものだと仮定します。 例えば、もし `type` を `DAY_SECOND` に指定した場合、 `expr` の値は 日、時、分、秒 からなる物と期待されます。 ここであなたが `"1:10"` のような値を指定していたなら、 MySQL は、日、時 の部分が忘れ去られて、分、秒 が与えられたと 推定します。 つまり、 `"1:10" DAY_SECOND` は `"1:10" MINUTE_SECOND` で あると理解されるのです。 これは、MySQL が `TIME` 値を時刻ではなく経過時間の表現と解釈 する方法に類似しています。 注意: 時刻部を含む何かに対して、日付値の加算や減算を行なう場合、日付値は自 動的に日時値に変換されます:

      mysql> select date_add("1999-01-01", interval 1 day);
             -> 1999-01-02
      mysql> select date_add("1999-01-01", interval 1 hour);
             -> 1999-01-01 01:00:00

  もし、不正な値が使用されたなら、結果は `NULL` です. もし `MONTH` や `YEAR_MONTH` や `YEAR` を足し算して、 結果となる日付が新しい月の最大日よりも大きい日になるようなら、 その日は、新しい月の最大日に修正されます。

      mysql> select DATE_ADD('1998-01-30', Interval 1 month);
              -> 1998-02-28

  例のように、`INTERVAL` と `type` キーワードは ケース依存ではありません.
`EXTRACT(type FROM date)`
  The `EXTRACT()` function uses the same kinds of interval type specifiers as `DATE_ADD()` or `DATE_SUB()`, but extracts parts from the date rather than performing date arithmetic.

      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

`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)`
  与えられた日数 `N` から `DATE` 値を返します:

      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_TIMESTAMP` が `TIMESTAMP` フィールドに使用された場合、 この関数は、暗黙の ``文字から UNIX タイムスタンプ'' 変換をすることなく、 値を得ます。 If you give `UNIX_TIMESTAMP()` a wrong or out-of-range date, it will return 0.
`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 文字列を返します。 `format` は `DATE_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

### 6.3.5 その他の関数

#### 6.3.5.1 ビット関数

これらは最大 64 ビットの範囲を持ちます。MySQL は `BIGINT` (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` がいくつビットを持っているか(２進数表記したときの１の数):

      mysql> select BIT_COUNT(29);
              -> 4

#### 6.3.5.2 その他の関数

`DATABASE()`
  現在のデータベース名を返します

      mysql> select DATABASE();
              -> 'test'

  もしデータベースが選択されていないなら、`DATABASE()` は空文字を返します。
`USER()`
`SYSTEM_USER()`
`SESSION_USER()`
  Returns the current MySQL user name:

      mysql> select USER();
              -> 'davida@localhost'

  MySQL バージョン 3.22.11 以降では、この関数はユーザー名とクライアントの ホスト名を含みます。 ユーザー名の部分だけ取り出すには次のようにします。 （これはホスト名が含まれていなくとも動くでしょう）：

      mysql> 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()`を使用します。 結果はバイナリ文字列で、長さは `string` と同じです。 フィールドにそれを保存したい場合は `BLOB` フィールド型を使用してください。
`DECODE(crypt_str,pass_str)`
  暗号化された文字列 `crypt_str` をパスワードとして `pass_str` を 用いて復号化します。`crypt_str` は `ENCODE()` から返された文字列 であるべきです。
`MD5(string)`
  文字列を MD5 チェックサムした結果を返します。 値は 32 桁の 16進表示です。 例えばハッシュキーとして使用できるように:

      mysql> select MD5("testing");
              -> 'ae2b1fca515949e5d54fb22b8ed95575'

  これは "RSA Data Security, Inc. MD5 Message-Digest Algorithm".
`LAST_INSERT_ID([expr])`
  最後に `AUTO_INCREMENT` フィールドに挿入されて自動的に生成された値を返しま す。 「8.4.3.126 `mysql_insert_id()`」節参照.

      mysql> select LAST_INSERT_ID();
              -> 195

  最後の作成された ID はそれぞれのコネクション毎にサーバーに維持されます。 これは他のクライアントからは変更できないでしょう。 もし他の非マジック値をもつ `AUTO_INCREMENT` フィールド （値が `NULL` でも `0` でもないということ） を更新しても、これは 変更されません。 一つの INSERT 文で同時に多くのレコードを挿入する場合、 `LAST_INSERT_ID()` は最初に挿入されたレコードの値を返します。この理由 は、他のサーバに対して同じ `INSERT` を簡単に再現できるようにするため です。 If `expr` is given as an argument to `LAST_INSERT_ID()`, then the value of the argument is returned by the function, is set as the next value to be returned by `LAST_INSERT_ID()` and used as the next auto_increment value. これは シーケンス番号のシミュレーションに使用できます： 最初にテーブルを作成：

      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()` もこの値を得るために使用できます。 Note that as `mysql_insert_id()` is only updated after `INSERT` and `UPDATE` statements, you can't use this function to retrieve the value for `LAST_INSERT_ID(expr)` after executing other SQL statements like `SELECT` or `SET`.
`FORMAT(X,D)`
  `'#,###,###.##'` のような形式(小数部 `X` 桁)で数値 `D` を整形 します。 もし `D` が `0` なら, 結果にはいかなる 小数点も小数部も含まれません。

      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

  ２つ目の `RELEASE_LOCK()` は `NULL` を返します。 なぜなら、 `"lock1"` は、２つ目の `GET_LOCK()` の呼び出し時点で、 自動的に解放されるからです。
`RELEASE_LOCK(str)`
  `GET_LOCK` で獲得したロック `str` を解放します。ロックが解 放された場合は `1`, このスレッドによってロックされていない場合は `0` (この場合、ロックは解放されません), `str`が存在しない場合は `NULL` が返ります。 もし、 `GET_LOCK()` をコールして得られなかった場合、 あるいは、既に解放されている場合は、ロックは存在しないでしょう。 The `DO` statement is convinient to use with `RELEASE_LOCK()`. 「6.4.9 `DO` Syntax」節参照.
`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_ATON(expr)`
  ネットワークアドレスに対する数値を表す整数を返します。アドレスは 4 または 8 バイトアドレスです:

      mysql> select INET_ATON("209.207.224.40");
             ->  3520061480

  生成された数値は常にネットワークバイトオーダです; たとえば、上記の数値は `209*255^3 + 207*255^2 + 224*255 +40` として計算されます。
`MASTER_POS_WAIT(log_name, log_pos)`
  複製の間、マスターログの指定された位置にスレーブが到達するまでブロックしま す。マスター情報が初期化されていない場合、NULL が返ります。スレーブが動作 していない場合ブロックし、スレーブが起動し、指定位置にくるまで待ちます。ス レーブが既に指定位置を通り過ぎていた場合、即時復帰します。戻り値は指定位置 を得るために待つ必要のあるログイベントの数、またはエラーの場合 NULL です。 マスタースレーブ同期制御に有用ですが、元々は手軽な複製テストのために書かれ ました。

## 6.4 Data Manipulation: `SELECT`, `INSERT`, `UPDATE`, `DELETE`

### 6.4.1 `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} [ASC | DESC], ...]
            [HAVING where_definition]
            [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] ,...]
            [LIMIT [offset,] rows]
            [PROCEDURE procedure_name]
            [FOR UPDATE | LOCK IN SHARE MODE]]

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

    mysql> SELECT 1 + 1;
             -> 2

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

- `SELECT`の表現では、`AS`による別名の指定が可能です。別名は、 フィールド名の表現として使われ、`ORDER BY`及び`HAVING`節とともに使用することができます。 例:

      mysql> select concat(last_name,', ',first_name) AS full_name
          from mytable ORDER BY full_name;

- `FROM table_references`節は、(例えば、選択するレコードにより、1つ又はそれ以上の) 結合するテーブルのリストを示します。 このリストはまた、`LEFT OUTER JOIN`参照を含むことがあります。 「6.4.1.1 `JOIN` 構文」節. を参照してください。
- `col_name`、`tbl_name.col_name`、`db_name.tbl_name.col_name`の ようにしてフィールドを表すことができます。 `SELECT`ステートメント内での列の参照が曖昧でなければ、`tbl_name`や `db_name.tbl_name`のようなプリフィックスを詳細に記述する必要はありません。 より明示的なフィールドの指定形式をを必要とする曖昧な参照の例は、 「6.1.2 データベース名、テーブル名、インデックス名、フィールド名、エイリアス名」節を参照のこと。
- テーブル参照は、`tbl_name AS alias_name`又は`tbl_name alias_name`を 使って別名を使用することが可能です:

      mysql> select t1.name, t2.salary from employee AS t1, info AS t2
                 where t1.name = t2.name;
      mysql> select t1.name, t2.salary from employee t1, info t2
                 where t1.name = t2.name;

- 出力用に選択されたフィールドは、`ORDER BY`節や`GROUP BY`節において、 フィールド名、フィールドのエイリアス名、又はフィールド番号にて指し示すことが できます。フィールド番号は1から始まります。

      mysql> select college, region, seed from tournament
                 ORDER BY region, seed;
      mysql> select college, region AS r, seed AS s from tournament
                 ORDER BY r, s;
      mysql> select college, region, seed from tournament
                 ORDER BY 2, 3;

  逆順で並べたい場合には、 `ORDER BY` 節の中で、あなたが並べたいと思っている フィールドの名前の後ろに、 `DESC` (descending) キーワードを 追加します。 デフォルトは昇順です； これは `ASC` キーワードを指定したことになります。
- `WHERE` 節で MySQL がサポートする任意の関数を使用することが できます。 「6.3 `SELECT` と `WHERE` 節で使用する関数」節参照.
- `HAVING`節は、`select_expression`においてどのフィールドの名前や エイリアス名でも指し示すことができます。 これは最後に適用され、クライアントにアイテムが送られる直前に実行されるので、 最適化されません。 `WHERE`節で書くべきものに`HAVING`を用いてはいけません。 例えば、次のように書いてはいけません:

      mysql> select col_name from tbl_name HAVING col_name > 0;

  その代わりに、次のように書いてください:

      mysql> select col_name from tbl_name WHERE col_name > 0;

  MySQL バージョン 3.22.5以降では、次のようにクエリを記述することができます:

      mysql> select user,max(salary) from users
                 group by user HAVING max(salary)>10;

  MySQLの古いバージョンでは、この代わりに次のように記述できます:

      mysql> select user,max(salary) AS sum from users
                 group by user HAVING sum>10;

- `SQL_SMALL_RESULT`, `SQL_BIG_RESULT`, `SQL_BUFFER_RESULT`, `STRAIGHT_JOIN`, `HIGH_PRIORITY` は ANSI SQL92 に対する MySQL 拡張です。
- `HIGH_PRIORITY` は、テーブルの更新よりも `SELECT` を優先させます。 これは一度で完了する、とても速いクエリにのみ適用すべきです。 もしリードロックされているテーブルがあったとし、 たとえ update 文がこのテーブルの解除を待っていたとしても、 `SELECT HIGH_PRIORITY` クエリは実行されます。
- `SQL_BIG_RESULT` は `GROUP BY` や `DISTINCT` と共に使用する 事ができ、結果セットが多くのレコードを持つことをオプティマイザに知らせます。 この場合、必要なら MySQL はディスクベースの一時テーブルを直接使用 します。`MySQL` はこの場合、`GROUP BY` 要素上のキーで一時テーブ ルを行なう代わりにソートを行なうことを選択します。
- `SQL_BUFFER_RESULT` は結果を一時テーブルへ強制的に置きます。これは MySQL がテーブルロックを速く解放して、クライアントに結果セットを 送るために長い時間が掛かる場合の助けになります。
- `SQL_SMALL_RESULT` (MySQL 固有のオプション) は `GROUP BY` か `DISTINCT` と共に使用する事ができ、 結果セットが小さくなることをオプティマイザに知らせます。この場合、 MySQL はソートする代わりに、速い一時テーブルを結果の保存のた めに使用します。 MySQL バージョン 3.23 では、これは通常必要ではありません。
- `GROUP BY` を使用する場合、`GROUP BY` 内のすべてのフィールドを `ORDER BY` に記述したかのように、出力レコードは `GROUP BY` に従っ てソートされます。MySQL は、`ASC` と `DESC` を `GROUP BY` に記述できるように、`GROUP BY` を拡張しています:

      SELECT a,COUNT(b) FROM test_table GROUP BY a DESC

- MySQL は、`GROUP BY` 節に記述されていないフィールドを select できるように `GROUP BY` の使用を拡張しています。あなたのクエリ から期待した結果を得ない場合、`GROUP BY` の説明を読んでください。 「M.3 Functions for Use with `GROUP BY` Clauses」節参照.
- `STRAIGHT_JOIN`は、`FROM`節にて記述されたテーブルの順序に従って結合するよう、 オプティマイザに強制します。オプティマイザが、テーブルを最適な順序で結合しない 場合に、クエリのスピードアップのためにこれを使用することが可能です。 「5.2.1 `EXPLAIN` 構文 (`SELECT`についての情報を得る)」節参照.
- `LIMIT` 節は、 `SELECT` 構文で返されるレコード数を指定するのに 使用されます。 `LIMIT` は一つか二つの数字の引数を取ります。 引数が2つ与えられたならば、最初の引数は最初のレコードからのオフセットを示し、 2つめの引数は返すレコードの最大数を示します。 初めのレコードのオフセットは0です(1ではありません)。

      mysql> select * from table LIMIT 5,10;  # 6〜15行目を返す

  もし引数が一つなら、返すべきレコードの最大行数を指定したことになります。

      mysql> select * from table LIMIT 5;     # 最初の5行を取り出す

  いいかえれば、`LIMIT n` は `LIMIT 0,n` と同じです。
- `SELECT`の書式、`SELECT ... INTO OUTFILE 'file_name'`は、 選択されたレコードをファイルに書き込みます。 ファイルはサーバ機に作成され、既に存在するファイルであってはなりません (``/etc/passwd'`のようなファイルの破壊を防止します)。 `SELECT ... INTO OUTFILE` は主に、サーバマシン上でとても速くテーブル をダンプすることを意図されています。サーバホストでない別のホスト上で結果ファ イルを生成したい場合は、`SELECT ... INTO OUTFILE` を使用できません。 この場合は代わりに、`mysqldump --tab` や `mysql -e "SELECT ..." > outfile` のようなクライアントプログラムを使用して、ファイルを生成す べきです。 `SELECT ... INTO OUTFILE`は、`LOAD DATA INFILE`の逆です。 `export_options`の構文は、`LOAD DATA INFILE`ステートメントの一部で 使われる`FIELDS`節や`LINES`節と同じような構成です。 「6.4.8 `LOAD DATA INFILE` 構文」節参照. 結果として取り出されるテキストファイルでは、 以下に示す文字が `ESCAPED BY` 指定の文字によってエスケープされます：
  - `ESCAPED BY` 文字自身
  - `FIELDS TERMINATED BY` の最初の文字
  - `LINES TERMINATED BY` の最初の文字
  さらに、 `ASCII 0` は、`ESCAPED BY` 0 (`ASCII 48`) にコンバートされます。 いかなる `FIELDS TERMINATED BY`, `ESCAPED BY`, `LINES TERMINATED BY` 指定されている文字も、エスケープしなければならない理由は、 テキストファイルを読み返せれるようにするためなのです。 `ASCII 0` はいくつかのページャーでも見れるようにするために エスケープされるのです。 結果のファイルは SQL の文を含んでいないので、何もエスケープする必要はありません。 次は、多くの古いプログラムによって使用されるフォーマットでファイルを得る例 です。

      SELECT a,b,a+b INTO OUTFILE "/tmp/result.text"
      FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
      LINES TERMINATED BY "\n"
      FROM test_table;

- `INTO OUTFILE` の代わりに `INTO DUMPFILE` を使用すると、 MySQL はファイルに１レコードだけを書きます。フィールドや行の終端 とすべてのエスケープを含みません。これはファイル内に BLOB を格納したい場合 に便利です。
- 注意: `INTO OUTFILE` と `INTO DUMPFILE` によって生成されたファイ ルは、すべてのユーザに読み出し可能になります！ この理由は、 MySQL サーバは、実行ユーザ以外の誰かによって所有されているファイ ルを生成できないからです(`mysqld` を root として動かすべきではありま せん)。あなたがレコードを取り出すことが可能なように、ファイルは全員に読み 出し可能にする必要があります。
- ページ／レコードロックとともにテーブルハンドラ上で `FOR UPDATE` を使 用すると、検査されるレコードは書き込みロックされます。

#### 6.4.1.1 `JOIN` 構文

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

    table_reference, table_reference
    table_reference [CROSS] JOIN table_reference
    table_reference INNER JOIN table_reference join_condition
    table_reference STRAIGHT_JOIN table_reference
    table_reference LEFT [OUTER] JOIN table_reference join_condition
    table_reference LEFT [OUTER] JOIN table_reference
    table_reference NATURAL [LEFT [OUTER]] JOIN table_reference
    { oj table_reference LEFT OUTER JOIN table_reference ON conditional_expr }
    table_reference RIGHT [OUTER] JOIN table_reference join_condition
    table_reference RIGHT [OUTER] JOIN table_reference
    table_reference NATURAL [RIGHT [OUTER]] JOIN table_reference

Where `table_reference` is defined as:

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

and `join_condition` is defined as:

    ON conditional_expr |
    USING (column_list)

注意: 3.23.17 より前のバージョンでは、`INNER JOIN` は `join_condition` を取りません！

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

- table referenceは、`tbl_name AS alias_name`や`tblname alias_name`に よる別名を指定することができます:

      mysql> select t1.name, t2.salary from employee AS t1, info AS t2
                 where t1.name = t2.name;

- `INNER JOIN`と`,` (コンマ)は、同義語です。どちらも使用される テーブル間の直積をとります。通常は`WHERE`条件にて、テーブルがどのように リンクされるべきかを定義します。
- `ON`条件節は、`WHERE`節で使用されるような条件文の書式です。
- もし、`LEFT JOIN` の `ON` や `USING` において 右側のテーブルにマッチするレコードが無かった場合、 全てのフィールドが`NULL`である1つのレコードが、右側のテーブルとして使用されます。 この事実は、あるテーブルについて、他のテーブルに対応するレコードが存在しない レコードを探すということに利用できます:

      mysql> select table1.* from table1
                 LEFT JOIN table2 ON table1.id=table2.id
                 where table2.id is NULL;

  この例は、`table1`の内、`id`の値が`table2`に存在しない全ての レコードを検索します。 (即ち、`table2`内のレコードと一致しない`table1`の全てのレコード。) もちろん、この場合の`table2.id`は、`NOT NULL`と定義されているもの と仮定します。 「5.2.6 MySQL はどのように `LEFT JOIN` と `RIGHT JOIN` を最適化するか？」節参照.
- `USING` `(column_list)`節のフィールド名リストは、両方のテーブルに 存在しなければなりません。`USING`節が次のように:

      A LEFT JOIN B USING (C1,C2,C3,...)

  定義されることは、`ON`式がこのように定義されるのと同義です:

      A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,...

- 同じフィールド名を持つ2つのテーブルの `NATURAL [LEFT] JOIN` は、 `USING` 節を伴った `INNER JOIN` や `LEFT JOIN` と 同じとして定義されます。
- `RIGHT JOIN` works analogously as `LEFT JOIN`. To keep code portable across databases, it's recommended to use `LEFT JOIN` instead of `RIGHT JOIN`.
- `STRAIGHT_JOIN`は、右側のテーブルの前に、常に左側のテーブルを読むことを 除けば、`JOIN`と全く同じことです。これは、結合オプティマイザが、不当な 順序でテーブルを出力するようなまれな事態に使用できます。
- MySQL バージョン 3.23.12 から、テーブルから情報を取り出す時に、 MySQL がどのインデックスを使用すべきかというヒントを与えることが できるようになりました。これは、MySQL が間違ったインデックスを使 用していることを `EXPLAIN` が示す場合に有用です。`USE INDEX (key_list)` を指定することによって、テーブルからレコードを見つけるために、 指定されたインデックスの一つだけを使用するように MySQL に伝えるこ とができます。別の構文 `IGNORE INDEX (key_list)` は、MySQL に特定のインデックスを使用しないように伝えるために使用できます。

例:

    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;

「5.2.6 MySQL はどのように `LEFT JOIN` と `RIGHT JOIN` を最適化するか？」節参照.

### 6.4.2 `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 ... VALUES` や `INSERT ... SELECT` などで明示しなければ、全てのフィールドの値が `VALUES()` の中に与えられ なくてはなりません。テーブル内のフィールド順が不明な場合、 これを調べるために`DESCRIBE tbl_name`を使用して下さい。
- テーブル内の一部のフィールドしか指定しない場合、指定されなかったフィールドには、 それぞれの初期値が指定されます。初期値の割当ては、 「6.5.3 `CREATE TABLE` 構文」節. で述べられています。
- `NULL`を`TIMESTAMP`フィールドに挿入した場合、フィールドには 現在時刻がセットされます。他の値を挿入した場合、指定された値が単純にセットされます。
- `expression`は、値リスト内で先頭に近い方のフィールドを参照しなければなりません。 例えば、次のように記述できます:

      mysql> INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);

  しかし、次のようには記述できません:

      mysql> INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);

- キーワード`LOW_PRIORITY`を指定した場合、`INSERT`の実行はそのテー ブルから値を読み込むクライアントがいなくなるまで遅らされます。この場合、ク ライアントは insert 文が完了するまで待たされます。テーブルが頻繁に使用され る場合、長い時間かかります。これはクライアントを一度に継続させる `INSERT DELAYED` と対称的です。 「6.4.3 `INSERT DELAYED` 構文」節参照. Note that `LOW_PRIORITY` should normally not be used with `MyISAM` tables as this disables concurrent inserts. 「7.1 MyISAM Tables」節参照.
- もし `IGNORE` キーワードを `INSERT` に 値とともに 与えるなら、 テーブル内の `PRIMARY` や `UNIQUE` キーにすでに存在する重複した ものは無視され、挿入されません。 多重行の値を含むレコードの `INSERT` にキーワード `IGNORE` を 指定しない場合、テーブルの `PRIMARY` キーや `UNIQUE` キーに 重複が起こる際に、挿入処理が異常終了します。 `IGNORE` を指定した場合、重複するキー値を持つレコードは挿入されません。 C API 関数 `mysql_info()` により、テーブルにいくつのレコードが挿入 されたかチェックすることができます。
- MySQLが、`DONT_USE_DEFAULT_FIELDS`オプションにより制限されていた 場合、`NULL`値を許さない全てのフィールドに明示的に値をしないと `INSERT`ステートメントは、エラーを生成します。 「2.3.3 典型的な `configure` オプション」節参照.
- `mysql_insert_id` 関数で `AUTO_INCREMENT` フィールドに使用された 値を見つけることができます。 「8.4.3.126 `mysql_insert_id()`」節参照.

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

    Records: 100 Duplicates: 0 Warnings: 0

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

- `NOT NULL`定義されたフィールドへの`NULL`の挿入。フィールドには 初期値が設定されます。
- 数値フィールドの範囲を超える値のセット。値は範囲内の限界値に補正されます。
- 数値フィールドへの ``10.34 a'` のような値のセット。引きずっている ゴミは取り除かれ、残りの数値部分が挿入されます。 値が数値として判断できなかった場合、フィールドには `0` がセットされます。
- `CHAR`、`VARCHAR`、`VARCHAR`、`TEXT`又は`BLOB` フィールドへの最大長を超える文字列の挿入。値はフィールドの最大長に切り捨てられます。
- 日付又は時刻フィールドへのフィールド属性に反した挿入。その属性に適した ``ゼロ''値がセットされます。

#### 6.4.2.1 `INSERT ... SELECT` 構文

    INSERT [LOW_PRIORITY] [IGNORE] [INTO] tbl_name [(column list)] SELECT ...

With `INSERT ... SELECT` statement you can quickly insert many rows into a table from one or many tables.

    INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID FROM tblTemp1 WHERE
    tblTemp1.fldOrder_ID > 100;

The following conditions hold for an `INSERT ... SELECT` statement:

- The target table of the `INSERT` statement cannot appear in the `FROM` clause of the `SELECT` part of the query because it's forbidden in ANSI SQL to `SELECT` from the same table into which you are inserting. (The problem is that the `SELECT` possibly would find records that were inserted earlier during the same run. When using sub-select clauses, the situation could easily be very confusing!)
- `AUTO_INCREMENT` columns work as usual.
- You can use the C API function `mysql_info()` to get information about the query. 「6.4.2 `INSERT` 構文」節参照.
- To ensure that the update log/binary log can be used to re-create the original tables, MySQL will not allow concurrent inserts during `INSERT .... SELECT`.

You can of course also use `REPLACE` instead of `INSERT` to overwrite old rows.

### 6.4.3 `INSERT DELAYED` 構文

    INSERT DELAYED ...

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

`INSERT DELAYED` only works with `ISAM` and `MyISAM` tables. Note that as `MyISAM` tables supports concurrent `SELECT` and `INSERT`, if there is no free blocks in the middle of the data file, you very seldom need to use `INSERT DELAYED` with `MyISAM`. 「7.1 MyISAM Tables」節参照.

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

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

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

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

- スレッドがあるテーブルに対し `DELAYED` 構文を実行するとき、 そのテーブルに対する全ての `DELAYED` 構文 を処理するためにハンドラースレッドが作成されます。 もしそのようなハンドラーが存在していない場合には。
- そのスレッドは、そのハンドラーが `DELAYED` ロックを既に持っているか どうかをチェックします； もし持っていないなら、そうするように ハンドラーに告げます。 たとえ他のスレッドが `READ` か `WRITE` ロックをそのテーブルに 持っていたとしても、 `DELAYED` ロックを得ることができます。 しかし、そのハンドラーは全ての `ALTER TABLE` ロックか `FLUSH TABLES` を待ちます。 そのテーブル構造が最新であるのを 確実にするために。
- スレッドは `INSERT` ステートメントを実行しますが、レコードをテーブル に書く代わりに、ハンドラスレッドによって管理されるキューに最後のレコードの コピーを置きます。文法エラーはスレッドによって通知され、クライアントプログ ラムに報告されます。
- クライアントは結果行の重複数や `AUTO_INCREMENT` の値を 報告できません； それはサーバーから得ることができません。 なぜなら、 `INSERT` はインサートオペレーションが完全に終了する前に 返るからです。 もし C API を使用しているなら、 `mysql_info()` 関数は 同様の理由によりなにも返しません。
- 更新ログは、レコードがそのテーブルに insert されたとき、そのハンドラースレッド によって更新されます。 複数レコードの挿入の場合、 更新ログは最初の行が 挿入されたときに更新されます。
- それぞれの `delayed_insert_limit` レコードが書かれた後、そのハンドラーは いかなる `SELECT` 文もまだ延期されていないかを確認します。 もしそうなら、続ける前にこれらに対して実行を可能にします。
- ハンドラーのキュー内にレコードがなくなったとき、テーブルはアンロックされます。 もし新しい `INSERT DELAYED` コマンドが `delayed_insert_timeout` 秒以内に 受け付けられなければ、ハンドラーは終了します。
- もし、特定のハンドラーのキュー内に `delayed_queue_size` 以上のレコードが 既に延期されているならば、そのスレッドは、キューに余裕がある間待ちます。 これは `mysqld` サーバーが delayed されたキューに全ての メモリーを確実に使用しないようにするのに役立ちます。
- そのハンドラースレッドは MySQL プロセスリストの `Command` 項 内に、 `delayed_insert` と共に表示されます。 これは `FLUSH TABLES` コマンドか `KILL thread_id` を実行することで、 kill できるでしょう。 しかし、これらは、終了する前に、キュー内の全てのレコードをテーブルに 保存しようとします。 この間、このスレッドは、他のスレッドから来たいかなる 新しい `INSERT` コマンドも受け付けません。 もし、この後に `INSERT DELAYED` コマンドを実行するなら、 新しいハンドラースレッドが作成されます。
- 上記のことは、もし `INSERT DELAYED` コマンドが既に走っているなら、 `INSERT DELAYED` コマンドは、普通の `INSERT` コマンドよりも高い 優先度を持つということです！ 他の update コマンドは `INSERT DELAY` キューが空になるまで、 あるいは誰かが `KILL thread_id` や `FLUSH TABLES` を実行して ハンドラーをキルするまで、 待たされます。
- 以下のステータス変数は `INSERT DELAYED` コマンドについての情報を 与えます：

  Variable | Meaning
  `Delayed_insert_threads` | ハンドラースレッドの数
  `Delayed_writes` | `INSERT DELAYED` で書かれるレコード数
  `Not_flushed_delayed_rows` | 書き込みを待つレコード数

  これらの変数は `SHOW STATUS` 構文を発行したり `mysqladmin extended-status` コマンドを実行することで見れます.

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

### 6.4.4 `UPDATE` 構文

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

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

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

`IGNORE` キーワードを指定した場合は、update 文は、 update 中に二重キーのエラーを得たとしても、異常終了しません。 衝突を引き起こすレコードは更新されません。

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

    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 #` で指定した数だけレコードを 変更できます。

### 6.4.5 `DELETE` 構文

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

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

`WHERE`節を指定することなしに`DELETE`を発行した場合、全てのレコードが 削除されます。 もし `AUTOCOMMIT` モードでこの操作を実行するならば、これは `TRUNCATE` と同様に動作します。 「6.4.6 `TRUNCATE` 構文」節参照. 一つの問題は、今、`DELETE` は削除したレコード数を 0 で返すことですが、 これはバージョン 4.0 で修正する予定です。

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

    mysql> DELETE FROM tbl_name WHERE 1>0;

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

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

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

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

### 6.4.6 `TRUNCATE` 構文

    TRUNCATE TABLE table_name

3.23 では、`DELETE FROM table_name` と同じことです。 「6.4.5 `DELETE` 構文」節参照. 違いは:

- テーブルを破棄して再生成するように実装されています。これは多くのレコードを 削除する時により速くなります。
- トランザクション安全ではありません; `COMMIT` が呼ばれたかのように `TRUNCATE TABLE` は自動的に現在のトランザクションを終了します。
- 削除したレコード数を返しません。
- テーブル定義ファイル ``table_name.frm'` が正しい限り、たとえ、データや インデックスファイルが汚れても、テーブルはこの方法で再生成できます。

`TRUNCATE` は ORACLE SQL 拡張です。

### 6.4.7 `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`と全く同じように 動作します。 「6.4.2 `INSERT` 構文」節参照.

In other words, you can't access the values of the old row from a `REPLACE` statement. In some old MySQL version it looked like you could do this, but that was a bug that has been corrected.

When one uses a `REPLACE` command, `mysql_affected_rows()` will return 2 if the new row replaced and old row. This is because in this case one row was inserted and then the duplicate was deleted.

The above makes it easy to check if `REPLACE` added or replaced a row.

### 6.4.8 `LOAD DATA INFILE` 構文

    LOAD DATA [LOW_PRIORITY | CONCURRENT] [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 権限も持たなければなりません。 「4.2.6 MySQL が提供する権限」節参照.

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

If you specify the keyword `CONCURRENT` with a `MyISAM` table, then other threads can retrieve data from the table while `LOAD DATA` is executing. Using this option will of course affect the performance of `LOAD DATA` a bit even if no other thread is using the table at the same time.

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

If you are using MySQL before Version 3.23.24 you can't read from a FIFO with `LOAD DATA INFILE`. If you need to read from a FIFO (for example the output from gunzip), use `LOAD DATA LOCAL INFILE` instead.

`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;

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

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

If you use `LOAD DATA INFILE` on an empty `MyISAM` table, all non-unique indexes are created in a separate batch (like in `REPAIR`). This normally makes `LOAD DATA INFILE` much faster when you have many indexes.

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

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

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

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

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

    LINES TERMINATED BY '\n'

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

- 改行をレコードの境界とみなす
- タブ文字によってフィールドを区切る
- クォート文字でフィールドを囲んでいないものとする
- タブ文字や改行文字及び``\'`の前に``\'`があることにより、それらをフィールド 値の一部のリテラル文字であるとして処理する。

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

- フィールド間にタブ文字を書く
- いずれのクォート文字でもフィールドを囲まない
- ``\'`の使用により、フィールド値の中で使用するタブ文字や改行文字、``\'`をエ スケープする
- レコードの終りに改行文字を書く

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

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

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

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

    mysql> SELECT * 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 BY`と`FIELDS ESCAPED BY`の値は 単一の文字でなければなりません。 `FIELDS TERMINATED BY`と`LINES TERMINATED BY`は２つ以上の文字となるで しょう。

例えば、リターン文字と改行文字のペアで区切られたレコードを書き込んだり、 このようなレコードを含んだファイルを読み込んだりするには、 `LINES TERMINATED BY '\r\n'`節を指定します。

    create table jokes (a int not null auto_increment primary key, joke text
    not null);
    load data infile "/tmp/jokes.txt" into table jokes fields terminated by ""
    lines terminated by "\n%%\n" (joke);

`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`により正しく読み込めない出力を生成する でしょう。例えば、このようにエスケープ文字を空にした場合、以下に示すような出力と なります。４行目の２つ目のフィールドに、(誤って)フィールドを区切るかのようなクォ ートに続くコンマを含んでいることに注視して下さい:

    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`文字の出現は、現在のフィー ルド値の一部として処理されます。具体的には、あるフィールドがそれ自身、た`EN CLOSED BY`文字で始まっている場合、フィールドらの内部で発生する２重の`ENCLOS ED 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 [OPTIONALLY] ENCLOSED BY`文字
- `FIELDS TERMINATED BY`値と`LINES TERMINATED BY`値の最初の文字
- ASCII 0 (エスケープ文字の後に続いて実際に書かれる文字はASCII `'0'`で、'ゼロ 値'バイトではありません)

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

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

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

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

- `LINES TERMINATED BY`が空文字列で`FIELDS TERMINATED BY`が空でない場合 、各レコードもまた`FIELDS TERMINATED BY`で終らせられます。
- `FIELDS TERMINATED BY`と`FIELDS ENCLOSED BY`値が両方とも空(`''`) の時、(区切られない)固定長行フォーマットが使用されます。 固定長行フォーマットでは、フィールド間に区切り文字列が使用されません。 その代わり、フィールド値は、フィールドの``表示''幅を使って書き込まれたり、読み込 まれます。 例えば、あるフィールドが`INT(7)`で定義されている場合、フィールドの値は7文字 の桁を使って書き込まれます。 入力においてフィールドは、７文字の読み込みにより得られます。 固定長行フォーマットはまた、`NULL`値の操作に好んで用いられます;下を参照のこ と。 注意: マルチバイト文字セットを使用している場合は固定長フォーマットは働きま せん。

`FIELDS`と`LINES`オプションによる`NULL`値の多様な取扱い:

- `FIELDS`と`LINES`の初期値のために、出力時に`NULL`は`\N`とし て書き込まれ、入力時に`\N`は`NULL`として読み込まれます(当然のことなが ら、`ESCAPED BY`文字は``\'`とします)。
- `FIELDS ENCLOSED BY`が空で無い時、定数`NULL`のフィールド値は`NULL` 値として読み込まれます(これは、文字列`'NULL'`として読み込まれる`FIELD S ENCLOSED BY`文字列で囲まれた`NULL`とは異なります)。
- `FIELDS ESCAPED BY`が空の時、`NULL`は`NULL`として書き込まれます。
- 固定長行フォーマット(`FIELDS TERMINATED BY`と`FIELDS ENCLOSED BY`がい ずれも空の場合に起こります)において、`NULL`は、空白文字列として書き込まれま す。 これは、ファイル内では、`NULL`値と空白値の見分けがつかないということを示し ていることに注意して下さい。ファイルからデータを読み戻す時に両者を区別しなければ ならない場合、固定長行フォーマットは使用すべきではありません。

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

- 固定長行(`FIELDS TERMINATED BY`と`FIELDS ENCLOSED BY`の両方が空)と `BLOB`フィールド。
- あるセパレータを他と同じかもしくは他のプリフィックスとした場合、`LOAD DATA INFILE`は、正しい入力処理ができないでしょう。 例えば、以下の`FIELDS`節は問題の原因となります:

      FIELDS TERMINATED BY '"' ENCLOSED BY '"'

- `FIELDS ESCAPED BY`が空で、フィールド値に、`FIELDS ENCLOSED BY`値や `LINES TERMINATED BY`値の後に`FIELDS TERMINATED BY`値がくるようなものを含 む場合、フィールドや行の読み込みが早めに打ち切られてしまいます。 これは、`LOAD DATA INFILE`が、フィールドやレコードの終了位置を正しく決めら れないことにより発生します。

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

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

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

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

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

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

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

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

- 文字型の場合、 フィールドの値は空文字にセットされます。
- 数値型の場合、フィールドの値は `0` にセットされます。
- 日付と時刻の型の場合、 フィールドの値は ``zero'' の意味する値がセットされます。 「6.2.2 日付と時間の型」節参照.

Note that these are the same values that result if you assign an empty string explicitly to a string, numeric, or date or time type explicitly in an `INSERT` or `UPDATE` statement.

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

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

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

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

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

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

パイプからの読み込みで `LOAD DATA` の必要があれば、次のトリッ クを使用できます:

    mkfifo /mysql/db/x/x
    chmod 666 /mysql/db/x/x
    cat < /dev/tcp/10.1.1.12/4711 > /nt/mysql/db/x/x
    mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x

If you are using a version of MySQL older than 3.23.25 you can only do the above with `LOAD DATA LOCAL INFILE`.

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

### 6.4.9 `DO` Syntax

    DO expression, [expression, ...]

Execute the expression but don't return any results. This is a shorthand of `SELECT expression, expression`, but has the advantage that it's slightly faster when you don't care about the result.

This is mainly useful with functions that has side effects, like `RELEASE_LOCK`.

## 6.5 Data Definition: `CREATE`, `DROP`, `ALTER`

### 6.5.1 `CREATE DATABASE` 構文

    CREATE DATABASE [IF NOT EXISTS] db_name

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

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

`mysqladmin`でもデータベースを作成することができます。 「4.8 MySQL Client-Side Scripts and Utilities」節参照.

### 6.5.2 `DROP DATABASE` 構文

    DROP DATABASE [IF EXISTS] db_name

`DROP DATABASE`は、データベース内の全てのテーブルと共にデータベースを破棄し ます。 シンボリックリンクされた `DROP DATABASE` を行なうと、リンクとオリジナ ルデータベースの両方が削除されます。 このコマンドの使用には万全の注意を払って下さい！

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

`DROP DATABASE` コマンドは与えられたデータベースディレクトリから、次 の拡張子のすべてのファイルを削除します:

.BAK | .DAT | .HSH | .ISD
.ISM | .ISM | .MRG | .MYD
.MYI | .db | .frm

2桁の数値のすべてのサブディレクトリ(`RAID` ディレクトリ)も削除されま す。

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

`mysqladmin`でもデータベースを破棄することができます。 「4.8 MySQL Client-Side Scripts and Utilities」節参照.

### 6.5.3 `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    FULLTEXT [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 = {BDB | HEAP | ISAM | InnoDB | MERGE | MYISAM }
    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 | fixed | compressed }
    or	RAID_TYPE= {1 | STRIPED | RAID0 } RAID_CHUNKS=#  RAID_CHUNKSIZE=#
    or	UNION = (table_name,[table_name...])
    or      DATA DIRECTORY="directory"
    or      INDEX DIRECTORY="directory"

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

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

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

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

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

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

File | Purpose
`tbl_name.frm` | Table definition (form) file
`tbl_name.MYD` | Data file
`tbl_name.MYI` | Index file

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

- `NULL`も`NOT NULL`も指定されなかった場合、フィールドは`NULL`が指 定されたものとして扱われます。
- 整数型のフィールドには付加属性`AUTO_INCREMENT`も指定することができます。 `AUTO_INCREMENT`のフィールドに値`NULL`又は`0`を挿入した場合、フィ ールドには`value+1`の値がセットされます。`value`は、そのテーブル内の当 該フィールドにおける現在の最大値です。 `AUTO_INCREMENT` は `1` からはじまります. 「8.4.3.126 `mysql_insert_id()`」節参照. 削除したレコードが、`AUTO_INCREMENT`フィールドの最大値を含んでいた場合、 その値は、`ISAM` と `BDB` テーブルでは、次に再利用されますが、 `MyISAM` と `InnoDB` テーブルでは再利用されません。 また、テーブル内の全てのレコードを `DELETE FROM table_name` (`WHERE`節 無しで) を `AUTOCOMMIT` モードで使用して削除した場合は、すべてのテーブル型で始めから採 番し直します。 注意: 1つのテーブルには1つしか`AUTO_INCREMENT`フィールドを指定でき ません。 また、インデックスを指定する必要があります。 MySQL 3.23 は auto_increment フィールドが正の数を持っている場合に だけ、正しく動作します。負の数の挿入はとても大きな正の数の挿入とみなされま す。これは、数値が正から負への 'wrap' over する時の精度の問題を回避するた めと、アクシデント的に 0 を含む auto_increment フィールドを得ることがない ことを確実にするために、行なわれます。 MySQL をいくつかの ODBC アプリケーションと互換にするために、次の クエリで最後に挿入されたレコードを見つけることができます:

      SELECT * FROM tbl_name WHERE auto_col IS NULL

- `TIMESTAMP`フィールドにおける`NULL`値は、他のフィールド属性と違った扱 われ方をします。定数`NULL`を`TIMESTAMP`フィールドに格納することはでき ません。`NULL`値の指定は現在時刻をセットすることを意味します。`TIMESTA MP`フィールドがこのように振舞うので、通常は`NULL`属性や`NOT NULL`属性 は適用できません。それらを指定しても無視されます。 一方、MySQLクライアントからは、より安易に`TIMESTAMP`フィールドを 利用でき、サーバも`TIMESTAMP`フィールドへの`NULL`の適用を報告しますが 、`TIMESTAMP`フィールドは実際には`NULL`値を保存することはありません。 code{DESCRIBE tbl_name}を使用して、テーブル定義文を取得することにより、この現象 を確認することができます。 `TIMESTAMP`フィールドに`0`を指定することは、`NULL`を指定すること と等しくないことに注意してください。なぜなら、`0`は`TIMESTAMP`の値とし て不正であるからです。
- フィールドに対して `DEFAULT` 値が指定されない場合は MySQL が 自動的にそれを割り当てます。 フィールドが `NULL` を値として取り得る場合は、デフォルト値は `NULL` です。 フィールドが `NOT NULL` として宣言された場合は、デフォルト値はフィー ルド型に依存します:
  - `AUTO_INCREMENT` 定義された以外の数値型のフィールドに対しては、 初期値は`0`となります。 `AUTO_INCREMENT`フィールドでは、デフォルト値は次のシーケンス番号になります。
  - `TIMESTAMP` 型以外の日付型と時刻型のフィールドに対しては、 初期値はその型において適切な``ゼロ''値となります。 例外: フィールドがそのテーブル内で最初の`TIMESTAMP`フィールドである場合、初 期値は現在時刻になります。 「6.2.2 日付と時間の型」節参照.
  - `ENUM` 以外の文字列型のフィールドに対しては、初期値は空文字列となります。 `ENUM` では、デフォルト値は最初の列挙値です。
  Default values must be constants. This means, for example, that you cannot set the default for a date column to be the value of a function such as `NOW()` or `CURRENT_DATE`.
- `KEY`は、`INDEX`の同義語です。
- MySQLでは、`UNIQUE`キーは固有値しか持つことができません。既に存在 するレコードとキーの値が重複するレコードを挿入しようとした場合、エラーが発生しま す。
- `PRIMARY KEY` はユニーク `KEY` で、すべてのキーフィールドは `NOT NULL` として定義されなければならないという特別な制限を伴います。 MySQL ではキーは `PRIMARY` と名付けられます。テーブルは `PRIMARY KEY` を一つだけ持つことができます。`PRIMARY KEY` を持た ない場合に、アプリケーションがテーブル内の `PRIMARY KEY` を尋ねると、 MySQL は `PRIMARY KEY` として、`NULL` フィールドを持た ない最初の `UNIQUE` キーを返します。
- `PRIMARY KEY`は複数フィールドインデックスとできます。しかしながら、1つのフ ィールド定義内では`PRIMARY KEY`属性を用いて複合インデックスを定義することが できませんので、フィールド定義内における指定は、プライマリ・キーが単独フィールド の場合のみとして下さい。複合フィールドの場合は、 `PRIMARY KEY(index_col_name,...)`文を使用しなければなりません。
- `PRIMARY` や `UNIQUE` キーが１つのフィールドだけからなり、その型が整数 の場合、それを `_rowid` としても参照することができます (バージョン 3.23.11 での新機能)。
- インデックスに名前を割り当てない場合、一意な名前を付けるために、`index_col_ name`内の最初のフィールド名に(`_2`, `_3`, ...)のようなサフィックスを付 加したものが割り当てられます。テーブルが使用しているインデックス名は、`SHOW INDEX FROM tbl_name`により確認することができます。 「4.5.5 `SHOW` 構文」節参照.
- `MyISAM` テーブルのみが、`NULL` 値をもつフィールドに対して インデックスを持つことが出来ます。 その他のテーブル型の場合、フィールドを `NOT NULL` で定義しなくてはなりませ ん。
- `col_name(length)`文を共に指定することで、`CHAR`フィールド又は `VARCHAR`フィールドの一部分だけをインデックスとして定義できます。 これによりインデックスファイルを適度に小さくすることができます。 「5.4.4 Column Indexes」節参照.
- `MyISAM` テーブル型のみが、 `BLOB` と `TEXT` フィールド上に インデックスを持つことが出来ます。 `BLOB` と `TEXT` フィールドに インデックスを張る場合、常に、インデックスの長さを指定しなくてはなりません：

      CREATE TABLE test (blob_col BLOB, index(blob_col(10)));

- `TEXT`フィールドや`BLOB`フィールドで `ORDER BY` や `GROUP BY` を使用すると、 最初の`max_sort_length`バイトだけが使用されます。 「6.2.3.2 `BLOB` と `TEXT` 型」節参照.
- MySQL バージョン 3.23.23 以降では、特殊な FULLTEXT イン デックスも生成できます。それらは全文検索に使用されます。`MyISAM` テー ブル型だけが `FULLTEXT` インデックスをサポートします。それらは `VARCHAR` と `TEXT` フィールドからだけ生成できます。インデックス は常にフィールド全体に起こります。部分インデックスはサポートされません。オ ペレーションの詳細は 「6.8 MySQL Full-text Search」節 を見てください。
- `FOREIGN KEY`、`CHECK`及び`REFERENCES`節は実際には何も行いません。 これらの構文は、互換性のためだけに用意されており、他のSQLサーバからのコードの 移植を容易にしたり、参照情報と共にテーブルを作成するようなアプリケーションを動作 させることを目的としています。 「1.4.4 MySQL に無い機能」節参照.
- 全ての`NULL`フィールドは、1ビット余計に消費し、直近のバイトに丸められます。
- レコードの最大長は、以下のようにして求められます:

      レコードの長さ = 1
                   + (フィールドの長さの合計)
                   + (NULLフィールドの数 + 7)/8
                   + (可変長フィールドの数)

- `table_options` と `SELECT` オプションは、 MySQL 3.23 以上でのみ実装されます。 テーブル型は：

  BDB または Berkeley_db | トランザクションセーフなテーブル 「7.5 BDB or Berkeley_DB Tables」節参照.
  HEAP | このテーブルのデータは、メモリー内にのみ蓄えられる 「7.4 HEAP Tables」節参照.
  ISAM | オリジナルのテーブル 「7.3 ISAM Tables」節参照.
  InnoDB | レコードロッキングを持ったトランザクション安全テーブル 「7.6 InnoDB テーブル」節参照.
  MERGE | 一つのテーブルとして使用される MyISAM テーブルの集まり 「7.2 MERGE Tables」節参照.
  MyISAM | ISAM にかわる 新しい バイナリ互換のテーブル。 「7.1 MyISAM Tables」節参照.

  「7 MySQL テーブル型」節参照. テーブル型が指定され、特定の型が有効でない場合、MySQL は指定され たものに近いテーブル型を選択します。例えば、`TYPE=BDB` が指定されて、 MySQL のディストリビューションが `BDB` テーブルをサポートし ない場合、代わりにテーブルは `MyISAM` として生成されます。 その他のテーブルオプションを使って、テーブルの振る舞いを最適化します。 たいていの場合は、オプションを明示する必要がありません。 明示的に指定されなかった場合、オプションはすべてのテーブル型に作用します。

  `AUTO_INCREMENT` | あなたがこのテーブルにセットしたい、次の auto_increment 値
  `AVG_ROW_LENGTH` | テーブルに含まれるレコードの長さのおおよその平均値。 可変長のレコードを持つ大きなテーブルに対してのみ、これをセットします。
  `CHECKSUM` | MySQL に全てのレコードをチェックさせたい場合、これを 1 にセットします。 (これは更新を遅くさせますが、不整合の生じたテーブルを見つけ出しやすくなります) (MyISAM)
  `COMMENT` | テーブルの、60文字コメント
  `MAX_ROWS` | あなたがテーブルに保存したいと考えている最大レコード数。
  `MIN_ROWS` | あなたがテーブルに保存したいと考えている最低レコード数
  `PACK_KEYS` | より小さいインデックスにしたいなら、これを 1 にします。 これは更新を遅くしますが、読み出しは速くなります (MyISAM, ISAM).
  `PASSWORD` | `.frm` ファイルをパスワード付きで暗号化。 このオプションは、標準の MySQL バージョンではなにも行いません。
  `DELAY_KEY_WRITE` | テーブルがクローズされるまでキーテーブルの更新を送らせたい場合、1に設定します(MyISAM)。
  `ROW_FORMAT` | レコードがどのように格納されるかを定義します。現在 DYNAMIC と STATIC オプションが MyISAM テーブルのために使用できるだけです。

  `MyISAM` テーブルを使用するならば、MySQL は `max_rows * avg_row_length` の値を、テーブルがどのくらい大きくなるか の推定に使用します。 もし、上記のオプションをなにも指定しなかった場合、テーブルの最大サイズは 4G になります。(か、あなたの OS が 2G しかサポートしていなければ 2G まで) この理由は、大きなファイルを本当に必要としない場合は、インデックスをより小 さく、より速くするため、ポインタサイズを小さく保持するためです。 `PACK_KEYS` を使用しない場合、デフォルトは文字列だけをパックし、数値 はパックしません。`PACK_KEYS=1` を使用するとさらに数値もパックされま す。 バイナリ数値キーをパックする時、MySQL はプレフィックス圧縮を使用 します。これは、同じ数値を多く持つ場合にだけこの大きな恩恵を得るということ を意味します。プレフィックス圧縮は、前のキーの何バイトが次のキーと同じであ るかを示すための余計な1バイトがすべてのキーに必要となることを意味します(注 意: レコードへのポインタは、圧縮の向上のため high-byte-first-order でキー の直後に格納されます)。これは、2つのレコードが同じキー多く持つ場合、後のす べての'同じ'キーは通常2バイト(レコードへのポインタを含む)だけを必要とする ということです。これを、通常のケースと比較してみてください。通常のケースは、 後のキーは'キーの格納サイズ' + ポインタサイズ(通常4)を必要とします。一方、 すべてのキーが全く異なっていると、キーが `NULL` 値を持つことができる キーではない場合では、キー毎に1バイトを消費します(この場合、パックされたキー の長さは、キーが `NULL` の時にマークのために使用されるのと同じバイト 数で格納されます)。
- もし `CREATE` ステートメントの後に `SELECT` を指定するならば、 MySQL は、`SELECT` で返ってくる全ての項目を収めるために、 新しいフィールドを作成します。 例えば：

      mysql> CREATE TABLE test (a int not null auto_increment,
                 primary key (a), key(b))
                 TYPE=MyISAM SELECT b,c from test2;

  これは 3つのフィールド a, b, c を `MyISAM` テーブルに作成します。 `SELECT` ステートメントからのフィールドがテーブルの右側に追加され、上 書きされないことに注意してください。次の例を見てください:

      mysql> select * from foo;
      +---+
      | n |
      +---+
      | 1 |
      +---+

      mysql> create table bar (m int) select n from foo;
      Query OK, 1 row affected (0.02 sec)
      Records: 1  Duplicates: 0  Warnings: 0

      mysql> select * from bar;
      +------+---+
      | m    | n |
      +------+---+
      | NULL | 1 |
      +------+---+
      1 row in set (0.00 sec)

  テーブル `foo` の各レコードについて、`foo` からの値と新しいフィー ルドのデフォルト値を伴って `bar` のレコードが 挿入されます。 `CREATE TABLE ... SELECT` will not automatically create any indexes for you. This is done intentionally to make the command as flexible as possible. If you want to have indexes in the created table, you should specify these before the `SELECT` statement:

      mysql> create table bar (unique (n)) select n from foo;

  もしデータをテーブルにコピーしている最中にエラーが起きたなら、 このテーブルは自動的に消去されることに注意してください。 更新ログ／バイナリログはオリジナルテーブルを再生成するために使用できます。 MySQL は `CREATE TABLE .... SELECT` 中に並行しての挿入を許し ません。
- `RAID_TYPE` オプションは、大規模ファイルをサポートしていない OS 上の 2G/4Gの制限を破る手助けをします。また、`RAID` ディレクトリを別の物理 ディスクに置くことにより、IO ボトルネックからさらに速度を得ることができま す。`RAID_TYPE` は、MySQL を `--with-raid` でコンフィグ すれば、どんな OS 上でも働きます。現在、`RAID_TYPE` は `STRIPED` だけが許されています(`1` と `RAID0` はこれの別名 です)。 `RAID_TYPE=STRIPED` を `MyISAM` テーブルに指定すると、 `MyISAM` はデータベースディレクトリ中に 00, 01, 02 という名前の `RAID_CHUNKS` サブディレクトリを生成します。これらのディレクトリのそ れぞれに、`MyISAM` は `table_name.MYD` を生成します。データファ イルにデータが書き込まれる時、`RAID` ハンドラは最初の `RAID_CHUNKSIZE` *1024 バイトを最初のファイルに、次の `RAID_CHUNKSIZE` *1024 バイトを次のファイルにマップします。
- `UNION` は同じテーブルの集まりを一つとして使用したい時に使用されます。 これは MERGE テーブルでだけ動作します。 「7.2 MERGE Tables」節参照。 今のところ、`MERGE` テーブルをマップするテーブル上に `SELECT`, `UPDATE`, `DELETE` 権限を持つことが必要です。マップされたすべて のテーブルは `MERGE` テーブルとして、同じデータベース内にある必要があ ります。
- 生成されたテーブルでは、`PRIMARY` キーは最初に置かれ、次にすべての `UNIQUE` キー、それから通常のキーが続きます。これは MySQL オ プティマイザを助け、どのキーを使用するかの優先度付けを行ない、重なった `UNIQUE` キーをさらにすばやく検出します。
- `DATA DIRECTORY="directory"` または `INDEX DIRECTORY="directory"` を使用することで、テーブルハンドラがテーブルとイン デックスファイルを置くべき場所を指定できます。`--skip-symlink` オプショ ンを使用しない時、これは `MySQL` 4.0 で `MyISAM` テーブルでだけ 動作します。 「5.6.1.2 Using Symbolic Links for Tables」節参照.

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

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

- `VARCHAR` columns with a length less than four are changed to `CHAR`.
- テーブル内にいくつかの可変長フィールドがある場合、結果的にレコード全体が可変長と なります。 その結果、テーブルがいくつかの可変長フィールド(`VARCHAR`、`TEXT`及び `BLOB`)を持つならば、3文字より大きいフィールド長の全ての`CHAR`フィールドは、 `VARCHAR`フィールドに変更されます。 このことは、フィールドの使用方法には影響しません。 MySQLでは、`VARCHAR`は文字列を格納するための1つの手段に過ぎません。 MySQLは、スペース埋めのコンバージョンを行いますし、テーブル操作もより速 く行います。 「7 MySQL テーブル型」節参照.
- `TIMESTAMP`フィールドの表示サイズは、2〜14の範囲の偶数でなければなりません。 表示サイズを0や14より大きく指定した場合、サイズは14に強制されます。1から13の範 囲の奇数の場合、大きい方の偶数値に強制されます。
- `TIMESTAMP` フィールドには `NULL` を代入できません； `NULL` は 現在の日時をセットします。 `NULL` and `NOT NULL` 属性は通常の方法では適用されず、それらを 与えた場合は無視されます。 `DESCRIBE tbl_name` は常に `TIMESTAMP` フィールドに `NULL` 値が割 り当てられた事を告げます。
- MySQL は他の SQL データベースの使用している型を MySQL 型に マップします。 「6.2.5 他のデータベースエンジンのフィールド型の使用」節参照.

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

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

### 6.5.4 `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    ADD FULLTEXT [index_name] (index_col_name,...)
      or	ADD [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name,...)
                [reference_definition]
      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 [TO] new_tbl_name
      or    ORDER BY col
      or    table_options

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

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

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

注意: `ALTER TABLE` に `RENAME` 以外のオプションを使用する場合、 MySQL は常に一時テーブルを生成します。データが厳密にコピーする必 要がないとしてもです(フィールドの名前を変更する時など)。 We plan to fix this in the future, but as one doesn't normally do `ALTER TABLE` that often this isn't that high on our TODO.

- `ALTER TABLE`を使うには、そのテーブルに ALTER、 INSERT、CREATE 権限が必要です。
- `IGNORE`はANSI SQL92に対するMySQLの拡張です。 これは、新しいテーブルのユニークキーで重複があった場合の動作を制御します。 `IGNORE`が指定されない場合、コピーは異常終了し、ロールバックされます。 `IGNORE`が指定された場合、ユニークキーの重複があったレコードに対し、最初の レコードだけを使用し、他は削除されます。
- 1つの`ALTER TABLE`ステートメントの中で、`ADD`、`ALTER`、 `DROP`、それから`CHANGE`節の複合的な発行が可能です。 これは、`ALTER TABLE`ステートメント毎に1つだけしかこれらの節を 許さないANSI SQL92に対するMySQLの拡張です。
- `CHANGE col_name`、`DROP col_name`及び`DROP INDEX`はANSI SQL92に対するMySQLの拡張です。
- `MODIFY` は `Oracle` の `ALTER TABLE` 拡張です。
- オプション語`COLUMN`は蛇足であり、記述を省くことが可能です。
- 他のオプション無しで`ALTER TABLE tbl_name RENAME TO new_name`を使用すると、 MySQLは`tbl_name`に一致するテーブルの名前を単純に変更します。 テンポラリテーブルの作成は必要としません。 「6.5.5 `RENAME TABLE` 構文」節参照.
- `create_definition`は、`CREATE TABLE`における`ADD`や`CHANGE` と同じ構文を使用します。 「6.5.3 `CREATE TABLE` 構文」節参照.
- `CHANGE old_col_name create_definition`節を使用することによりフィールドの名 前を変更することができます。 このようなことを行うためには、フィールドの旧名称と新名称、それからそのフィールド の現在の型を指定する必要があります。例えば、ある`INTEGER`フィールドを`a`から`b`に変更する場合、以下のように実行することができます:

      mysql> ALTER TABLE t1 CHANGE a b INTEGER;

  もしフィールドの名前を変えることなく、型だけを変更したい場合であっても、 この `CHANGE` 構文は、たとえ同じ名前であっても、 ２つの名前を指定するよう要求します。 例:

      mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;

  しかし MySQL バージョン 3.22.16a からは, `MODIFY` を使用して、 名称変更をすることなくフィールドの型を変更することができます。

      mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;

- `CHANGE` や `MODIFY` を使用して、フィールドの一部にインデックス が存在するようなフィールドを短くしようとしても(例えば `VARCHAR` フィー ルドの最初の10文字上ににインデックスがある場合)、インデックスされた文字数 よりもフィールドを短くすることはできません。
- `CHANGE` や `MODIFY` を用いてフィールドの型を変更する場合、 MySQLは可能な限り新しい型にデータをコンバートしようと試みます。
- MySQL バージョン 3.22以降では、 `FIRST`又は`ADD ... AFTER col_name`を使用して、 テーブルのレコード内の指定した位置に、フィールドを追加すること ができます。 デフォルトでは、フィールドは(そのレコードの)最後に追加されます。
- `ALTER COLUMN`は、フィールドの新たな初期値を指定したり、フィールドの古い初 期値を削除したりします。 古い初期値が削除され、フィールドが`NULL`を許す場合、新たな初期値は`NUL L`となります。 `NULL`が許されない場合、 「6.5.3 `CREATE TABLE` 構文」節 で 説明されている通り、MySQL は初期値を割り当てます。 「6.5.3 `CREATE TABLE` 構文」節.
- `DROP INDEX`は、インデックスを削除します。これはANSI SQL92に対する MySQL の拡張です。 「6.5.8 `DROP INDEX` 構文」節参照.
- フィールドがテーブルから削除されると、そのフィールドが含まれているインデックスか らもそのフィールドが削除されます。 インデックスを構成する全てのフィールドが削除されると、そのインデックスも削除され ます。
- テーブルが一つのフィールドだけを含む場合、フィールドは破棄できません。テー ブルを削除するつもりなら、`DROP TABLE` を代わりに使用してください。
- `DROP PRIMARY KEY`は、プライマリ・インデックスを削除します。もしプライマリ インデックスが存在しなければ、そのテーブルの最初の`UNIQUE`インデックスが削 除されます。 (MySQLは、明示的に`PRIMARY KEY`が指定されなければ最初の`UNIQU E`キーを`PRIMARY KEY`として扱います。) If you add a `UNIQUE INDEX` or `PRIMARY KEY` to a table, this is stored before any not `UNIQUE` index so that MySQL can detect duplicate keys as early as possible.
- `ORDER BY` は指定した順のレコードで新しいテーブルを生成することができ ます。注意: 挿入と削除の後にはこの順序は保持されません。テーブルを、後で order をしたいフィールドの順にしておくと MySQL のソートがより簡単 になる場合があります。このオプションは、主に一定の順でレコードをクエリする つもりであることを知っているときに、主に有用です; テーブルに大きな変更をし た後にこのオプションを使用することで、より高い性能を得ることができるdしょ う。
- `ALTER TABLE` を `MyISAM` テーブルに使用する場合、すべての非ユニー クインデックスは(`REPAIR` のような)別のバッチで生成されます。これは多 くのインデックスがある場合、`ALTER TABLE` をより速くします。
- C API関数`mysql_info()`により、どれだけのレコードがコピーされたか、(`I GNORE`が指定されている時は)どれだけのレコードがユニークキーの重複により削除され たかを調べることができます。
- `FOREIGN KEY`、`CHECK`及び`REFERENCES`節は、実際には 何もしません。これらの構文は、互換性のためだけに用意されており、 他のSQLサーバからのコードの移植を容易にしたり、 参照情報と共にテーブルを作成するようなアプリケーションを動作 させることを目的としています。 「1.4.4 MySQL に無い機能」節参照.

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

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

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

    mysql> ALTER TABLE t1 RENAME t2;

フィールド `a`を `INTEGER` から `TINYINT NOT NULL` に (名前は同じままで)変更し、 `b` を `CHAR(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;

To add a new `AUTO_INCREMENT` integer column named `c`:

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

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

`AUTO_INCREMENT` フィールドを追加した場合、フィールドの値は 自動的にシーケンス番号で埋められます。 最初のシーケンス番号は、`ALTER TABLE` 前に `SET INSERT_ID=#` を 実行するか、または `AUTO_INCREMENT = #` テーブルオプションを使用する ことで設定できます。 「5.5.6 `SET` 構文」節参照.

MyISAM テーブルでは、`AUTO_INCREMENT` フィールドを変更しない場合、シー ケンス番号は影響を受けません。`AUTO_INCREMENT` フィールドを破棄し、そ れから別の `AUTO_INCREMENT` フィールドを追加した場合、番号は再度 1 か ら始まります。

「A.6.1 Problems with `ALTER TABLE`.」節参照.

### 6.5.5 `RENAME TABLE` 構文

    RENAME TABLE tbl_name TO new_table_name[, tbl_name2 TO new_table_name2,...]

リネームは自動的に行なわれます。これは、他のスレッドはリネームが動作中はテー ブルのどこにもアクセスできないことを意味します。空のテーブルでテーブルを置 き換えることが可能です:

    CREATE TABLE new_table (...);
    RENAME TABLE old_table TO backup_table, new_table TO old_table;

リネームは左から右に行なわれます。２つのテーブルの名前を交換したい場合には、 次のようにする必要があることを意味します:

    RENAME TABLE old_table    TO backup_table,
                 new_table    TO old_table,
                 backup_table TO new_table;

２つのデータベースが同じディスク上にあれば、あるデータベースから他のデータ ベースにリネームすることも可能です:

    RENAME TABLE current_database.table_name TO other_database.table_name;

`RENAME` 実行時には、ロックされたテーブルや有効なトランザクションを持 つことはできません。元のテーブルで `ALTER` と `DROP` 権限を、新 しいテーブルで `CREATE` と `INSERT` 権限を持つことも必要です。

MySQL が複数のテーブルのリネームで何らかのエラーに遭遇した場合、 リネームしたすべてのテーブルを逆にリネームし、すべてを元の状態に戻します。

### 6.5.6 `DROP TABLE` Syntax

    DROP TABLE [IF EXISTS] tbl_name [, tbl_name,...] [RESTRICT | CASCADE]

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

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

`RESTRICT` と `CASCADE` は移植を簡単にするために許されています。 しばらくはこれらは何も行ないません。

注意: `DROP TABLE` はトランザクション安全ではなく、自動的に すべてのアクティブトランザクションをコミットします。

### 6.5.7 `CREATE INDEX` 構文

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

`CREATE INDEX` 構文は MySQL 3.22 より以前のバージョンではなにもし ません。 バージョン 3.22 以降で、`CREATE INDEX` はインデックスの作成のために `ALTER TABLE` を呼びだしています。 @xref{ALTER TABLE, , `ALTER TABLE`}.

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

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

`CHAR` と `VARCHAR` フィールドでは、インデックスはフィールドの一部分だ けを使用して 作成されます。これは `col_name(length)` 構文を使用します。 (`BLOB` と `TEXT` 節では 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 がどのようにしてインデックスを使用するかは → 「5.4.3 MySQL はどのようにインデックスを使用するか？」節.

`FULLTEXT` indexes can index only `VARCHAR` and `TEXT` columns, and only in `MyISAM` tables. `FULLTEXT` indexes are available in MySQL Version 3.23.23 and later. 「6.8 MySQL Full-text Search」節.

### 6.5.8 `DROP INDEX` 構文

    DROP INDEX index_name ON tbl_name

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

## 6.6 Basic MySQL User Utility Commands

### 6.6.1 `USE` 構文

    USE db_name

`USE db_name` 構文は、 MySQL に `db_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 の互換のために提供されています。

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

    {DESCRIBE | DESC} tbl_name {col_name | wild}

`DESCRIBE` is a shortcut for `SHOW COLUMNS FROM`. 「4.5.5.1 Retrieving information about Database, Tables, Columns, and Indexes」節参照.

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

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

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

`SHOW` 構文は似たような情報を提供します。 「4.5.5 `SHOW` 構文」節参照.

## 6.7 MySQL Transactional and Locking Commands

### 6.7.1 `BEGIN/COMMIT/ROLLBACK` 構文

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

もし トランザクションセーフのテーブル(like `BDB`, `InnoDB`) を使用するなら, 以下のコマンドで MySQL を 非 `autocommit` モード状態にすることができます：

    SET AUTOCOMMIT=0

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

ある一連のステートメントのために `AUTOCOMMIT` モードからスイッチし たい場合は、`BEGIN` または `BEGIN WORK` ステートメントを使用で きます。

    BEGIN;
    SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
    UPDATE table2 SET summmary=@A WHERE type=1;
    COMMIT;

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

If you do a `ROLLBACK` when you have updated a non-transactional table you will get an error (`ER_WARNING_NOT_COMPLETE_ROLLBACK`) as a warning. All transactional safe tables will be restored but any non-transactional table will not change.

If you are using `BEGIN` or `SET AUTOCOMMIT=0`, you should use the MySQL binary log for backups instead of the older update log. Transactions are stored in the binary log in one chunk, upon `COMMIT`, to ensure that transactions which are rolled back are not stored. 「4.9.4 The Binary Update Log」節参照.

The following commands automatically end a transaction (as if you had done a `COMMIT` before executing the command):

`ALTER TABLE` | `BEGIN` | `CREATE INDEX`
`DROP DATABASE` | `DROP TABLE` | `RENAME TABLE`
`TRUNCATE`

You can change the isolation level for transactions with `SET TRANSACTION ISOLATION LEVEL ...`. 「6.7.3 `SET TRANSACTION` 構文」節参照.

### 6.7.2 `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` を発行した場合やサーバーが接続を閉じた場合、 自動で解除されます。

The main reasons to use `LOCK TABLES` are for emulating transactions or getting more speed when updating tables. This is explained in more detail later.

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

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

When you use `LOCK TABLES`, you must lock all tables that you are going to use and you must use the same alias that you are going to use in your queries! If you are using a table multiple times in a query (with aliases), you must get a lock for each alias!

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

`LOCK TABLES` works as follows:

1. Sort all tables to be locked in a internally defined order (from the user standpoint the order is undefined).
2. If a table is locked with a read and a write lock, put the write lock before the read lock.
3. Lock one table at a time until the thread gets all locks.

This policy ensures that table locking is deadlock free. There is however other things one needs to be aware of with this schema:

If you are using a `LOW_PRIORITY_WRITE` lock for a table, this means only that MySQL will wait for this particlar lock until there is no threads that wants a `READ` lock. When the thread has got the `WRITE` lock and is waiting to get the lock for the next table in the lock table list, all other threads will wait for the `WRITE` lock to be released. If this becomes a serious problem with your application, you should consider converting some of your tables to transactions safe tables.

You can safely kill a thread that is waiting for a table lock with `KILL`. 「4.5.4 `KILL` 構文」節参照.

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

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

- テーブルをまとめて多くの操作を実行しようとする場合、使用しようとしているテー ブルをロックするととても速くなります。もちろん、他のスレッドは `READ` ロッ クされたテーブルの更新はできませんし、他のスレッドは `WRITE` ロックされた テーブルを読むことはできません。 The reason some things are faster under `LOCK TABLES` is that MySQL will not flush the key cache for the locked tables until `UNLOCK TABLES` is called (normally the key cache is flushed after each SQL statement). This speeds up inserting/updateing/deletes on `MyISAM` tables.
- `MySQL` のトランザクションをサポートしないテーブルハンドラーを使用 している場合、他のスレッドが `SELECT`,`UPDATE` の間に来ないことを 保証したいならば、`LOCK TABLES` を使用する必要があります。 次の例は安全のためには `LOCK TABLES` を必要とします：

      mysql> LOCK TABLES trans READ, customer WRITE;
      mysql> select sum(value) from trans where customer_id= some_id;
      mysql> update customer set total_value=sum_from_previous_statement
                 where customer_id=some_id;
      mysql> UNLOCK TABLES;

  `LOCK TABLES` を使用しない場合、`SELECT` の実行と `UPDATE` の 実行を行う間に、他のスレッドが新しい `trans` 行を挿入する隙ができます。

インクリメント アップデイト (`UPDATE customer SET value=value+new_value`) または `LAST_INSERT_ID()` 関数の使用により、多くの場合 `LOCK TABLES` を回避 できます。

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

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

You can lock all tables in all databases with read locks with the `FLUSH TABLES WITH READ LOCK` command. 「4.5.3 `FLUSH` 構文」節参照. This is very convenient way to get backups if you have a file system, like Veritas, that can take snapshots in time.

NOTE: `LOCK TABLES` is not transaction-safe and will automatically commit any active transactions before attempting to lock the tables.

### 6.7.3 `SET TRANSACTION` 構文

    SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
    [READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE]

Sets the transaction isolation level for the global, whole session or the next transaction.

The default behavior is to set the isolation level for the next (not started) transaction.

If you set the `GLOBAL` privilege it will affect all new created threads. You will need the `PROCESS` privilege to do do this.

Setting the `SESSION` privilege will affect the following and all future transactions.

You can set the default isolation level for `mysqld` with `--transaction-isolation=...`. 「4.1.1 mysqld コマンド行オプション」節参照.

## 6.8 MySQL Full-text Search

Since Version 3.23.23, MySQL has support for full-text indexing and searching. Full-text indexes in MySQL are an index of type `FULLTEXT`. `FULLTEXT` indexes can be created from `VARCHAR` and `TEXT` columns at `CREATE TABLE` time or added later with `ALTER TABLE` or `CREATE INDEX`. For large datasets, adding `FULLTEXT` index with `ALTER TABLE` (or `CREATE INDEX`) would be much faster than inserting rows into the empty table with a `FULLTEXT` index.

Full-text search is performed with the `MATCH` function.

    mysql> CREATE TABLE articles (
        ->   id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
        ->   title VARCHAR(200),
        ->   body TEXT,
        ->   FULLTEXT (title,body)
        -> );
    Query OK, 0 rows affected (0.00 sec)

    mysql> INSERT INTO articles VALUES
        -> (0,'MySQL Tutorial', 'DBMS stands for DataBase Management ...'),
        -> (0,'How To Use MySQL Efficiently', 'After you went through a ...'),
        -> (0,'Optimizing MySQL','In this tutorial we will show how to ...'),
        -> (0,'1001 MySQL Trick','1. Never run mysqld as root. 2. Normalize ...'),
        -> (0,'MySQL vs. YourSQL', 'In the following database comparison we ...'),
        -> (0,'MySQL Security', 'When configured properly, MySQL could be ...');
    Query OK, 5 rows affected (0.00 sec)
    Records: 5  Duplicates: 0  Warnings: 0

    mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database');
    +----+-------------------+---------------------------------------------+
    | id | title             | body                                        |
    +----+-------------------+---------------------------------------------+
    |  5 | MySQL vs. YourSQL | In the following database comparison we ... |
    |  1 | MySQL Tutorial    | DBMS stands for DataBase Management ...     |
    +----+-------------------+---------------------------------------------+
    2 rows in set (0.00 sec)

The function `MATCH` matches a natural language query `AGAINST` a text collection (which is simply the set of columns covered by a `FULLTEXT` index). For every row in a table it returns relevance - a similarity measure between the text in that row (in the columns that are part of the collection) and the query. When it is used in a `WHERE` clause (see example above) the rows returned are automatically sorted with relevance decreasing. Relevance is a non-negative floating-point number. Zero relevance means no similarity. Relevance is computed based on the number of words in the row, the number of unique words in that row, the total number of words in the collection, and the number of documents (rows) that contain a particular word.

The above is a basic example of using `MATCH` function. Rows are returned with relevance decreasing.

    mysql> SELECT id,MATCH (title,body) AGAINST ('Tutorial') FROM articles;
    +----+-----------------------------------------+
    | id | MATCH (title,body) AGAINST ('Tutorial') |
    +----+-----------------------------------------+
    |  1 |                        0.64840710366884 |
    |  2 |                                       0 |
    |  3 |                        0.66266459031789 |
    |  4 |                                       0 |
    |  5 |                                       0 |
    |  6 |                                       0 |
    +----+-----------------------------------------+
    5 rows in set (0.00 sec)

This example shows how to retrieve the relevances. As neither `WHERE` nor `ORDER BY` clauses are present, returned rows are not ordered.

    mysql> SELECT id, body, MATCH (title,body) AGAINST (
        -> 'Security implications of running MySQL as root') AS score
        -> FROM articles WHERE MATCH (title,body) AGAINST
        -> ('Security implications of running MySQL as root');
    +----+-----------------------------------------------+-----------------+
    | id | body                                          | score           |
    +----+-----------------------------------------------+-----------------+
    |  4 | 1. Never run mysqld as root. 2. Normalize ... | 1.5055546709332 |
    |  6 | When configured properly, MySQL could be ...  |   1.31140957288 |
    +----+-----------------------------------------------+-----------------+
    2 rows in set (0.00 sec)

This is more complex example - the query returns the relevance and still sorts the rows with relevance decreasing. To achieve it one should specify `MATCH` twice. Note, that this will cause no additional overhead, as MySQL optimizer will notice that these two `MATCH` calls are identical and will call full-text search code only once.

MySQL uses a very simple parser to split text into words. A ``word'' is any sequence of letters, numbers, ``''`, and ``_'`. Any ``word'' that is present in the stopword list or just too short (3 characters or less) is ignored.

Every correct word in the collection and in the query is weighted, according to its significance in the query or collection. This way, a word that is present in many documents will have lower weight (and may even have a zero weight), because it has lower semantic value in this particular collection. Otherwise, if the word is rare, it will receive a higher weight. The weights of the words are then combined to compute the relevance of the row.

Such a technique works best with large collections (in fact, it was carefully tuned this way). For very small tables, word distribution does not reflect adequately their semantical value, and this model may sometimes produce bizarre results.

    mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('MySQL');
    Empty set (0.00 sec)

Search for the word `MySQL` produces no results in the above example. Word `MySQL` is present in more than half of rows, and as such, is effectively treated as a stopword (that is, with semantical value zero). It is, really, the desired behavior - a natural language query should not return every second row in 1GB table.

A word that matches half of rows in a table is less likely to locate relevant documents. In fact, it will most likely find plenty of irrelevant documents. We all know this happens far too often when we are trying to find something on the Internet with a search engine. It is with this reasoning that such rows have been assigned a low semantical value in this particular dataset.

### 6.8.1 Fulltext restrictions

- All parameters to the `MATCH` function must be columns from the same table that is part of the same fulltext index.
- The argument to `AGAINST` must be a constant string.

### 6.8.2 Fine-tuning MySQL Full-text Search

Unfortunately, full-text search has no user-tunable parameters yet, although adding some is very high on the TODO. However, if you have a MySQL source distribution ( 「2.3 MySQL ソースディストリビューションのインストール」節参照.), you can somewhat alter the full-text search behavior.

Note that full-text search was carefully tuned for the best searching effectiveness. Modifying the default behavior will, in most cases, only make the search results worse. Do not alter the MySQL sources unless you know what you are doing!

- Minimal length of word to be indexed is defined in `myisam/ftdefs.h` file by the line

      #define MIN_WORD_LEN 4

  Change it to the value you prefer, recompile MySQL, and rebuild your `FULLTEXT` indexes.
- The stopword list is defined in `myisam/ft_static.c` Modify it to your taste, recompile MySQL and rebuild your `FULLTEXT` indexes.
- The 50% threshold is caused by the particular weighting scheme chosen. To disable it, change the following line in `myisam/ftdefs.h`:

      #define GWS_IN_USE GWS_PROB

  to

      #define GWS_IN_USE GWS_FREQ

  and recompile MySQL. There is no need to rebuild the indexes in this case.

### 6.8.3 New Features of Full-text Search to Appear in MySQL 4.0

This section includes a list of the fulltext features that are already implemented in the 4.0 tree. It explains More functions for full-text search entry of 「1.6.1 Things that should be in 4.0」節.

- `REPAIR TABLE` with `FULLTEXT` indexes, `ALTER TABLE` with `FULLTEXT` indexes, and `OPTIMIZE TABLE` with `FULLTEXT` indexes are now up to 100 times faster.
- `MATCH ... AGAINST` is going to supports the following boolean operators:
  - `+`word means the that word must be present in every row returned.
  - `-`word means the that word must not be present in every row returned.
  - `<` and `>` can be used to decrease and increase word weight in the query.
  - `~` can be used to assign a negative weight to a noise word.
  - `*` is a truncation operator.
  Boolean search utilizes a more simplistic way of calculating the relevance, that does not have a 50% threshold.
- Searches are now up to 2 times faster due to optimized search algorithm.
- Utility program `ft_dump` added for low-level `FULLTEXT` index operations (querying/dumping/statistics).

### 6.8.4 Full-text Search TODO

- Make all operations with `FULLTEXT` index faster.
- Support for braces `()` in boolean full-text search.
- Phrase search, proximity operators
- Boolean search can work without `FULLTEXT` index (yes, very slow).
- Support for "always-index words". They could be any strings the user wants to treat as words, examples are "C++", "AS/400", "TCP/IP", etc.
- Support for full-text search in `MERGE` tables.
- Support for multi-byte charsets.
- Make stopword list to depend of the language of the data.
- Stemming (dependent of the language of the data, of course).
- Generic user-supplyable UDF (?) preparser.
- Make the model more flexible (by adding some adjustable parameters to `FULLTEXT` in `CREATE/ALTER TABLE`).

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