第12章 SQL ステートメント構文

目次

12.1. データ定義ステートメント
12.1.1. ALTER DATABASE 構文
12.1.2. ALTER TABLE 構文
12.1.3. ALTER LOGFILE GROUP 構文
12.1.4. ALTER TABLESPACE 構文
12.1.5. ALTER SERVER 構文
12.1.6. CREATE DATABASE 構文
12.1.7. CREATE INDEX 構文
12.1.8. CREATE TABLE 構文
12.1.9. CREATE LOGFILE GROUP 構文
12.1.10. CREATE TABLESPACE 構文
12.1.11. CREATE SERVER 構文
12.1.12. DROP DATABASE 構文
12.1.13. DROP INDEX 構文
12.1.14. DROP TABLE 構文
12.1.15. DROP LOGFILE GROUP 構文
12.1.16. DROP TABLESPACE 構文
12.1.17. DROP SERVER 構文
12.1.18. RENAME DATABASE 構文
12.1.19. RENAME TABLE 構文
12.2. データ取り扱いステートメント
12.2.1. DELETE 構文
12.2.2. DO 構文
12.2.3. HANDLER 構文
12.2.4. INSERT 構文
12.2.5. LOAD DATA INFILE 構文
12.2.6. REPLACE 構文
12.2.7. SELECT 構文
12.2.8. サブクエリ構文
12.2.9. TRUNCATE 構文
12.2.10. UPDATE 構文
12.3. MySQL ユーティリティ ステートメント
12.3.1. DESCRIBE 構文
12.3.2. HELP 構文
12.3.3. USE 構文
12.4. MySQL トランザクションとロッキング関連のステートメント
12.4.1. START TRANSACTIONCOMMIT、そして ROLLBACK 構文
12.4.2. ロールバックできないステートメント
12.4.3. 暗黙のコミットを引き起こすステートメント
12.4.4. SAVEPOINTROLLBACK TO SAVEPOINT 構文
12.4.5. LOCK TABLESUNLOCK TABLES 構文
12.4.6. SET TRANSACTION 構文
12.4.7. XA トランザクション
12.5. データベース管理ステートメント
12.5.1. アカウント管理ステートメント
12.5.2. テーブル メンテナンス ステートメント
12.5.3. SET 構文
12.5.4. SHOW 構文
12.5.5. その他の管理ステートメント
12.6. 複製ステートメント
12.6.1. マスタ サーバをコントロールする SQL ステートメント
12.6.2. スレーブ サーバをコントロールする SQL ステートメント
12.7. プリペアド ステートメントの為の SQL 構文

この章では、MySQL にサポートされている SQL ステートメントの構文について説明します。後半の章に、ステートメントについての追加説明があります。

12.1. データ定義ステートメント

12.1.1. ALTER DATABASE 構文

ALTER {DATABASE | SCHEMA} [db_name]
    alter_specification [alter_specification] ...

alter_specification:
    [DEFAULT] CHARACTER SET charset_name
  | [DEFAULT] COLLATE collation_name

ALTER DATABASE でデータベースの全体的な特徴を変更する事ができます。これらの特徴は、データベースディレクトリの db.opt ファイルに格納されています。ALTER DATABASE を利用する為には、データベース上の ALTER 権限が必要です。ALTER SCHEMAALTER DATABASE の同義語です。

CHARACTER SET 条項はデフォルト データベースの文字セットを変更します。COLLATE 条項はデフォルト データベースの照合を変更します。章?9. キャラクタセットサポートは文字セットと照合名を検討します。

ステートメントがデフォルト データベースに適応する場合、データベース名は省略する事ができます。

MySQL Enterprise 製造環境では、データベースの変更は頻繁に起こる事ではないので、セキュリティ違反を意味するかもしれません。MySQL ネットワーク モニタリングとアドバイス サービスの一環で提供されるアドバイザーが、データ定義ステートメントが発行されると、自動的に警告を発します。追加情報については http://www-jp.mysql.com/products/enterprise/advisors.html を参照してください。

12.1.2. ALTER TABLE 構文

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

alter_specification:
    table_option ...
  | ADD [COLUMN] column_definition [FIRST | AFTER col_name ]
  | ADD [COLUMN] (column_definition,...)
  | ADD {INDEX|KEY} [index_name] [index_type] (index_col_name,...)
  | ADD [CONSTRAINT [symbol]]
        PRIMARY KEY [index_type] (index_col_name,...)
  | ADD [CONSTRAINT [symbol]]
        UNIQUE [INDEX|KEY] [index_name] [index_type] (index_col_name,...)
  | ADD FULLTEXT [INDEX|KEY] [index_name] (index_col_name,...)
      [WITH PARSER parser_name]
  | ADD SPATIAL [INDEX|KEY] [index_name] (index_col_name,...)
  | ADD [CONSTRAINT [symbol]]
        FOREIGN KEY [index_name] (index_col_name,...)
        [reference_definition]
  | ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
  | CHANGE [COLUMN] old_col_name column_definition
        [FIRST|AFTER col_name]
  | MODIFY [COLUMN] column_definition [FIRST | AFTER col_name]
  | DROP [COLUMN] col_name
  | DROP PRIMARY KEY
  | DROP {INDEX|KEY} index_name
  | DROP FOREIGN KEY fk_symbol
  | DISABLE KEYS
  | ENABLE KEYS
  | RENAME [TO] new_tbl_name
  | ORDER BY col_name [, col_name] ...
  | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
  | [DEFAULT] CHARACTER SET charset_name [COLLATE collation_name]
  | DISCARD TABLESPACE
  | IMPORT TABLESPACE
  | PARTITION BY partition_options
  | ADD PARTITION (partition_definition)
  | DROP PARTITION partition_names
  | COALESCE PARTITION number
  | REORGANIZE PARTITION partition_names INTO (partition_definitions)
  | ANALYZE PARTITION partition_names
  | CHECK PARTITION partition_names
  | OPTIMIZE PARTITION partition_names
  | REBUILD PARTITION partition_names
  | REPAIR PARTITION partition_names
  | REMOVE PARTITIONING

index_col_name:
    col_name [(length)] [ASC | DESC]

index_type:
    USING {BTREE | HASH}

ALTER TABLE で既存テーブルの構造を変更する事ができます。例えば、カラムの追加や削除、インデックスの作成や破壊、既存カラム タイプの変更、またはカラムやテーブル自体の名前の変更をする事ができます。テーブルや、テーブル タイプのコメントを変更する事もできます。

多くの許容される変更の構文は、CREATE TABLE ステートメントの条項に似ています。詳細については、項12.1.8. 「CREATE TABLE 構文」 をご参照ください。

ストレージ エンジンがその操作をサポートしていないテーブルに対しては、いくつかの操作の結果は警告になってしまうかもしれません。これらの警告は SHOW WARNINGS で表示する事ができます。詳しくは 項12.5.4.31. 「SHOW WARNINGS 構文」 を参照してください。

ほとんどの場合、 ALTER TABLE は元テーブルのテンポラリ コピーを作成する事で起動します。そのコピー上で変更が行われ、その後元テーブルが削除されて新しいテーブルがリネームされます。ALTER TABLE が実行している間、他のクライアントが元テーブルを読む事ができます。新しいテーブルの準備ができるまで更新と書き込みは止められ、その後更新に失敗する事なく新しいテーブルに自動的にリダイレクトされます。

テンポラリ テーブルが必要ない場合がいくつかあります。

  • もし、他のオプション無しで ALTER TABLE tbl_name RENAME TO new_tbl_name を利用すると、MySQLはテーブル tbl_name に対応する全てのファイルをリネームします。(テーブルをリネームする為に RENAME TABLE ステートメントを利用する事もできます。詳しくは 項12.1.19. 「RENAME TABLE 構文」 を参照してください。)リネームされたテーブルに与えられた権限は、新しい名前に移動しません。それらは手動で変更しなければいけません。

  • ALTER TABLE ...ADD PARTITION はMySQLクラスタ以外にテンポラリテーブルを作成しません。RANGELIST パーティションの ADDDROP 操作は直接の操作、またはそれに近い操作です。HASHKEY パーティションの ADDCOALESCE 操作は変更されたパーティション間でデータをコピーします。 LINEAR HASH/KEY が利用されていない限り、これは新しいテーブルを作成するのとほとんど変わりません。(操作はパーティションごとに行われますが。)REORGANIZE 操作は変更されたパーティションだけをコピーし、変更されていない物には関係しません。

そうでない場合は、そのデータが必ずコピーされる必要がある訳ではなくても、MySQL がテンポラリ テーブルを作成します。 (カラム名を変更した時と同じように)MyISAM テーブルは、高い値に myisam_sort_buffer_size システム変数を設定する事で、インデックスの再作成操作のスピードを上げる事ができます。 (これは変更プロセスの中で一番遅い操作です。)

  • ALTER TABLE を利用するには、テーブルに ALTERINSERT、そして CREATE 権限が必要です。

  • IGNORE はスタンダード SQL の MySQL 拡張子です。これは、新しいテーブルのユニーク キーに複製があったり、ストリクト モードが有効時に警告が出たりした時に ALTER TABLE がどのように機能するかコントロールします。もし IGNORE が指定されなければ、複製キー エラーが起きた時、コピーは異常終了し、元に戻されます。もし IGNORE が指定されると、ユニーク キーに複製された行の、最初の行だけが使用され、それ以外の相反する行は削除されます。不正な値は、適合する許容値に一番近い値まで切り捨てられます。

  • table_optionCREATE TABLE ステートメントで利用する事ができる種類のテーブル オプションを意味します。(項12.1.8. 「CREATE TABLE 構文」 に全てのテーブル オプションがリストされています。)これは、 ENGINEAUTO_INCREMENT、そして AVG_ROW_LENGTH 等のオプションを含んでいます。しかし、ALTER TABLEDATA DIRECTORYINDEX DIRECTORY テーブル オプションを無視します。

    例えば、テーブルが InnoDB テーブルになるように変換するには、このステートメントを利用します。

    ALTER TABLE t1 ENGINE = InnoDB;
    

    MySQL 5.1.11 以降のバージョンでは、不注意なデータ ロスを防ぐ為に、テーブルのストレージ エンジンを MERGEBLACKHOLE 変更する時に ALTER TABLE を利用する事はできません。

    AUTO_INCREMENT カウンターを新しい行で使用するように値を変える為には、これを行って下さい。

    ALTER TABLE t2 AUTO_INCREMENT = value;
    

    既に使用されている値と同じ、またはそれ以下の値にカウンターをリセットする事はできません。MyISAM では、AUTO_INCREMENT カラム内の値が現在の最高値と同じかそれ以下の値なら、その値は現在の最高値プラス1にリセットされます。InnoDBでは、もしその値がカラム内の現在の最高値以下であれば、エラー メッセージは表示されず、現在のシーケンス値は変更されません。

  • 単一 ALTER TABLE ステートメントの中で、カンマで区切られた複数の ADDALTERDROP、 そして CHANGE 条項を発行する事ができます。これは、1つの ALTER TABLE ステートメントに対して1つの条項しか許可しない、スタンダード SQL の MySQL 拡張子です。例えば、単一ステートメントに複数のカラムをドロップするには、これを実行してください。

    ALTER TABLE t2 DROP COLUMN c, DROP COLUMN d;
    
  • CHANGE col_nameDROP col_name、そして DROP INDEX はスタンダード SQL の MySQL 拡張子です。

  • MODIFYALTER TABLE のオラクル拡張子です。

  • COLUMN という言葉は任意であり、省く事ができます。

  • column_definition 条項は CREATE TABLE と同じように、 ADDCHANGE に同じ構文を利用します。この構文は、データタイプだけでなく、カラム名も含むという事を覚えておいて下さい。詳しくは 項12.1.8. 「CREATE TABLE 構文」 を参照してください。

  • CHANGE old_col_name column_definition 条項を利用してカラムをリネームする事ができます。それを行うには、カラムの古い名前と新しい名前、そして現在そのカラムが持つタイプを指定してください。例えば、INTEGER カラムを a から b にリネームするには、次の物を実行する事ができます。

    ALTER TABLE t1 CHANGE a b INTEGER;
    

    もしカラム名ではなくカラム タイプを変更したければ、 CHANGE 構文には、両方同じだとしても古いカラム名と新しいカラム名が必要です。例:

    ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
    

    リネームせずにカラム タイプを変更するには、MODIFY を利用する事もできます。

    ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
    
  • インデックスを持つカラムを短くする為に CHANGEMODIFY を利用し、その結果カラム長がインデックス長よりも短くなるなら、MySQL はインデックスを自動的に短くします。

  • CHANGEMODIFY を利用してデータタイプを変更する時、MySQL は既存カラムを新しいタイプに可能な限り変換しようと試みます。

  • テーブル行の中の指定した場所にカラムを追加するには、FIRSTAFTER col_name を利用してください。デフォルトはカラムを最後に追加します。CHANGEMODIFY 操作の中で FIRSTAFTER を利用する事もできます。

  • ALTER ...SET DEFAULT または ALTER ...DROP DEFAULT はそれぞれ、カラムに新しいデフォルト値を指定したり、古いデフォルト値を削除したりします。もし古いデフォルトが削除されて、カラムが NULL になり得るなら、新しいデフォルトは NULL です。もしカラムが NULL になり得ないなら、項10.1.4. 「データタイプデフォルト値」 に説明されているように、MySQLはデフォルト値を割り当てます。

  • DROP INDEX はインデックスを削除します。これはスタンダード SQL の MySQL 拡張子です。詳しくは 項12.1.13. 「DROP INDEX 構文」 を参照してください。

  • もしカラムがテーブルからドロップされると、そのカラムが関わっている全てのインデックスからも削除されます。もし1つのインデックスを構成している全てのカラムがドロップされると、そのインデックスもドロップされます。

  • もしテーブルがカラムを1つだけ含んでいると、そのカラムはドロップできません。もしテーブルを削除したいのであれば、代わりに DROP TABLE を利用してください。

  • DROP PRIMARY KEY はプライマリ インデックスをドロップします。注意:MySQL の古いバージョンは、もしプライマリ インデックスが存在しなければ、DROP PRIMARY KEY はテーブルの中の最初の UNIQUE インデックスをドロップします。これは、主キーがエラーにならないテーブルに DROP PRIMARY KEY を利用しようとしている MySQL 5.1 では起こりません。

    もし UNIQUE INDEXPRIMARY KEY がテーブルに追加されると、MySQL が重複キーをなるべく早く見つけられるように、非ユニーク インデックスの前に格納されます。

  • いくつかのストレージ エンジンでは、インデックスを作成する時にタイプを指定する事ができます。index_type 指定子の構文は USING type_name です。MySQL 5.1.10 以前では、USING はインデックス カラム リストの前だけに与える事ができました。5.1.10 以降のバージョンでの望ましい位置は、カラム リストの後ろです。MySQL 5.3 以降は、カラム リストの前でのオプションの使用は見られません。

  • ORDER BY で指定した順番の行で新しいテーブルを作成する事ができます。挿入と削除の後ではテーブルの順番が変わってしまう事を覚えておいて下さい。このオプションは、ほとんど毎回同じ順番で行のクエリを行う場合に便利です。テーブルに大きい変更を行った後にこのオプションを利用すると、高い性能を得る事が可能でしょう。テーブルが、後でカラムをオーダーしたい順番になっていれば、MySQL のソートは簡単になる場合があります。

    ORDER BY 構文は、ソートの昇順や降順を指示する為に、それぞれが任意で ASC または DESC が付随する1つか2つのカラム名を指定できます。デフォルトは昇順です。カラム名だけがソート基準として許されていて、任意の式は許されていません。

  • MyISAM テーブル上でALTER TABLE を利用すると、別のバッチに全ての非ユニークインデックスが作成されます。 ( REPAIR TABLE に関して)多くのインデックスがある時は、この方法で ALTER TABLE が大変早くなります。

    この特徴は明確に起動する事ができます。ALTER TABLE ... DISABLE KEYS は MySQL に MyISAM テーブルの非ユニーク インデックスの更新を停めるよう命令します。ALTER TABLE ...その時は、欠けているインデックスを再作成する為に ALTER TABLE ...ENABLE KEYS を利用する必要があります。MySQL は、キーを1つ1つ挿入するよりも大変早い特別なアルゴリズムを利用してこの作業を行いますので、大量挿入を行う前にキーを無効化しておく事でかなりのスピードアップを実現する事ができます。ALTER TABLE ...の利用ALTER TABLE ...DISABLE KEYS の利用は、先に触れられた権限に加え、INDEX 権限を必要とします。

    ENABLE KEYSDISABLE KEYS は、MySQL 5.1.11 以前では分割されたテーブルに対してはサポートされていませんでした。(バグ #19502)

  • FOREIGN KEYREFERENCES 条項は、ADD [CONSTRAINT [symbol]] FOREIGN KEY (...) REFERENCES ... (...) を施行する InnoDB ストレージ エンジンにサポートされています。詳しくは 項13.5.6.4. 「FOREIGN KEY 制約」 を参照してください。その他のストレージ エンジンでは、条項は解析されますが、無視されます。CHECK 条項は、全てのストレージ エンジンに解析されますが、無視されます。詳しくは 項12.1.8. 「CREATE TABLE 構文」 を参照してください。構文を受け入れながらも無視するのは、別のSQLサーバからコードをポートし易くし、参照を利用してテーブルを作成するアプリケーションを起動させるという、互換性の為です。詳しくは 項1.8.5. 「MySQLと標準SQLとの違い」 を参照してください。

    単一 ALTER TABLE ステートメントの別々の条項の中に外部キーを追加したりドロップしたりはできません。別々のステートメントを利用しなければいけません。

  • InnoDB は外部キーをドロップする為の ALTER TABLE の利用をサポートします。

    ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol;
    

    単一 ALTER TABLE ステートメントの別々の条項の中に外部キーを追加したりドロップしたりはできません。別々のステートメントを利用しなければいけません。

    追加情報については を参照してください。項13.5.6.4. 「FOREIGN KEY 制約」

  • テーブルが書き込みロックされ、ALTER TABLE がテーブル構造を変更するのに利用されると、保留中の INSERT DELAYED ステートメントは失われてしまいます。

  • もしテーブルのデフォルト文字セットと全ての文字カラム(CHARVARCHARTEXT)を新しい文字セットに変更したければ、このようなステートメントを利用してください。

    ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;
    

    警告: 先行操作が文字セット間でカラム値の変換を行います。もし1つの文字セット内にカラムを持つが(latin1等)、格納値は実際には別の互換性の無い文字セット(utf8 等) を利用しているという場合には、これは 必要ではありません。このような場合は、それぞれのカラムに対して次のような作業が必要になります。

    ALTER TABLE t1 CHANGE c1 c1 BLOB;
    ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;
    

    BLOB カラムへの、またはそれからの変換時には変換が起きない為、これが有効なのです。

    CONVERT TO CHARACTER SET binary を指定すると、CHARVARCHAR、そして TEXT カラムはそれぞれが対応するバイナリ文字列タイプに変換されます。(BINARYVARBINARYBLOB)これは、そのカラムはそれ以上文字セットを持たなくなり、それに続く CONVERT TO 操作が適応されないという事を意味します。

    テーブルの default 文字セットだけを変更するには、このステートメントを利用してください。

    ALTER TABLE tbl_name DEFAULT CHARACTER SET charset_name;
    

    DEFAULT という言葉は任意です。テーブルに追加する新しいカラムの文字セットを指定しなければ、デフォルトの文字セットがその時に利用される文字セットです。(例えば、ALTER TABLE ... ADD column と共に)

  • .ibd ファイルの中のテーブルスペースで作成された InnoDB テーブルに対して、そのファイルは廃棄、またインポートする事ができます。.ibd ファイルを廃棄する為には、このステートメントを利用してください。

    ALTER TABLE tbl_name DISCARD TABLESPACE;
    

    これは現在の .ibd ファイル削除しますので、まずバックアップがある事を確認してください。テーブルスペース ファイルが廃棄されている最中にテーブルにアクセスしようとすると、エラーが発生します。

    .ibd のバックアップ ファイルをインポートする為には、まずそれをデータベース ディレクトリにコピーし、そしてこのステートメントを発行してください。

    ALTER TABLE tbl_name IMPORT TABLESPACE;
    

    項12.2.7. 「SELECT 構文」を参照してください。

  • MySQL 5.1.5では ALTER TABLE の領域確保に関する拡張子がいくつか追加されました。これらは、領域確保されたテーブルと共に、再領域確保、追加、ドロップ、マージ、そしてパーティションの分割、また、領域確保のメンテナンスを行う為に利用する事ができます。

    そのまま partition_options 条項を領域確保されたテーブル上で ALTER TABLE と共に利用すると、partition_options によって定義された領域確保スキームに従って、そのテーブルを再領域確保します。この条項は必ず PARTITION BY で始まり、CREATE TABLEpartition_options 条項に適応するのと同様で、同じ構文と別のルールが後に続きます。(さらに詳細な説明については 項12.1.8. 「CREATE TABLE 構文」 を参照してください。) また、まだ分割されていない既存テーブルの分割に利用する事もできます。例えば、この様に定義された(領域確保されていない)テーブルを見てください。

    CREATE TABLE t1 (
        id INT,
        year_col INT
    );
    

    このテーブルは id カラムを領域確保キーとして利用し、HASHによって、このステートメントを用いて、8区画に分割する事ができます。

    ALTER TABLE t1
        PARTITION BY HASH(id)
        PARTITIONS 8;
    

    ALTER TABLE ... PARTITION BY ステートメントを利用して作成されたテーブルは、CREATE TABLE ... PARTITION BY を利用して作成された物と同じルールに従わなければいけません。これは、領域確保制限でも説明されているように、テーブルが持っているであろう全てのユニークキー間(主キーを含む)の関係を管理するルール、そして分割式の中で利用されるカラムを含みます。領域確保キーとユニークキー分割数を指定する為の CREATE TABLE ... PARTITION BY ルールは、 ALTER TABLE ... PARTITION BY にも適応します。

    ALTER TABLE ... PARTITION BY は MySQL 5.1.6 から利用可能になりました。

    ALTER TABLE ADD PARTITIONpartition_definition 条項は、同名のCREATE TABLE ステートメント条項に対して同名の条項がするのと同じように、同じオプションをサポートします。(構文と説明に関しては 項12.1.8. 「CREATE TABLE 構文」 を参照してください。)ここに表示されているように、分割済のテーブルが作成されていると仮定します。

    CREATE TABLE t1 (
        id INT,
        year_col INT
    )
    PARTITION BY RANGE (year_col) (
        PARTITION p0 VALUES LESS THAN (1991),
        PARTITION p1 VALUES LESS THAN (1995),
        PARTITION p2 VALUES LESS THAN (1999)
    );
    

    次のように、2002 以下の数値を格納する為にこのテーブルに新しいパーティション p3 を追加する事ができます。

    ALTER TABLE t1 ADD PARTITION (PARTITION p3 VALUES LESS THAN (2002));
    

    1つ、または複数の RANGELIST 分割をドロップする為に DROP PARTITION を利用する事ができます。このステートメントは HASHKEY パーティションと一緒に利用する事はできませんが、代わりに COALESCE PARTITION を利用してください。(下記参照)partition_names リストの中で名前が付けられた、ドロップされたパーティションに格納されたデータは全て廃棄されます。例えば、あらかじめ定義されたテーブル t1 を利用し、ここに表されているように p0p1 という名前が付いたパーティションをドロップする事ができます。

    ALTER TABLE t1 DROP PARTITION p0, p1;
    

    DROP PARTITIONNDB Cluster ストレージ エンジンを利用するテーブルと一緒には機能しない事を覚えて置いてください。項15.3.1. 「RANGELIST パーティションの管理」項14.13. 「MySQL Cluster の既知の制限」 を参照して下さい。

    ADD PARTITIONDROP PARTITION は現在 IF [NOT] EXISTS をサポートしていません。パーティションや分割されたテーブルをリネームする事も不可能です。その代わりに、もしパーティションをリネームしたいのであれば、パーティションをドロップして再作成する必要があります。そしてもし分割済テーブルをリネームしたければ、全てのパーティションをドロップし、テーブルをリネームし、そしてドロップされたパーティションをもう一度追加する必要があります。

    数字 でパーティション数を減らす為に HASHKEY で分割されたテーブルと一緒に COALESCE PARTITION を利用する事ができます。次の定義を利用して t2 テーブルを作成したと仮定してください。

    CREATE TABLE t2 (
        name VARCHAR (30),
        started DATE
    )
    PARTITION BY HASH( YEAR(started) )
    PARTITIONS 6;
    

    次のステートメントを利用して t2 で利用されたパーティション数を6から4に減らす事ができます。

    ALTER TABLE t2 COALESCE PARTITION 2;
    

    最後の number パーティションに含まれているデータは、残りのパーティションにマージする事ができます。この場合、パーティション4と5は、最初の4つのパーティションにマージされます。(パーティション0、1、2、そして3)

    分割されたテーブルで利用されたパーティションのいくつかを変更するには、REORGANIZE PARTITION を利用する事ができます。このステートメントの利用方法はいくつかあります:

    • いくつかのセットになったパーティションを単一パーティションにマージする。この方法は、いくつかのパーティションに partition_names リストの中で名前をつけ、 partition_definitionに1つの定義を付ける事で行う事ができます。

    • 1つの既存パーティションをいくつかのパーティションに分割する。これは、単一パーティションに partition_names で名前をつけ、いくつかの partition_definitions を与える事で実行できます。

    • VALUES LESS THAN を利用して定義されたパーティションのサブセットの範囲、または VALUES IN を利用して定義されたパーティションのサブセットの値リストを変更する。

    注意:明確に名前が付けられていないパーティションに対しては、MySQL は自動的にp0p1p2、などのようなデフォルト名を付けます。MySQL 5.1.7 以降のバージョンでは、サブ パーティションに関しても同じ事が言えます。

    ALTER TABLE ... REORGANIZE PARTITION ステートメントに関する詳細情報と例に関しては、 項15.3. 「パーティショニング管理」 を参照してください。

  • いくつかの追加条項は、パーティションのメンテナンスと修復機能に似た物を、CHECK TABLEREPAIR TABLE (分割されたテーブルにはサポートされて いない物 ) などの様なステートメントを利用して、分割されていないテーブルに提供します。これらには、ANALYZE PARTITIONCHECK PARTITIONOPTIMIZE PARTITIONREBUILD PARTITION、そして REPAIR PARTITION が含まれます。これらのオプションのそれぞれは、カンマで区切られた1つか複数のパーティション名で構成される partition_names 条項を利用します。パーティションは変更されるテーブルの中に既に存在していなければいけません。これらについての更なる情報や例については、 項15.3.3. 「パーティションのメンテナンス」 を参照してください。

  • テーブルや、そのデータに影響を与える事無くテーブルの分割を除去できるようにする為、MySQL 5.1.8 で REMOVE PARTITIONING が導入されました。(以前は ENGINE オプションを利用して行われていました。)このオプションは、追加、ドロップ、ドロップ カラムやインデックスをリネームする為に利用されるような、ALTER TABLE オプションと組み合わせる事ができます。

    MySQL 5.1.7 以前のバージョンでは、ENGINE オプションを ALTER TABLE と一緒に利用すると、テーブルが削除されてしまう可能性がある領域確保の原因になりました。MySQL5.1.8 からは、このオプションによる、テーブルに利用されるストレージ エンジンの変更はほとんど無く、領域確保にも全く影響を与えません。

mysql_info() C API 機能を利用すると、いくつの行がコピーされ、(IGNORE が利用された時) いくつの行がユニークキー値の複製の為に削除されたのかを確認する事ができます。詳しくは 項23.2.3.35. 「mysql_info() を参照してください。

ALTER TABLE の利用方法を表すいくつかの例があります。ここに表されているように作成された、テーブル t1 から始めましょう。

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

t1 から t2 のテーブルの名前を付けるには

ALTER TABLE t1 RENAME t2;

カラム aINTEGER から TINYINT NOT NULL (同じ名前のまま)に変更する為に、そしてカラム b を、b から c に変更するのと同じように、CHAR(10) から CHAR(20) に変更する為には:

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

d と名づけられた新しい TIMESTAMP カラムを追加する為には:

ALTER TABLE t2 ADD d TIMESTAMP;

カラム d とカラム a にインデックスを追加する為には:

ALTER TABLE t2 ADD INDEX (d), ADD INDEX (a);

カラム c を取り除く為には:

ALTER TABLE t2 DROP COLUMN c;

c と名づけられた新しい AUTO_INCREMENT カラムを追加する為には:

ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
  ADD PRIMARY KEY (c);

AUTO_INCREMENT カラムはインデックスされなければいけない為、c (PRIMARY KEY として)をインデックスした、そして、主キー カラムは NULL になり得ない為 cNOT NULL として宣言したという事を覚えておいて下さい。

AUTO_INCREMENT カラムを追加する時、カラム値はシーケンス番号で自動的にファイルされます。MyISAM テーブルには、ALTER TABLE の前に SET INSERT_ID=value を実行する事、またはAUTO_INCREMENT=value テーブルオプションを利用する事により最初のシーケンス番号を設定する事ができます。詳しくは 項12.5.3. 「SET 構文」 を参照してください。

MyISAM テーブルを利用すると、AUTO_INCREMENT カラムを変更しなければ、シーケンス番号は影響を受けません。もし AUTO_INCREMENT カラムをドロップし、そして別の AUTO_INCREMENT カラムを追加すると、番号は1から始まる順番に並べ直されます。

レプリケーションが利用された時、テーブルに AUTO_INCREMENT カラムを追加してもスレーブとマスターの行は同じ順番にはならないでしょう。これは、行の番号付けがテーブルに利用される特別なストレージ エンジンと、行が挿入される順番によって決まる為に起こります。もしマスターとスレーブ上で同じ順番である事が重要であれば、AUTO_INCREMENT 番号を割り当てる前に行の順番を整えておく必要があります。テーブル t1AUTO_INCREMENT カラムを追加したいと仮定して、次のステートメントは t1 と同一の AUTO_INCREMENT カラムを持つ新しいテーブル t2 を作成します。

CREATE TABLE t2 (id INT AUTO_INCREMENT PRIMARY KEY) 
SELECT * FROM t1 ORDER BY col1, col2;

これは、テーブル t1 はカラム col1col2 を持つと仮定します。

このステートメント セットはまた、t1 と同一の AUTO_INCREMENT カラムを追加した

新しいテーブル t2 を作成します。

CREATE TABLE t2 LIKE t1;
ALTER TABLE T2 ADD id INT AUTO_INCREMENT PRIMARY KEY;
INSERT INTO t2 SELECT * FROM t1 ORDER BY col1, col2;

重要:マスターとスレーブ上で同じ順番である事を保障する為に、t1全てのカラムは ORDER BY 条項内で参照を付けられる必要があります。

AUTO_INCREMENT カラムを持つコピーを作成、実装する為に利用した方法に関わらず、最後のステップは元テーブルをドロップし、コピーをリネームする事です。

DROP t1;
ALTER TABLE t2 RENAME t1;

項B.1.7.1. 「Problems with ALTER TABLE も参照してください。

12.1.3. ALTER LOGFILE GROUP 構文

ALTER LOGFILE GROUP logfile_group
    ADD UNDOFILE 'file'
    INITIAL_SIZE [=] size
    ENGINE [=] engine

このステートメントは、'file' と名付けられた UNDO ファイルを、既存ログファイルグループ logfile_group に追加します。ALTER LOGFILE GROUP ステートメントはたった一つの ADD UNDOFILE 条項を持ちます。DROP UNDOFILE 条項はサポートされていません。

INITIAL_SIZE パラメータは UNDO ファイルの冒頭のサイズをバイトで設定します。my.cnf で利用されている物と同様、大きさによって一文字の省略形を持つ size に従う事もできます。通常これは M (メガ バイト) か G (ギガ バイト)のどちらかの文字です。

ENGINE パラメータ(要求された)が、このログ ファイル グループによって利用されるストレージエンジンを決め、その名前はengine となります。MySQL 5.1では、engine に受け入れられる値は NDBNDBCLUSTER だけです。

ここに、ログ ファイル グループ lg_3 が既に CREATE LOGFILE GROUP を利用して作成されていると仮定した例があります。(項12.1.9. 「CREATE LOGFILE GROUP 構文」 を参照してください。)

ALTER LOGFILE GROUP lg_3
    ADD UNDOFILE 'undo_10.dat'
    INITIAL_SIZE=32M
    ENGINE=NDB;

ALTER LOGFILE GROUPENGINE = NDB と共に利用された時、UNDO ログ ファイルがそれぞれのクラスタ データ ノード上に作成されます。INFORMATION_SCHEMA.FILES テーブルに問い合わせする事によって UNDO ファイルが作成され、それらの情報を得た事を証明する事ができます。例:

mysql> SELECT FILE_NAME, LOGFILE_GROUP_NUMBER, EXTRA 
    -> FROM INFORMATION_SCHEMA.FILES 
    -> WHERE LOGFILE_GROUP_NAME = 'lg_3';
+-------------+----------------------+----------------+
| FILE_NAME   | LOGFILE_GROUP_NUMBER | EXTRA          |
+-------------+----------------------+----------------+
| newdata.dat |                    0 | CLUSTER_NODE=3 |
| newdata.dat |                    0 | CLUSTER_NODE=4 |
| undo_10.dat |                   11 | CLUSTER_NODE=3 |
| undo_10.dat |                   11 | CLUSTER_NODE=4 |
+-------------+----------------------+----------------+
4 rows in set (0.01 sec)

(詳しくは 項21.21. 「INFORMATION_SCHEMA FILES テーブル」 を参照してください。)

MySQL 5.1.6 では ALTER LOGFILE GROUP が追加されました。MySQL 5.1 では MySQL クラスタのディスク データ ストレージと一緒の時のみ利用する事ができます。詳しくは 項14.11. 「MySQL Cluster ディスク データ ストレージ」 を参照してください。

12.1.4. ALTER TABLESPACE 構文

ALTER TABLESPACE tablespace
    ADD DATAFILE 'file'
    INITIAL_SIZE [=] size
    ENGINE [=] engine

ALTER TABLESPACE tablespace
    DROP DATAFILE 'file'
    ENGINE [=] engine

このステートメントは新しいデータ ファイルを追加する時かテーブルスペースからデータ ファイルをドロップする時に利用する事ができます。

ADD DATAFILE 異形では、size がバイトで計算され、INITIAL_SIZE 構文を利用して初期のサイズを指定する事が要求されます。my.cnf で利用されている物と同様、大きさによって一文字の省略形を持つ整数値に従う事もできます。通常これは M (メガ バイト) か G (ギガ バイト)のどちらかの文字です。

一度データ ファイルが作成されると、そのサイズは変更できませんが、追加の ALTER TABLESPACE ... ADD DATAFILE ステートメントを利用する事によりテーブルスペースにより多くのデータ ファイルを追加する事ができます。

DROP DATAFILEALTER TABLESPACE と共に利用する事で、テーブルスペースから 'file' をドロップする事ができます。このファイルは CREATE TABLESPACEALTER TABLESPACE を利用してテーブルスペースに既に追加されていなければいけません。そうでなければエラーが発生します。

ALTER TABLESPACE ... ADD DATAFILEALTER TABLESPACE ... DROP DATAFILE の2つは、テーブルスペースに利用されるストレージ エンジンを指定する ENGINE 条項を必要とします。MySQL 5.1では、engine に受け入れられる値は NDBNDBCLUSTER だけです。

ALTER TABLESPACE ... ADD DATAFILEENGINE = NDB と共に利用された時、データ ファイルがそれぞれのクラスタ データ ノード上に作成されます。INFORMATION_SCHEMA.FILES テーブルに問い合わせする事によってデータ ファイルが作成され、それらの情報を得た事を証明する事ができます。例えば、次のクエリは newts 名付けられたテーブルスペースに属する全てのデータ ファイルを表していす。

mysql> SELECT LOGFILE_GROUP_NAME, FILE_NAME, EXTRA 
    -> FROM INFORMATION_SCHEMA.FILES
    -> WHERE TABLESPACE_NAME = 'newts' AND FILE_TYPE = 'DATAFILE';
+--------------------+--------------+----------------+
| LOGFILE_GROUP_NAME | FILE_NAME    | EXTRA          |
+--------------------+--------------+----------------+
| lg_3               | newdata.dat  | CLUSTER_NODE=3 |
| lg_3               | newdata.dat  | CLUSTER_NODE=4 |
| lg_3               | newdata2.dat | CLUSTER_NODE=3 |
| lg_3               | newdata2.dat | CLUSTER_NODE=4 |
+--------------------+--------------+----------------+
2 rows in set (0.03 sec)

詳しくはこちらをを参照してください。項21.21. 「INFORMATION_SCHEMA FILES テーブル」

MySQL 5.1.6 では ALTER TABLESPACE が追加されました。MySQL 5.1 では MySQL クラスタの ディスク データ ストレージと一緒の時のみ利用する事ができます。詳しくは 項14.11. 「MySQL Cluster ディスク データ ストレージ」 を参照してください。

12.1.5. ALTER SERVER 構文

ALTER SERVER  server_name
OPTIONS (option ...)

server_name のサーバ情報を変更し、CREATE SERVER コマンドごとの指定オプションを調整します。詳しくは 項12.1.11. 「CREATE SERVER 構文」 を参照してください。mysql.servers テーブル内の対応するフィールドは適宜更新されます。

例えば、USER オプションを更新する為には:

ALTER SERVER s OPTIONS (USER 'sally');

ALTER SERVER を利用する為に特別な権限は必要ありません。

ALTER SERVER は自動コミットを引き起こしません。

12.1.6. CREATE DATABASE 構文

CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
    [create_specification [create_specification] ...]

create_specification:
    [DEFAULT] CHARACTER SET charset_name
  | [DEFAULT] COLLATE collation_name

CREATE DATABASE は、与えられた名前でデータベースを作成します。このステートメントを利用する為には、データベースに CREATE 権限が必要です。CREATE SCHEMACREATE DATABASE の同義語です。

もしデータベースが存在し、IF NOT EXISTS を指定しなかった場合、エラーが発生します。

create_specification オプションはデータベースの特徴を指定します。データベースの特徴は、データベース ディレクトリの db.opt ファイルに格納されています。CHARACTER SET 条項はデフォルト データベースの文字セットを指定します。COLLATE 条項はデフォルト データベースの照合を指定します。章?9. キャラクタセットサポートは文字セットと照合名を検討します。

MySQL 内のデータベースは、その中のテーブルに対応するディレクトリとして実行されます。最初にデータベースが作成された時にはその中にはテーブルが無いので、CREATE DATABASE ステートメントが、MySQL データディレクトリ下にディレクトリと db.opt ファイルだけを作成します。項8.2. 「識別子」 に許可されたデータベース名のルールが紹介されています。もしデータベース名が特別な文字を含んでいる場合、その名前は項8.2.3. 「ファイル名への識別子のマッピング」に表されているようにそれらの文字が暗号化された形を含んだ物になります。

もしデータ ディレクトリ下にディレクトリを手動で作成したら(例えば mkdirを利用して)、サーバはそれをデータベース ディレクトリとみなし、SHOW DATABASES のアウトプット内に現れます。

データベースを作成する為に mysqladmin プログラムを利用する事もできます。詳しくは 項7.9. 「mysqladmin ? MySQL サーバの管理を行うクライアント」 を参照してください。

12.1.7. CREATE INDEX 構文

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
    [index_type]
    ON tbl_name (index_col_name,...)
    [index_option ...]

index_col_name:
    col_name [(length)] [ASC | DESC]

index_type:
    USING {BTREE | HASH}

index_option:
    KEY_BLOCK_SIZE value
  | index_type
  | WITH PARSER parser_name

CREATE INDEX は、インデックスを作成する為に ALTER TABLE ステートメントにマップされています。詳しくは 項12.1.2. 「ALTER TABLE 構文」 を参照してください。インデックスに関する更なる情報については、 項6.4.5. 「MySQLにおけるインデックスの使用」 を参照してください。

通常、テーブルが CREATE TABLE で作成される時にテーブル上に全てのインデックスを作成します。詳しくは 項12.1.8. 「CREATE TABLE 構文」 を参照してください。CREATE INDEX で既存テーブルにインデックスを追加する事ができます。

(col1,col2,...) のカラム リストは複合カラム インデックスを作成します。インデックス値は与えられたカラムの値を結合する事によって形作られます。

CHARVARCHARBINARY、そして VARBINARY カラムには、インデックス プリフィックス長を指定する為に col_name(length) 構文を利用して、カラム値の最初に部分だけを利用するインデックスを作成する事ができます。BLOBTEXT カラムもまたインデックスする事ができますが、プリフィックス長を与える 必要があります。。プリフィックス長は非バイナリ文字列タイプには文字で指定され、バイナリ文字列タイプにはバイトで指定されます。これは、インデックス エントリはCHARVARCHAR、そして TEXT カラムのそれぞれのカラム値の最初の length 文字で、そして BINARYVARBINARY、そして BLOB カラムのそれぞれのカラム値の最初の length バイトで成り立っているという事です。

ここに表示されているステートメントは、 name カラムの最初の10文字を利用してインデックスを作成します。

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

もしカラム内の名前の最初の10文字が違っていれば、このインデックスは name カラム全体から作成されたインデックスよりも遅くは無いはずです。また、部分的なカラムをインデックスに利用する事でインデックス ファイルを小さくする事ができるので、ディスクのスペースを節約し、 INSERT 操作を早くする事ができます。

プリフィックスは最高で1000バイトの長さまで可能です。(InnoDB テーブルは767バイト)非バイナリ データ タイプ(CHARVARCHARTEXT)では CREATE INDEX ステートメントのプリフィックス長は文字数で解釈される一方、プリフィックス リミットはバイトで計算されるという事を覚えておいて下さい。マルチバイトの文字セットを利用するカラムのプリフィックス長を指定する時にはこれを考慮に入れておいて下さい。

UNIQUE インデックスは、インデックス内の全ての値は明確でなければいけないというような制限を作成します。既存行とマッチするキー値の新しい行を追加しようとするとエラーが発生します。全てのエンジンに対して、UNIQUE インデックスは NULL を含む事ができるカラムの複数 NULL 値を許容します。

FULLTEXT インデックスは MyISAM テーブルにだけサポートされており、CHARVARCHAR、そして TEXT カラムだけを含む事ができます。インデックスする作業は必ずカラム全体に対して行われますので、部分的インデックスはサポートされておらず、プリフィックス長を指定しても無視されます。操作に関しての詳細は 項11.7. 「全文検索関数」 を参照してください。

SPATIAL インデックスは MyISAM テーブルに対してだけサポートされており、 NOT NULL として定義された空間カラムだけを含む事ができます。章?16. Spatial Extensionsで空間データタイプについて説明されています。

MySQL 5.1 内では

  • もし MyISAMInnoDB、または MEMORY ストレージエンジンを利用していれば、その時だけNULL 値を持つ事ができるカラム上にインデックスを追加する事ができます。

  • もし MyISAMInnoDB ストレージエンジンを利用していれば、その時だけBLOBTEXTカラム上にインデックスを追加する事ができます。

index_col_name 仕様は ASCDESC で終わる事ができます。これらのキーワードは昇順や降順インデックス値ストレージを指定する為の将来の拡張子として許容されます。現在は、それらは解析されますが無視されます。インデックス値は毎回昇順で格納されます。

インデックス カラム リストに続き、インデックス オプションが与えられます。index_option 値は次のうちのどれかになり得ます。

  • KEY_BLOCK_SIZE value

    このオプションはインデックス キー ブロックに利用するサイズについてストレージ エンジンにヒントを提供します。このエンジンは必要に応じて値を変更する事が可能です。0という値は、デフォルト値を利用しなければいけないという事を表しています。KEY_BLOCK_SIZE は MySQL 5.1.10 で追加されました。

  • index_type

    いくつかのストレージ エンジンでは、インデックスを作成する時にタイプを指定する事ができます。別々のストレージ エンジンにサポートされた許容インデックス タイプは次のテーブルに表されています。複数インデックス タイプがリストされている部分に関しては、インデックス指定子が指示されていなければ最初の物がデフォルトです。

    ストレージ エンジン許容インデックス タイプ
    MyISAMBTREE
    InnoDBBTREE
    MEMORY/HEAPHASHBTREE

    もし規定のストレージ エンジンに対して正当ではないインデックス タイプを指定し、しかしクエリに影響を与えずにそのエンジンが利用できる別の有効なインデックス タイプが存在すれば、エンジンはその有効なタイプを利用します。

    例:

    CREATE TABLE lookup (id INT) ENGINE = MEMORY;
    CREATE INDEX id_index USING BTREE ON lookup (id);
    

    TYPE type_nameUSING type_name の同義語として解釈されます。しかし、USING が好ましい形です。

    注意:MySQL 5.1.10 以前のバージョンでは、オプションは ON tbl_name 条項の前にだけ指示する事ができました。このオプションのこの位置での利用は 5.1.10 以降は廃止予定で、MySQL 5.3 以降はサポートされなくなります。

  • WITH PARSER parser_name

    このオプションは FULLTEXT インデックスとだけ利用する事ができます。もしフル テキスト インデックスと検索操作が特別対応を必要とするなら、これはインデックスを利用してパーサー プラグインと提携します。プラグインの作成に関しての詳細は項25.2. 「The MySQL Plugin Interface」 を参照してください。

12.1.8. CREATE TABLE 構文

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
    (create_definition,...)
    [table_option ...]
    [partition_options]

または:

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

または:

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
    { LIKE old_tbl_name | (LIKE old_tbl_name) }

create_definition:
    column_definition
  | [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...)
      [index_option ...]
  | {INDEX|KEY} [index_name] [index_type] (index_col_name,...)
      [index_option ...]
  | [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY]
      [index_name] [index_type] (index_col_name,...)
      [index_option ...]
  | {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (index_col_name,...)
      [index_option ...]
  | [CONSTRAINT [symbol]] FOREIGN KEY
      [index_name] (index_col_name,...) [reference_definition]
  | CHECK (expr)

column_definition:
    col_name data_type [NOT NULL | NULL] [DEFAULT default_value]
      [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]
      [COMMENT 'string'] [reference_definition]

data_type:
    BIT[(length)]
  | TINYINT[(length)] [UNSIGNED] [ZEROFILL]
  | SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
  | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
  | INT[(length)] [UNSIGNED] [ZEROFILL]
  | INTEGER[(length)] [UNSIGNED] [ZEROFILL]
  | BIGINT[(length)] [UNSIGNED] [ZEROFILL]
  | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
  | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
  | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
  | DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL]
  | NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL]
  | DATE
  | TIME
  | TIMESTAMP
  | DATETIME
  | YEAR
  | CHAR(length)
      [CHARACTER SET charset_name] [COLLATE collation_name]
  | VARCHAR(length)
      [CHARACTER SET charset_name] [COLLATE collation_name]
  | BINARY(length)
  | VARBINARY(length)
  | TINYBLOB
  | BLOB
  | MEDIUMBLOB
  | LONGBLOB
  | TINYTEXT [BINARY]
      [CHARACTER SET charset_name] [COLLATE collation_name]
  | TEXT [BINARY]
      [CHARACTER SET charset_name] [COLLATE collation_name]
  | MEDIUMTEXT [BINARY]
      [CHARACTER SET charset_name] [COLLATE collation_name]
  | LONGTEXT [BINARY]
      [CHARACTER SET charset_name] [COLLATE collation_name]
  | ENUM(value1,value2,value3,...)
      [CHARACTER SET charset_name] [COLLATE collation_name]
  | SET(value1,value2,value3,...)
      [CHARACTER SET charset_name] [COLLATE collation_name]
  | spatial_type

index_col_name:
    col_name [(length)] [ASC | DESC]

index_type:
    USING {BTREE | HASH}

index_option:
    KEY_BLOCK_SIZE value
  | index_type
  | WITH PARSER parser_name

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

reference_option:
    RESTRICT | CASCADE | SET NULL | NO ACTION

table_option:
    [TABLESPACE tablespace_name STORAGE DISK]
    ENGINE [=] engine_name
  | AUTO_INCREMENT [=] value
  | AVG_ROW_LENGTH [=] value
  | [DEFAULT] CHARACTER SET charset_name
  | CHECKSUM [=] {0 | 1}
  | COLLATE collation_name
  | COMMENT [=] 'string'
  | CONNECTION [=] 'connect_string'
  | DATA DIRECTORY [=] 'absolute path to directory'
  | DELAY_KEY_WRITE [=] {0 | 1}
  | INDEX DIRECTORY [=] 'absolute path to directory'
  | INSERT_METHOD [=] { NO | FIRST | LAST }
  | KEY_BLOCK_SIZE [=] value
  | MAX_ROWS [=] value
  | MIN_ROWS [=] value
  | PACK_KEYS [=] {0 | 1 | DEFAULT}
  | PASSWORD [=] 'string'
  | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}
  | UNION [=] (tbl_name[,tbl_name]...)

partition_options:
    PARTITION BY
          [LINEAR] HASH(expr)
        | [LINEAR] KEY(column_list)
        | RANGE(expr)
        | LIST(expr)
    [PARTITIONS num]
    [SUBPARTITION BY
          [LINEAR] HASH(expr)
        | [LINEAR] KEY(column_list)
      [SUBPARTITIONS num]
    ]
    [(partition_definition [, partition_definition] ...)]

partition_definition:
    PARTITION partition_name
        [VALUES {LESS THAN (expr) | MAXVALUE | IN (value_list)}]
        [[STORAGE] ENGINE [=] engine_name]
        [COMMENT [=] 'comment_text' ]
        [DATA DIRECTORY [=] 'data_dir']
        [INDEX DIRECTORY [=] 'index_dir']
        [MAX_ROWS [=] max_number_of_rows]
        [MIN_ROWS [=] min_number_of_rows]
        [TABLESPACE [=] (tablespace_name)]
        [NODEGROUP [=] node_group_id]
        [(subpartition_definition [, subpartition_definition] ...)]

subpartition_definition:
    SUBPARTITION logical_name
        [[STORAGE] ENGINE [=] engine_name]
        [COMMENT [=] 'comment_text' ]
        [DATA DIRECTORY [=] 'data_dir']
        [INDEX DIRECTORY [=] 'index_dir']
        [MAX_ROWS [=] max_number_of_rows]
        [MIN_ROWS [=] min_number_of_rows]
        [TABLESPACE [=] (tablespace_name)]
        [NODEGROUP [=] node_group_id]

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

CREATE TABLE は、与えられた名前でデータ ベースを作成します。テーブルに対して CREATE 権限を持つ必要があります。

項8.2. 「識別子」 に許容テーブル名のルールが紹介されています。デフォルトによって、デフォルト データベースの中にテーブルが作成されます。テーブルが既に存在したり、デフォルト データベースが無かったり、データベースが存在しなかったりするとエラーが発生します。

指定データベース内にテーブルを作成するには、テーブル名を db_name.tbl_name と指定する事ができます。この作業は、デフォルト データベースが無くても、あると仮定して行われます。もし引用識別子を利用するなら、データベースとテーブル名は別々に引用してください。例えば、`mydb.mytbl` ではなく `mydb`.`mytbl` と書いてください。

テーブルを作成する時、TEMPORARY キーワードを利用する事ができます。TEMPORARY テーブルは現在の接続でのみ現れ、接続が終了すると自動的にドロップされます。これは、2つの異なる接続同士、または、既存の同名の非TEMPORARY テーブルとお互いに対立する事無く、同じテンポラリ テーブル名を利用する事ができるという意味になります。(テンポラリ テーブルがドロップされるまで、既存テーブルは隠されています。)テンポラリ テーブルを作成する為には CREATE TEMPORARY TABLES 特権を持つ必要があります。

注意:CREATE TABLE は、もし TEMPORARY キーワードを利用すると自動的に現在のアクティブなトランザクションを行いません。

もしテーブルが存在すると IF NOT EXISTS キーワードはエラーが起こるのを防ぎます。しかし、CREATE TABLE ステートメントに指示されたテーブルと既存テーブルが同一の構造である事の照合は行われません。注意:もし IF NOT EXISTSCREATE TABLE ... SELECT ステートメント内で利用すると、SELECT 部分によって選択された全ての行はテーブルが既に存在するかどうかに関わらず挿入されます。

MySQL はそれぞれのテーブルをデータベース ディレクトリ内に .frm テーブル フォーマットで表します。テーブルのストレージ エンジンは別のファイルを作成する事もあります。MyISAM テーブルの場合、ストレージ エンジンはデータとインデックス ファイルを作成します。従って、各 MyISAM テーブル tbl_name は3つのディスク ファイルを持ちます。

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

章?13. ストレージエンジンとテーブルタイプ でテーブルを表す為にそれぞれのストレージ エンジンがどのファイルを作成するのか説明されています。もしテーブル名が特別な文字を含んでいる場合、そのテーブル ファイルの名前は項8.2.3. 「ファイル名への識別子のマッピング」に表されているようにそれらの文字が暗号化された形を含んだ物になります。

data_type は、データ タイプはカラム定義だという事を意味します。 spatial_type は空間データ タイプを意味します。表示されるデータ タイプ構文はただの見本です。各タイプの性質についての情報だけでなく、カラム データ タイプを指定する事ができる構文の完全な説明については、章?10. データタイプ章?16. Spatial Extensions を参照してください。

いくつかの属性は全てのデータ タイプには対応しません。AUTO_INCREMENT は整数タイプにのみ対応します。DEFAULTBLOBTEXT タイプには対応しません。

  • もし NULLNOT NULL のどちらも指定されなければ、そのカラムは NULL が指定されたという形で扱われます。

  • 整数カラムは追加属性 AUTO_INCREMENT を持つ事ができます。インデックスされた AUTO_INCREMENT カラムに NULL (推奨) か 0 の値を挿入すると、カラムは次のシーケンス値に設定されます。通常これは 、value が現在テーブルの中にあるカラムの最大値である、value+1 です。AUTO_INCREMENT シーケンスは 1 で始まります。

    行の挿入後に AUTO_INCREMENT 値を検索するには、 LAST_INSERT_ID() SQL 機能か mysql_insert_id() C API 関数を利用してください。項11.10.3. 「情報関数」項23.2.3.37. 「mysql_insert_id() を参照して下さい。

    もし NO_AUTO_VALUE_ON_ZERO SQL モードが有効であれば、新しいシーケンス値を発生させずに 0AUTO_INCREMENT カラムに 0 として格納する事ができます。詳しくは 項4.2.6. 「SQL モード」 を参照してください。

    注意:各テーブルに AUTO_INCREMENT カラムは1つだけ存在する事ができ、それはインデックスされる必要があり、DEFAULT 値を持つ事はできません。AUTO_INCREMENT カラムは正数のみを含んでいる時だけ正しく機能します。負数を挿入すると、とても大きな正数を挿入したと解釈されます。これは、数字が正数から負数に 「ラップ」 される時の精度の問題を避ける為に、また 0 を含む AUTO_INCREMENT カラムを誤って採用してしまわない為に行われます。

    MyISAM テーブルには、複合カラム キー内の AUTO_INCREMENT セカンダリ カラムを指定する事ができます。詳しくは Using AUTO_INCREMENT を参照してください。

    MySQL 互換性がいくつかの ODBC アプリケーション持つ為に、次のクエリを利用して、最後に挿入された行に AUTO_INCREMENT 値を見つける事ができます。

    SELECT * FROM tbl_name WHERE auto_col IS NULL
    

    InnoDBAUTO_INCREMENT の更なる情報に関しては、項13.5.6.3. 「AUTO_INCREMENT カラムが InnoDB 内でどのように機能するか」 を参照してください。

  • SERIAL 属性は BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE のエイリアスです。

  • 文字データタイプ(CHARVARCHARTEXT)は、文字セットとカラムの照合を指定する為にCHARACTER SETCOLLATE 属性を含む事ができます。詳細に関しては 章?9. キャラクタセットサポート を参照して下さい。CHARSETCHARACTER SET の同義語です。例:

    CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);
    

    MySQL 5.1 は、文字の中の文字カラム定義の長さ仕様を解明します。(MySQL 4.1 以前のバージョンでは、それらはバイトで解釈されます。)BINARYVARBINARY の長さはバイトで表されています。

  • DEFAULT 条項はカラムのデフォルト値を指定します。例外がひとつあります。デフォルト値は一定でなければいけませんので、それは関数や式にはなり得ません。これは例えば、日付カラムの値に NOW()CURRENT_DATE のような関数の値をデフォルトとして設定する事はできないという意味です。例外として、TIMESTAMP カラムのデフォルトとして CURRENT_TIMESTAMP を指定する事ができます。詳しくは 項10.3.1.1. 「TIMESTAMP MySQL 4.1での性質」 を参照してください。

    もしカラム定義が明示的な DEFAULT 値を含まない場合、MySQL はデフォルト値を 項10.1.4. 「データタイプデフォルト値」 のように規定します。

    BLOBTEXT カラムはデフォルト値として割り当てる事ができません。

  • カラムのコメントは、255文字の長さまでで COMMENT オプションで指定できます。コメントは SHOW CREATE TABLESHOW FULL COLUMNS ステートメントによって表示されます。

  • KEY は通常 INDEX の同義語です。キー属性 PRIMARY KEY はまた、カラム定義の中では単に KEY として指定できます。これは、互換性の為に他のデータベースと共に利用されます。

  • UNIQUE インデックスは、インデックス内の全ての値は明確でなければいけないというような制限を作成します。既存行とマッチするキー値の新しい行を追加しようとするとエラーが発生します。全てのエンジンに対して、UNIQUE インデックスは NULL を含む事ができるカラムの複数 NULL 値を許容します。

  • PRIMARY KEY は、全てのキー カラムが NOT NULL として定義されなければいけないユニーク インデックスです。もしそれらが NOT NULL として明示的に宣言されなければ、MySQL はそれらを暗示的に(そして静かに)宣言します。1つのテーブルは1つの PRIMARY KEY しか持つ事ができません。もし PRIMARY KEY が無いのにアプリケーションがテーブル内で PRIMARY KEY を要求したら、MySQL は PRIMARY KEY として NULL カラムを持たない最初の UNIQUE インデックスを返します。

    InnoDB テーブル内で長い PRIMARY KEY を持つとスペースを無駄に利用します。(詳しくは 項13.5.13. 「InnoDB テーブルとインデックス構造」 を参照してください。)

  • 作成されたテーブル内では、PRIMARY KEY が最初に置かれ、次に UNIQUE インデックスが続き、そして次に非ユニーク インデックスが続きます。このおかげで MySQL オプチマイザがどのインデックスを優先して利用するのか、また複製 UNIQUE キーをより早く検索する為に役立ちます。

  • PRIMARY KEY は複合カラム インデックスになり得ます。しかし、カラム仕様内で PRIMARY KEY キー属性を利用して複合カラム インデックスを作成する事はできません。それをしても、単一カラムが最初に来るという印が付けられるだけです。別々の PRIMARY KEY(index_col_name, ...) 条項を利用しなければいけません。

  • もし PRIMARY KEYUNIQUE インデックスが整数タイプを持つ1つだけののカラムで構成されていたら、そのカラムを SELECT ステートメントの中で _rowid として参照する事もできます。

  • MySQL 内では、PRIMARY KEY の名前は PRIMARY です。他のインデックスに関しては、もし名前を割り当てなければ、それを固有の物にする為に任意のサフィックス(_2_3...)を利用して、最初にインデックスされたカラムと同じ名前に指定されます。SHOW INDEX FROM tbl_name を利用してテーブルのインデックス名を調べる事ができます。詳しくは 項12.5.4.17. 「SHOW INDEX 構文」 を参照してください。

  • いくつかのストレージ エンジンでは、インデックスを作成する時にタイプを指定する事ができます。index_type 指定子の構文は USING type_name です。

    例:

    CREATE TABLE lookup
      (id INT, INDEX USING BTREE (id))
      ENGINE = MEMORY;
    

    MySQL 5.1.10 以前では、USING はインデックス カラム リストの前だけに与える事ができました。5.1.10 以降のバージョンでの望ましい位置は、カラム リストの後ろです。MySQL 5.3 以降は、カラム リストの前でのオプションの使用は見られません。

    index_option 値はインデックスの追加オプションを指定します。USING はそのようなオプションの1つです。許容 index_option 値の詳細に関しては 項12.1.7. 「CREATE INDEX 構文」 を参照してください。

    インデックスに関する更なる情報については、項6.4.5. 「MySQLにおけるインデックスの使用」 を参照してください。

  • MySQL 5.1 では、MyISAMInnoDB、そして MEMORY ストレージ エンジンだけが NULL 値を持つ事ができるカラムをインデックス上でサポートしています。それ以外の場合、インデックスされたカラムを NOT NULL として宣言しなければエラーが発生します。

  • CHARVARCHARBINARY、そして VARBINARY カラムには、インデックス プリフィックス長を指定する為に col_name(length) 構文を利用して、カラム値の最初に部分だけを利用するインデックスを作成する事ができます。BLOBTEXT カラムもまたインデックスする事ができますが、プリフィックス長を与える 必要があります。。プリフィックス長は非バイナリ文字列タイプには文字で指定され、バイナリ文字列タイプにはバイトで指定されます。これは、インデックス エントリはCHARVARCHAR、そして TEXT カラムのそれぞれのカラム値の最初の length 文字で、そして BINARYVARBINARY、そして BLOB カラムのそれぞれのカラム値の最初の length バイトで成り立っているという事です。このようにカラム値のプリフィックスだけをインデックスする事で、インデックス ファイルをとても小さくする事ができます。詳しくは 項6.4.3. 「カラムインデックス」 を参照してください。

    MyISAMInnoDB ストレージ エンジンだけが BLOBTEXT カラムのインデックスをサポートします。例:

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

    プリフィックスは最高で1000バイトの長さまで可能です。(InnoDB テーブルは767バイト)非バイナリ データ タイプ (CHARVARCHARTEXT)では CREATE TABLE ステートメントのプリフィックス長は文字数で解釈される一方、プリフィックス リミットはバイトで計算されるという事を覚えておいて下さい。マルチバイトの文字セットを利用するカラムのプリフィックス長を指定する時にはこれを考慮に入れておいて下さい。

  • index_col_name 仕様は ASCDESC で終わる事ができます。これらのキーワードは昇順や降順インデックス値ストレージを指定する為の将来の拡張子として許容されます。現在は、それらは解析されますが無視されます。インデックス値は毎回昇順で格納されます。

  • SELECT内のTEXTBLOB カラムに対して ORDER BYGROUP BY を利用する時、サーバは max_sort_length システム変数によって指示された初期バイト数だけを利用して値をソートします。詳しくは 項10.4.3. 「BLOBTEXT タイプ」 を参照してください。

  • フル テキスト検索に利用される特別な FULLTEXT インデックスを作成する事ができます。MyISAM ストレージ エンジンだけが FULLTEXT インデックスをサポートします。それらは CHARVARCHAR、そして TEXT カラムからのみ作成する事ができます。インデックスする作業は必ずカラム全体に対して行われますので、部分的インデックスはサポートされておらず、プリフィックス長を指定しても無視されます。操作に関しての詳細は 項11.7. 「全文検索関数」 を参照してください。WITH PARSER 条項は、もしフル テキスト インデックスと検索操作が特別対応を必要とするなら、インデックスと共にパーサー プラグインと提携する為に index_option 値として指定する事ができます。この条項は FULLTEXT インデックスだけに対して正当です。プラグインの作成に関しての詳細は項25.2. 「The MySQL Plugin Interface」 を参照してください。

  • 空間データ タイプ上に SPATIAL インデックスを作成する事ができます。空間タイプは MyISAM テーブルに対してだけサポートされており、インデックスされたカラムは NOT NULL として宣言されなければいけません。詳しくは 章?16. Spatial Extensions を参照してください。

  • InnoDB テーブルは外部キー制約のチェックをサポートします。詳しくは 項13.5. 「InnoDB ストレージ エンジン」 を参照してください。InnoDB 内の FOREIGN KEY 構文は、このセクションの最初でCREATE TABLE ステートメントの為に紹介された構文よりも制限的である事を覚えておいてください。参照テーブルのカラムは必ず明確に名前を付けられる必要があります。InnoDB は、外部キーへの ON DELETEON UPDATE 作用の両方をサポートします。正確な構文に関しては、項13.5.6.4. 「FOREIGN KEY 制約」 を参照してください。

    その他のストレージ エンジンに関しては、MySQL サーバは CREATE TABLE ステートメント内の FOREIGN KEYREFERENCES 構文を検索し無視します。CHECK 条項は、全てのストレージ エンジンに解析されますが、無視されます。詳しくは 項1.8.5.5. 「外部キー」 を参照してください。

  • MyISAM テーブルに対しては、各 NULL カラムは1ビット余分に利用し、一番近いバイト数に丸められます。バイトでの最大行長は次のように計算されます。

    row length = 1
                 + (sum of column lengths)
                 + (number of NULL columns + delete_flag + 7)/8
                 + (number of variable-length columns)
    

    delete_flag は静的行フォーマットのテーブルに対しては1です。静的テーブルは、行が削除されたかどうか指示するフラッグに対して行レコード内でビットを利用します。 delete_flag は、フラッグがダイナミック行ヘッダー内で格納される為、ダイナミック テーブルに対しては0です。

    これらの計算は、NULL カラムと NOT NULL カラムの格納サイズが同じである InnoDB テーブルには適応しません。

TABLESPACE ... STORAGE DISK テーブルオプションは NDB Cluster テーブルとのみ使用されます。これはテーブルをクラスタ ディスク データ テーブルスペースに割り当てます。tablespace_name と名づけられたテーブルスペースは CREATE TABLESPACE を利用してあらかじめ作成されている必要があります。このテーブルオプションは MySQL 5.1.6 で紹介されています。詳しくは項14.11. 「MySQL Cluster ディスク データ ストレージ」 を参照してください。

ENGINE テーブル オプションはテーブルにストレージ エンジンを指定します。

ENGINE テーブル オプションは、次のテーブルに表されているストレージ エンジン名を利用します。

ストレージ エンジン説明
ARCHIVEアーカイブ ストレージ エンジン詳しくは 項13.10. 「ARCHIVE ストレージエンジン」 を参照してください。
CSVカンマで区切られた値のフォーマットで行を格納するテーブル詳しくは 項13.11. 「CSV ストレージエンジン」 を参照してください。
EXAMPLE例エンジン詳しくは 項13.8. 「EXAMPLE ストレージエンジン」 を参照してください。
FEDERATEDリモート テーブルにアクセスするストレージ エンジン詳しくは 項13.9. 「FEDERATED ストレージエンジン」 を参照してください。
HEAPこれは MEMORY の同義語です。
ISAM (OBSOLETE)MySQL 5.1 では無効です。もし古いバージョンから MySQL 5.1 にアップグレードするなら、その作業の 前に 全ての既存 ISAM テーブルを MyISAM に変換しなければいけません。
InnoDB行ロックと外部キーを持つトランザクション セーフ テーブル詳しくは 項13.5. 「InnoDB ストレージ エンジン」 を参照してください。
MEMORYこのストレージ エンジンのデータはメモリの中だけに格納されます。詳しくは 項13.7. 「MEMORY (HEAP) ストレージエンジン」 を参照してください。
MERGE1つのテーブルとして利用される MyISAM テーブルの集まり。また、MRG_MyISAM としても知られています。詳しくは 項13.6. 「MERGE ストレージエンジン」 を参照してください。
MyISAMMySQL に利用されるデフォルト ストレージ エンジンであるバイナリ ポータブル ストレージ エンジン。詳しくは 項13.4. 「MyISAM ストレージエンジン」 を参照してください。
NDBCLUSTERクラスタ化された、耐障害性の、メモリ ベースのテーブル。また、NDB としても知られています。詳しくは 章?14. MySQL Cluster を参照してください。

もし適応しないストレージ エンジンが指定されると、MySQL は代わりにデフォルト エンジンを利用します。通常は MyISAM です。例えば、テーブル定義が ENGINE=INNODB オプションを含み、MySQL サーバが INNODB テーブルをサポートしなければ、そのテーブルは MyISAM テーブルとして作成されます。これは、トランザクショナル テーブルをマスタ上に持つが、スレーブ上に作成されたテーブルが非トランザクショナルである場合(スピードを速める為)の複製設定を可能にします。 MySQL 5.1 では、ストレージ エンジン仕様が支持されていなければ警告が表示されます。

注意:古い TYPE オプションは ENGINE と同義語です。MySQL 4.0 以降、TYPE は廃止されましたが、MySQL 5.1 (MySQL 5.1.7 となる予定)ではまだ後方互換性の為にサポートされています。MySQL 5.1.8 より、警告が表示されるようになりました。これはMySQL 5.2 では廃止される予定です。新しいアプリケーションの中では TYPE は利用するべきではありません、また、代わりに ENGINE を利用する為に、既存アプリケーションの変換を今すぐ始めるべきです。.(詳しくは 項C.1.9. 「Changes in release 5.1.8 (Not released)」 を参照してください。)

その他のテーブル オプションはテーブルの動作を最適化する為に利用されます。ほとんどの場合、それらのうちのどれも指定する必要はありません。これらのオプションは、指示されない限り全てのストレージ エンジンに適応します。与えられたストレージ エンジンに適応しないオプションは、受け入れられ、テーブル定義の一部として記憶されるでしょう。そのようなオプションは、後程もし異なるストレージ エンジンの利用の為にテーブルを変換する時 ALTER TABLE を利用すれば適応されます。

  • AUTO_INCREMENT

    テーブルの初期 AUTO_INCREMENT 値。MySQL 5.1 では、これは MyISAMMEMORY、そして InnoDB テーブルに対して機能します。これはまた、MySQL 5.1.6 以降も ARCHIVE テーブルに対しても機能します。 AUTO_INCREMENT テーブル オプションをサポートしないエンジンに最初の自動インクリメント値を設定する為に、テーブルを作成した後、求められる値よりの1少ない値の 「dummy」 行を挿入し、その後ダミー行を削除してください。

    CREATE TABLE ステートメント内の AUTO_INCREMENT テーブル オプションをサポートするエンジンには、AUTO_INCREMENT 値をリセットする為に ALTER TABLE tbl_name AUTO_INCREMENT = N を利用する事もできます。その値は、現在カラム内にある最大値よりも小さく設定する事はできません。

  • AVG_ROW_LENGTH

    テーブルの平均行長近似値です。可変サイズ行を持つ大きいテーブルに対してのみ、これを設定する必要があります。

    MyISAM テーブルを作成する時、MySQL はテーブルが最終的にどの程度の大きさになるのかを決める為に MAX_ROWSAVG_ROW_LENGTH オプションの製品を利用します。もしどちらのオプションも指定しなければ、テーブルの最大サイズはデフォルトで256 TB になります。(もし使用している OS がその大きさのファイルをサポートしていなければ、テーブル サイズはファイル サイズ制限に制約されます。)もし大きいファイルが必要無く、インデックスを小さく早くする為にポインタサイズを小さくしたければ、myisam_data_pointer_size システム変数を設定する事でデフォルトのポインタ サイズを小さくする事ができます。(詳しくは 項4.2.3. 「システム変数」 をご確認ください。)もし全てのテーブルをデフォルトの制限よりも大きくする事を希望し、必要以上にテーブルが遅く、大きくなっても良いのであれば、この変数を設定する事でデフォルトのポインタサイズを増やす事ができます。

  • [DEFAULT] CHARACTER SET

    テーブルにデフォルト文字セットを指定します。CHARSETCHARACTER SET の同義語です。

  • CHECKSUM

    MySQL に全ての行のライブ チェックサムを維持させたければこれを1に設定してください。(これはテーブルが変更される度に MySQL が自動的に更新するチェックサムです。)これはテーブルの更新スピードを少し遅くしますが、壊れたテーブルを見つけるのが早くなります。CHECKSUM TABLE ステートメントはチェックサムをリポートします。(MyISAM のみです。)

  • COLLATE

    テーブルにデフォルト照合を指定します。

  • COMMENT

    最高60文字のテーブルに対するコメントです。

  • CONNECTION

    FEDERATED テーブルの接続文字列です。(注意:MySQL の古いバージョンは COMMENT オプションを接続文字列に利用していました。)

  • DATA DIRECTORYINDEX DIRECTORY

    DATA DIRECTORY='directory'INDEX DIRECTORY='directory' を利用する事で、MyISAM ストレージ エンジンがテーブルのデータ ファイルとインデックス ファイルをどこに置く必要があるのかを指定する事ができます。ディレクトリは、相対パス名ではなくフルパス名でなければいけません。

    これらのオプションは --skip-symbolic-links オプションを利用していない時だけ機能します。OS にはまた、有効なスレッド セーフな realpath() コールがなければいけません。詳細については、項6.6.1.2. 「Unix 上のテーブルに対するシンボリックリンクの使用」 をご参照ください。

  • DELAY_KEY_WRITE

    キー更新をテーブルが閉じられる時まで遅らせたければこれを1に設定してください。項4.2.3. 「システム変数」 内の delay_key_write システム変数についての説明を参照してください。(MyISAM のみです。)

  • INSERT_METHOD

    もしデータを MERGE テーブルに挿入したければ、その行が挿入されるべきテーブルのINSERT_METHOD を利用して指定する必要があります。INSERT_METHODMERGE テーブルにのみ有効なオプションです。最初か最後のテーブルに挿入する為には FIRSTLAST 値を、また挿入を防ぐ為には NO 値を利用してください。詳しくは 項13.6. 「MERGE ストレージエンジン」 を参照してください。

  • KEY_BLOCK_SIZE

    このオプションはインデックス キー ブロックに利用するサイズについてストレージ エンジンにヒントを提供します。このエンジンは必要に応じて値を変更する事が可能です。0という値は、デフォルト値を利用しなければいけないという事を表しています。テーブル値を無効にする為に、個々のインデックス定義はそれ自身の KEY_BLOCK_SIZE 値を指定する事ができます。KEY_BLOCK_SIZE は MySQL 5.1.10 で追加されました。

  • MAX_ROWS

    テーブル内に格納する予定の最大行数。これは、厳しい制限というよりは、ストレージ エンジンに対して、テーブルが少なくてもこの程度の行数を格納できる必要があるという事を表すヒントのような物です。

  • MIN_ROWS

    テーブル内に格納する予定の最小行数

  • PACK_KEYS

    PACK_KEYSMyISAM テーブルとだけ効果を発揮します。小さいインデックスを持ちたければ、このオプションを1に設定してください。これは通常更新スピードを遅くし、読み込みを早くします。オプションを0に設定すると、全てのキー パッキングが無効になります。これを DEFAULT に設定すると、ストレージ エンジンには長い CHARVARCHAR カラムだけをパックするように指令が出ます。

    もし PACK_KEYS を利用しなければ、デフォルトでは文字列をパックしますが、数字はパックしません。もし PACK_KEYS=1 を利用すると、数字もパックされます。

    バイナリ数値キーをパックする時、MySQL はプリフィックス圧縮を利用します。

    • 前のキーのいくつのバイト分が次のキーと同じであるかを示す為に、全てのキーは1バイト分多く必要とします。

    • 行のポインタは、圧縮を強化する為に、キーの直後に高バイト順で直接格納されます。

    これは、もし2つの連続した行上に複数の同等なキーを持っていたら、全ての後続する 「同じ」 キーは通常2バイトしか利用しないという事を意味します。(行のポインタを含む)これを、後続キーが storage_size_for_key + pointer_size を取る通常のケースと比べてみてください。(ポインタサイズは通常4)反対に、同じ数値を多く持つ場合のみ、プリフィックス圧縮の恩恵を多いに受ける事ができます。もし全てのキーが全く異なり、NULL 値を持つ事ができるキーでなければ、1つのキーに対してもう1バイト多く利用する事になります。(この場合、もしキーが NULL であれば、パックされたキー長はマークする為に利用された物と同じバイト数で格納されます。)

  • PASSWORD

    パスワードを持つ .frm ファイルを暗号化します。このオプションは、スタンダード MySQL バージョン内では何も行いません。

  • RAID_TYPE

    RAID サポートは MySQL 5.0 以降は削除されました。RAID の情報に関しては、http://dev.mysql.com/doc/refman/4.1/en/create-table.html を参照してください。

  • ROW_FORMAT

    行がどのように格納されるべきかを定義します。MyISAM テーブルに対しては、静的、または可変長行フォーマットのオプション値は FIXEDDYNAMIC になり得ます。 myisampack はタイプを COMPRESSED に設定します。詳しくは 項13.4.3. 「MyISAM テーブルストレージフォーマット」 を参照してください。

    InnoDB テーブルに対しては、行はデフォルトでコンパクト フォーマットに格納されます。(ROW_FORMAT=COMPACT)ROW_FORMAT=REDUNDANT を指定する事により、MySQL の古いバージョンで利用される非コンパクト フォーマットをリクエストする事もできます。

  • UNION

    UNION は、同一の MyISAM テーブルの集まりを1つの物としてアクセスしたい時に利用する事ができます。これは MERGE テーブルとのみ機能します。詳しくは 項13.6. 「MERGE ストレージエンジン」 を参照してください。

    MERGE テーブルにマップするテーブルに、SELECTUPDATE、そして DELETE 権限を持たなければいけません。(注意:以前は、全てのテーブルは、MERGE テーブルそのものと同じデータベース内にある必要がありました。この制限はもう適応されません。)

partition_optionsCREATE TABLE を利用して作成されたテーブルの領域確保をコントロールする為に利用できます。重要:このセクションの冒頭で紹介された partition_options の構文内に表された全てのオプションが、全ての領域確保タイプに有効であるわけではありません。テーブル作成と MySQL 領域確保に関係する他のステートメントの追加例だけでなく、MySQL 内での領域確保の機能と使用に関しての完全な情報については、各タイプの情報仕様の為の個別タイプをリストした物、そして 章?15. パーティショニング を見てください。

partition_options は、もし利用されるなら最小の PARTITION BY 条項を含む必要があります。この条項はパーティションを決めるのに利用される関数を含んでいます。その関数は、num が分割数の時、1から num の整数値を返します。(1つのテーブルが含むユーザー定義パーティションの最高数は1024です。 このセクション ? の後半で紹介される ?サブ パーティションはこの最高数に含まれています。)MySQL 5.1 でこの機能に対して有効な物は次のリストに表されています。

  • HASH(expr):行を置く為のキーを作成する為に1つ、または複数のカラムをハッシュします。expr は1つ、または複数のテーブルカラムを利用する式です。これは、単一整数値を生む正当な MySQL 式(MySQL 関数を含む)であればどれでもよいです。例えば、これらは全て PARTITION BY HASH を利用した有効な CREATE TABLE ステートメントです。

    CREATE TABLE t1 (col1 INT, col2 CHAR(5))
        PARTITION BY HASH(col1);
    
    CREATE TABLE t1 (col1 INT, col2 CHAR(5))
        PARTITION BY HASH( ORD(col2) );
    
    CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME)
        PARTITION BY HASH ( YEAR(col3) );
    

    PARTITION BY HASH と、VALUES LESS THANVALUES IN 条項は一緒に利用しません。

    PARTITION BY HASH はパーティション数によって分割された (モジュール)expr の残りを利用します。追加情報については 項15.2.3. 「HASH 分割」 を参照してください。

    LINEAR キーワードは異なるアルゴリズムを若干必要とします。lこの場合、行が格納されるパーティション数は、1つ、または複数の論理的な AND 操作の結果計算されます。線形ハッシングについての説明と例に関しては、 項15.2.3.1. 「LINEAR HASH 分割」 を参照してください。

  • KEY(column_list):MySQL がハッシング機能を均等なデータ分布を保障する為に提供するという事以外、これは HASH と似ています。column_list 引数は単にテーブル カラムのリストです。この例は、キーによって4つのパーティションに分割された単純なテーブルを表しています。

    CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE)
        PARTITION BY KEY(col3)
        PARTITIONS 4;
    

    キーによって分割されたテーブルには、LINEAR キーワードを利用した線形領域確保を採用する事ができます。これは HASH によって分割されたテーブルと同じ効果を持ちます。これは、分割数はモジュールではなく & 演算子を利用して求められるという事を意味します。(詳細に関しては 項15.2.3.1. 「LINEAR HASH 分割」、と 項15.2.4. 「KEY 分割」 を参照してください。)この例は、5つのパーティション間でデータを分布する為にキーによる線形領域確保を利用しています。

    CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE)
        PARTITION BY LINEAR KEY(col3)
        PARTITIONS 5;
    

    PARTITION BY KEY と、VALUES LESS THANVALUES IN 条項は一緒に利用しません。

  • RANGE:この場合、exprVALUES LESS THAN 演算子のセットを利用して値の範囲を表します。範囲の領域確保を利用する時、VALUES LESS THAN を利用して最低1つのパーティションを定義する必要があります。VALUES IN を範囲の領域確保に利用する事はできません。

    VALUES LESS THAN は直定数値、または単一値を評価する式のどちらかと一緒に利用する事ができます。

    次のスキームに従って、年次値を含むカラム上で分割したいテーブルを持っていると仮定します。

    パーティション数:年次範囲:
    01990以前
    11991 ? 1994
    21995 ? 1998
    31999 ? 2002
    42003 ? 2005
    52006以降

    そのような領域確保スキームを実施するテーブルはここに表されている CREATE TABLE ステートメントによって実現されます。

    CREATE TABLE t1 (
        year_col  INT,
        some_data INT
    )
    PARTITION BY RANGE (year_col) (
        PARTITION p0 VALUES LESS THAN (1991),
        PARTITION p1 VALUES LESS THAN (1995),
        PARTITION p2 VALUES LESS THAN (1999),
        PARTITION p3 VALUES LESS THAN (2002),
        PARTITION p4 VALUES LESS THAN (2006),
        PARTITION p5 VALUES LESS THAN MAXVALUE
    );
    

    PARTITION ... VALUES LESS THAN ... ステートメントは連続法で機能します。VALUES LESS THAN MAXVALUE は、指示されない限り、最大値よりも大きい 「leftover」 値を指定する為に機能します。

    VALUES LESS THAN 条項は switch ... case ブロックの case 部分と似た方法で連続的に機能するという事を覚えて置いてください。(C、Java、そしてPHP等のような多くのプログラム言語内で見られるのと同じように)これは、それぞれの連続した VALUES LESS THAN 内で指定された上限はその前の物よりも大きく、MAXVALUE に参照を付ける物がリストの一番最後に来るという方法で条項を配列しなければいけない、という事を意味します。

  • LIST(expr):これは州や国のコードなどのような、制限された値のセットを持つテーブル カラムに基づいたパーティションを割り当てる時に便利です。このような場合、特定の州や国に関係している行を1つのパーティションに指定したり、または、特定の州や国のセットに対してパーティションを用意しておく事ができます。これは、VALUES IN だけが各パーティションに許容値を指定するのに利用されるという事を除いて、RANGE と似ています。

    VALUES IN はマッチする値のリストと共に利用されます。例えば、次のように領域確保スキームを作成する事ができます。

    CREATE TABLE client_firms (
        id   INT,
        name VARCHAR(35)
    )
    PARTITION BY LIST (id) (
        PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21),
        PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22),
        PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23),
        PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
    );
    

    リストの領域確保を利用する時、VALUES IN を利用して最低1つのパーティションを定義する必要があります。VALUES LESS THANPARTITION BY LIST と一緒に利用する事はできません。

    注意:現在は、VALUES IN と共に利用される値のリストは整数値のみで構成されています。

  • パーティション数は、num がパーティション数である PARTITIONS num 条項を利用して任意に指定されます。この条項、そして PARTITION 条項が両方利用されたら、numPARTITION 条項を利用して宣言されたパーティションの合計数と同一でなければいけません。

    注意:RANGELIST によって領域確保されたテーブルを作成するのに PARTITIONS 条項を利用したかどうかに関わらず、テーブル定義の中に最低1つ以上の PARTITION VALUES 条項を含む必要があります。(下記参照)

  • パーティションは任意でサブ パーティションに分解する事もあります。これは任意の SUBPARTITION BY 条項を利用して指示する事ができます。サブ パーティションは HASHKEY によって行われるでしょう。これらのどちらかは LINEAR でしょう。これらは、既に説明された同等な領域確保のタイプと同じように機能します。(LISTRANGE でサブ パーティションするのは不可能です。)

    整数値が後に続く SUBPARTITIONS キーワードを利用してサブ パーティション数を指示する事ができます。

  • MySQL 5.1.12 で、PARTITIONSSUBPARTITIONS 条項で利用された値の厳密なチェックを紹介しています。このバージョンから、この値は次のルールを遵守します。

    • 値は正数、ゼロ以外の整数でなければいけません。

    • ゼロが前に付いてはいけません。

    • 値は整数直定数である必要があり、式にはなり得ません。例えば、0.2E+012 であると評価されたとしても、PARTITIONS 0.2E+01 は許されません。(バグ #15890)

各パーティションは partition_definition 条項を利用して個別に定義されるでしょう。この条項を形成するそれぞれの部分は次のような物です。

  • PARTITION partition_name:これはパーティションの論理名を指定します。

  • VALUES 条項:範囲の領域確保に関しては、各パーティションが VALUES LESS THAN 条項を含む必要があり、リストの領域確保に関しては、各パーティションに対して VALUES IN 条項を指定する必要があります。これは、どの行がこのパーティションに格納されるのかという事を決める為に利用されます。構文例に関しては、章?15. パーティショニング のパーティション タイプに関する説明を参照してください。

  • 任意の COMMENT 条項はパーティションを説明する為に利用されるでしょう。.このコメントは単一引用句で始まらなければいけません。例:

    COMMENT = 'Data for the years previous to 1999'
    
  • DATA DIRECTORYINDEX DIRECTORY は、このパーティションのデータとインデックスがそれぞれどこに格納されるのかを指示する為に利用されます。data_dir to index_dir の両方は、絶対的なシステム パスネームでなければいけません。例:

    CREATE TABLE th (id INT, name VARCHAR(30), adate DATE)
    PARTITION BY LIST(YEAR(adate))
    (
      PARTITION p1999 VALUES IN (1995, 1999, 2003)
        DATA DIRECTORY = '/var/appdata/95/data'
        INDEX DIRECTORY = '/var/appdata/95/idx',
      PARTITION p2000 VALUES IN (1996, 2000, 2004)
        DATA DIRECTORY = '/var/appdata/96/data'
        INDEX DIRECTORY = '/var/appdata/96/idx',
      PARTITION p2001 VALUES IN (1997, 2001, 2005)
        DATA DIRECTORY = '/var/appdata/97/data'
        INDEX DIRECTORY = '/var/appdata/97/idx',
      PARTITION p2000 VALUES IN (1998, 2002, 2006)
        DATA DIRECTORY = '/var/appdata/98/data'
        INDEX DIRECTORY = '/var/appdata/98/idx'
    );
    

    DATA DIRECTORYINDEX DIRECTORY は、MyISAM テーブルで利用される CREATE TABLE ステートメントの table_option 条項と同じ形で機能します。

    各パーティションには、1つのデータ ディレクトリとインデックス ディレクトリが指定されます。もし指定されなければ、データとインデックスはデフォルトで MySQL データ ディレクトリに格納されます。

  • パーティション内に格納する行の最大、最小数をそれぞれ指定する為に MAX_ROWSMIN_ROWS が利用されます。max_number_of_rowsmin_number_of_rows の値は正整数でなければいけません。同名のテーブル レベル オプションと同様に、これらはサーバに対してただの 「提案」 として機能し、厳しい制限ではありません。

  • 任意の TABLESPACE 条項は、パーティションのテーブルスペースを指定するのに利用されるでしょう。MySQL クラスタにのみ利用されます。

  • 任意の [STORAGE] ENGINE 条項は、この MySQL サーバにサポートされたエンジンであるこのパーティション内のテーブルが、指定されたストレージ エンジンを利用するように機能します。STORAGE キーワードとイコールのサイン(=) の両方は任意です。もしこのオプションを利用して、パーティションを特定するストレージ エンジンが設定されなければ、テーブル全体に適応するエンジンがこのパーティションで利用されます。

    注意:領域確保ハンドラは PARTITIONSUBPARTITION の両方に対して [STORAGE] ENGINE オプションを受け入れます。現在これを利用する唯一の方法は、全てのパーティション、サブ パーティションを同じストレージ エンジンに設定する事です。もし同じテーブル内で、パーティション、サブ パーティションに異なるストレージ エンジンを設定しようとするとエラーが発生します。エラー 1469 (HY000): MySQL のこのバージョンではパーティション内でハンドラを混在させる事は許可されていません。. 将来の MySQL 5.1 リリース時には、領域確保に関するこの制限を取り除く予定です。

  • NODEGROUP オプションは node_group_id によって確認されたノード グループの一部としてこのパーティションを機能させる為に利用できます。このオプションは MySQL クラスタに対してだけ利用可能です。

  • パーティション定義は、1つかそれ以上の subpartition_definition 条項を含みます。これらはそれぞれ、name が識別子のサブ パーティションである SUBPARTITION name の最小値で構成されます。SUBPARTITION を利用した PARTITION キーワードの入れ替え以外は、サブ パーティション定義の構文はパーティション定義の構文と同一です。

    サブ パーティションは HASHKEY によって行われなけれる必要があり、そして RANGELIST パーティション上のみで行われます。詳しくは 項15.2.5. 「サブ分割」 を参照してください。

パーティションは修正し、マージし、テーブルに追加し、テーブルからドロップする事ができます。これらのタスクを成し遂げる為の基本的な MySQL ステートメントについての情報は、項12.1.2. 「ALTER TABLE 構文」 を参照してください。更なる詳細説明や例に関しては、項15.3. 「パーティショニング管理」 を参照してください。

CREATE TABLE ステートメントの最後に SELECT を追加する事で、1つのテーブルから別のテーブルを作成する事ができます。

CREATE TABLE new_tbl SELECT * FROM orig_tbl;

MySQLは SELECT 内の全ての要素に対して新しいカラムを作成します。例:

mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
    ->        PRIMARY KEY (a), KEY(b))
    ->        ENGINE=MyISAM SELECT b,c FROM test2;

これは、これらの3つのカラム ab、そして 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 の結果出来るテーブル内では、CREATE TABLE 部分の中でのみ名づけられたカラムが最初に来ます。両方で名づけられたカラムか SELECT 部分の中でのみ名づけられたカラムがその後に来ます。SELECT カラムのデータ タイプは CREATE TABLE 部分の中でカラムを指定する事によって無効にする事もできます。

もしデータをテーブルにコピーしている間にエラーが発生すると、それは自動的にドロップされるので作成されません。

CREATE TABLE ... SELECT は自動的にインデックスを作成しません。これはステートメントを可能な限りフレキシブルにする為に意図的に行われます。もし作成したテーブルの中でインデックスを持ちたければ、SELECT ステートメントの前にこれらを指定しなければいけません。

mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;

データ タイプの変換が行われるかもしれません。例えば、AUTO_INCREMENT 属性は保管されず、VARCHAR カラムが CHAR カラムになる事ができます。

CREATE ... SELECT でテーブルを作成する時、必ずクエリの中では 全ての関数呼び出しや式をエイリアスにしてください。もしそれをしなければ、CREATE ステートメントは失敗するか、望まないカラム名になってしまいます。

CREATE TABLE artists_and_works
  SELECT artist.name, COUNT(work.artist_id) AS number_of_works
  FROM artist LEFT JOIN work ON artist.id = work.artist_id
  GROUP BY artist.id;

発生したカラムに対して、データ タイプを明示的に指定する事もできます。

CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;

元テーブルの中で指定されたカラム属性やインデックスを含む、他のテーブルの定義に基づき空のテーブルを作成するには、LIKE を利用してください。

CREATE TABLE new_tbl LIKE orig_tbl;

コピーは元テーブルと同じバージョンのテーブル ストレージ フォーマットを利用して作成されます。

CREATE TABLE ... LIKE は、元テーブルに対して、または外部キー定義に対して指示された DATA DIRECTORYINDEX DIRECTORY テーブル オプションを保管しません。

ユニーク キー値を複製する行をどのように扱うかを指示する為に、IGNOREREPLACE によって SELECT を先行させる事ができます。IGNORE 利用すると、ユニーク キー値上に既存の行を複製する新しい行は廃棄されます。REPLACE を利用すると、新しい行は同じユニーク キー値を持つ行を置き換えます。もし IGNOREREPLACE も指示されなければ、複製ユニーク キー値はエラーになります。

バイナリ ログが元テーブルを再作成する為に利用できる事を保障する為に、MySQL は CREATE TABLE ... SELECT の最中の並列挿入を許可しません。

12.1.8.1. サイレント カラム仕様変更

いくつかのケースでは、MySQL は CREATE TABLEALTER TABLE ステートメント内で与えられたカラム仕様を静かに変更します。これらは、データ タイプ、データ タイプに関連する属性、またはインデックス仕様にとっての変更になります。

  • TIMESTAMP ディスプレイ サイズは廃棄されます。

  • PRIMARY KEY の一部であるカラムは、そのように宣言されなくても NOT NULL にされます。

  • テーブルが作成された時、ENUMSET メンバー値から後続スペースが自動的に削除されます。

  • MySQL は他の SQL データベース ベンダーに利用された特定のデータ タイプを MySQL タイプにマップします。詳しくは 項10.7. 「その他のデータベースエンジンのデータタイプの利用」 を参照してください。

  • もし規定のストレージ エンジンに対して正当ではないインデックス タイプを指定する為に USING を含み、しかしクエリに影響を与えずにそのエンジンが利用できる別の有効なインデックス タイプが存在すれば、エンジンはその有効なタイプを利用します。

MySQL が、指定したデータ タイプ以外の物を利用したかどうかを確認する為には、テーブルを作成、または変更した後に DESCRIBESHOW CREATE TABLE ステートメントを発行してください。

もし myisampack を利用してテーブルを圧縮すると、特定の他のデータタイプの変更を行う事ができます。詳しくは 項13.4.3.3. 「圧縮テーブルの特徴」 を参照してください。

12.1.9. CREATE LOGFILE GROUP 構文

CREATE LOGFILE GROUP logfile_group
    ADD UNDOFILE 'undo_file'
    INITIAL_SIZE [=] initial_size
    [UNDO_BUFFER_SIZE [=] undo_buffer_size]
    ENGINE [=] engine_name

このステートメントは、'undo_file' と名づけられた単一 UNDO ファイルを持つ logfile_group という名前の新しいログ ファイル グループを作成する事ができます。CREATE LOGFILE GROUP ステートメントはたった一つの ADD UNDOFILE 条項を持ちます。

MySQL 5.1.8 から、いつでも1つのクラスタに付き1つだけのログ ファイル グループを持つ事ができるようになりました。(バグ #16386を参照して下さい。)

INITIAL_SIZE パラメータは UNDO ファイルの初期サイズを設定します。任意の UNDO_BUFFFER_SIZE パラメータは、ログ ファイル グループに対して UNDO バッファに利用されるサイズを設定します。UNDO_BUFFER_SIZE のデフォルト値は 8M (8メガバイト)で、この値は有効なシステム メモリの量を超える事はできません。initial_sizeundo_buffer_size_size の両方はバイトで指示されます。my.cnf で利用されている物と同様、大きさによって一文字の省略形を持つこれらのうちのどちらか、または両方に従う事もできます。通常これは M (メガ バイト) か G (ギガ バイト)のどちらかの文字です。

ENGINE パラメータが、このログ ファイル グループによって利用されるストレージ エンジンを決め、その名前はengine となります。MySQL 5.1 では engineNDBNDBCLUSTER の値の1つにならなければいけません。

ENGINE = NDB と一緒に利用された時、ログ ファイル グループと、関連する UNDO ログ ファイルは、各クラスタ データ ノード上に作成されます。INFORMATION_SCHEMA.FILES テーブルに問い合わせする事によって UNDO ファイルが作成され、それらの情報を得た事を証明する事ができます。例:

mysql> SELECT LOGFILE_GROUP_NAME, LOGFILE_GROUP_NUMBER, EXTRA
    -> FROM INFORMATION_SCHEMA.FILES
    -> WHERE FILE_NAME = 'undo_10.dat';
+--------------------+----------------------+----------------+
| LOGFILE_GROUP_NAME | LOGFILE_GROUP_NUMBER | EXTRA          |
+--------------------+----------------------+----------------+
| lg_3               |                   11 | CLUSTER_NODE=3 |
| lg_3               |                   11 | CLUSTER_NODE=4 |
+--------------------+----------------------+----------------+
2 rows in set (0.06 sec)

(詳しくは 項21.21. 「INFORMATION_SCHEMA FILES テーブル」 を参照してください。)

MySQL 5.1.6 では CREATE LOGFILE GROUP が追加されました。MySQL 5.1 では MySQL クラスタの ディスク データ ストレージと一緒の時のみ利用する事ができます。詳しくは 項14.11. 「MySQL Cluster ディスク データ ストレージ」 を参照してください。

12.1.10. CREATE TABLESPACE 構文

CREATE TABLESPACE tablespace
    ADD DATAFILE 'file'
    USE LOGFILE GROUP logfile_group
    [EXTENT_SIZE [=] extent_size]
    INITIAL_SIZE [=] initial_size
    ENGINE [=] engine

このステートメントは、テーブルに格納スペースを提供しながら1つ、または複数のデータ ファイルを含む事ができるテーブルスペースを作成する為に利用されます。1つのデータ ファイルはこのステートメントを利用してテーブルスペースに作成、または追加されます。ALTER TABLESPACE ステートメントを利用してテーブルスペースにデータ ファイルを追加する事ができます。(項12.1.4. 「ALTER TABLESPACE 構文」 を参照してください。)

1つ、または複数の UNDO ログ ファイルのログ ファイル グループは USE LOGFILE GROUP 条項を利用して作成する為にテーブルスペースに割り当てる必要があります。logfile_groupCREATE LOGFILE GROUP で作成した既存在ログ ファイル グループでなければいけません。(項12.1.9. 「CREATE LOGFILE GROUP 構文」 を参照してください。)複数のテーブルスペースは UNDO ロギングに同じログ ファイル グループを利用するでしょう。

EXTENT_SIZE は、テーブル スペースに属する全てのファイルに利用される範囲で、サイズをバイトで設定します。デフォルト値は4バイトです。

extent はディスク スペース割り当てのユニットです。1つの範囲は、別の範囲が利用されるまで、可能な限りのできるだけ多くのデータで満たされます。INFORMATION_SCHEMA.FILES テーブルをクエリする事によって、与えられたファイルでいくつの範囲がフリーであるかを確認する事ができるので、そのファイルの中でどれくらいのフリー スペースがあるのかの概算が導かれます。更なる情報や例に関しては、項21.21. 「INFORMATION_SCHEMA FILES テーブル」 を参照してください。

INITIAL_SIZE パラメータはデータ ファイルの合計サイズをバイトで設定します。一度データ ファイルが作成されると、そのサイズは変更できませんが、追加の ALTER TABLESPACE ... ADD DATAFILE を利用する事によりテーブルスペースにより多くのデータ ファイルを追加する事ができます。詳しくは 項12.1.4. 「ALTER TABLESPACE 構文」 を参照してください。

EXTENT_SIZEINITIAL_SIZE を設定する時(片方、または両方)、my.cnf で利用されている物と同様、大きさによって一文字の省略形を持つ数字に従う事もできます。通常これは M (メガ バイト) か G (ギガ バイト)のどちらかの文字です。

ENGINE パラメータが、このテーブルスペースが利用するストレージ エンジンを決め、その名前はengine となります。MySQL 5.1 では engineNDBNDBCLUSTER の値の1つにならなければいけません。

CREATE TABLESPACE ... ADD DATAFILEENGINE = NDB と共に利用された時、テーブルスペースと関連するデータ ファイルがそれぞれのクラスタ データ ノード上に作成されます。INFORMATION_SCHEMA.FILES テーブルに問い合わせする事によってデータ ファイルが作成され、それらの情報を得た事を証明する事ができます。例:

mysql> SELECT LOGFILE_GROUP_NAME, FILE_NAME, EXTRA 
    -> FROM INFORMATION_SCHEMA.FILES
    -> WHERE TABLESPACE_NAME = 'newts' AND FILE_TYPE = 'DATAFILE';
+--------------------+-------------+----------------+
| LOGFILE_GROUP_NAME | FILE_NAME   | EXTRA          |
+--------------------+-------------+----------------+
| lg_3               | newdata.dat | CLUSTER_NODE=3 |
| lg_3               | newdata.dat | CLUSTER_NODE=4 |
+--------------------+-------------+----------------+
2 rows in set (0.01 sec)

(詳しくは 項21.21. 「INFORMATION_SCHEMA FILES テーブル」 を参照してください。)

MySQL 5.1.6 では CREATE TABLESPACE が追加されました。MySQL 5.1 では MySQL クラスタのディスク データ ストレージと一緒の時のみ利用する事ができます。詳しくは 項14.11. 「MySQL Cluster ディスク データ ストレージ」 を参照してください。

12.1.11. CREATE SERVER 構文

CREATE SERVER server_name
    FOREIGN DATA WRAPPER wrapper_name
    OPTIONS (option ...)

option:
  { HOST character-literal
  | DATABASE character-literal
  | USER character-literal
  | PASSWORD character-literal
  | SOCKET character-literal
  | OWNER character-literal
  | PORT numeric-literal }

このステートメントは FEDERATED ストレージ エンジンと共に利用する為のサーバの定義を作成します。CREATE SERVER ステートメントは mysql データベース内の servers テーブル内の新しい行を作成します。

server_name はサーバの固有の参照でなければいけません。サーバ定義は、サーバの領域内では広範囲です。特定のデータ ベースにサーバ定義を適応するのは不可能です。server_name は最長63文字の長さを持ち(63文字以上の名前は静かに切り捨てられる)、大文字と小文字を区別しません。単一引用句を利用して名前を指定します。

wrapper_namemysql となる必要があり、そして1つの引用句を利用して引用されます。wrapper_name のその他の値は現在はサポートされていません。

option に対しては、文字直定数か数値定数のどちらかを指定しなければいけません。文字直定数は UTF 8で、最高64文字の長さとデフォルトを空の文字列にサポートします。文字列定数は静かに64文字まで切り捨てられます。数値定数は0から9999の間の数字である必要があり、デフォルト値は0です。

CREATE SERVER ステートメントを利用する為に特別な権限は必要ありません。

CREATE SERVER ステートメントは mysql.server テーブル内に FEDERATED テーブルを作成する時に CREATE TABLE ステートメントと共に利用する事ができるエントリを作成します。指定するオプションは mysql.server テーブル内にカラムを投入する為に利用されます。テーブルカラムは Server_nameHostDbUsernamePasswordPort そして Socket です。

例:

CREATE SERVER s
FOREIGN DATA WRAPPER mysql
OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');

テーブルに格納されたデータは FEDERATED テーブルへの接続を作成する時に利用できます。

CREATE TABLE t (s1 INT) ENGINE=FEDERATED CONNECTION='s';

更なる情報については 項13.9. 「FEDERATED ストレージエンジン」 を参照してください。

CREATE SERVER は自動コミットを引き起こしません。

12.1.12. DROP DATABASE 構文

DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

DROP DATABASE はデータベース内の全てのテーブルをドロップし、データベースを削除します。このステートメントには 十分 注意してください!DROP DATABASE を利用する為には、データベース上の DROP 権限が必要です。DROP SCHEMADROP DATABASE の同義語です。

重要:データベースがドロップされる時、データベース上のユーザ権限は自動的にドロップ されません 。詳しくは 項12.5.1.3. 「GRANT 構文」 を参照してください。

IF EXISTS は、データベースが存在しない時にエラーの発生を防ぎます。

もし象徴的にデータベースとリンクした DROP DATABASE を利用すると、リンクと元データベースの両方が削除されます。

DROP DATABASE は削除されたテーブル数を返します。これは、削除された .frm ファイルの数と対応しています。

DROP DATABASEステートメントは、通常作業の最中に MySQL が作成するファイルやディレクトリを与えられたデータベースから削除します。

  • これらの拡張子を持つ全てのファイル:

    .BAK.DAT.HSH.MRG
    .MYD.MYI.TRG.TRN
    .db.frm.ibd.ndb
    .par???
  • もし存在するなら、db.opt ファイルです。

MySQL がリストされたばかりのファイルやディレクトリを削除した後、もしデータベース ディレクトリ内に別のファイルやディレクトリが残れば、そのデータベース ディレクトリは削除する事ができません。この場合、残っている全てのファイルやディレクトリを手作業で削除し、DROP DATABASE ステートメントをもう一度発行しなければいけません。

mysqladmin でデータベースをドロップする事もできます。詳しくは 項7.9. 「mysqladmin ? MySQL サーバの管理を行うクライアント」 を参照してください。

12.1.13. DROP INDEX 構文

DROP INDEX index_name ON tbl_name

DROP INDEX はテーブル tbl_name から index_name と名づけられたインデックスをドロップします。このステートメントは、インデックスをドロップする為に ALTER TABLE ステートメントにマップされます。詳しくは 項12.1.2. 「ALTER TABLE 構文」 を参照してください。

12.1.14. DROP TABLE 構文

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

DROP TABLE は1つまたは複数のテーブルを削除します。各テーブルごとに DROP 権限を持つ必要があります。全てのテーブル データとテーブル定義が 削除されます ので、このステートメントには 注意してください !引数リストの中に名前を付けたテーブルのいずれも存在しない場合、 MySQL は、存在していなかった為にドロップできなかったテーブルを名称別に表し、エラーを戻しますが、MySQL は既存リスト中のテーブルもすべてドロップします。

重要:テーブルがドロップされる時、テーブル上のユーザー権限は自動的にドロップ されません 。詳しくは 項12.5.1.3. 「GRANT 構文」 を参照してください。

パーティション テーブルに対しては、DROP TABLE がテーブル定義と、その全てのパーティションと、それらのパーティションに格納された全てのデータを恒久的に削除する事を覚えておいて下さい。これはまた、ドロップされたテーブルに関連する領域確保定義(.par)ファイルも削除します。

IF EXISTSを利用して、存在していないテーブルに対してエラーが発生するのを防いでください。IF EXISTSを使用すると、実在していないテーブルに対して NOTE が生成されます。詳しくは 項12.5.4.31. 「SHOW WARNINGS 構文」 を参照してください。

RESTRICTCASCADE がポーティングを簡単にする事ができます。MySQL 5.1 ではそれらは何もしません。

注意:DROP TABLE は、TEMPORARY キーワードを利用しない限り自動的に現在のアクティブなトランザクションを行います。

TEMPORARY キーワードは次の効果を持ちます。

  • ステートメントは TEMPORARY テーブルだけをドロップします。

  • ステートメントは進行中のトランザクションを終了しません。

  • アクセス権をチェックしません。(TEMPORARY テーブルはそれを作成したクライアントだけが見る事ができる物なので、チェックは必要ありません。)

TEMPORARY を利用するのは、非 TEMPORARY テーブルを誤ってドロップしない事を保障するのに有効な方法です。

12.1.15. DROP LOGFILE GROUP 構文

DROP LOGFILE GROUP logfile_group
    ENGINE [=] engine

このステートメントは logfile_group 名前が付いたログ ファイル グループをドロップします。ログ ファイル グループが既に存在していなければエラーが発生します。(ログ ファイル グループの作成についての詳細は 項12.1.9. 「CREATE LOGFILE GROUP 構文」 を参照してください。)

重要:ログ ファイル グループをドロップする前に、UNDO ロギングにそのログ ファイル グループを利用する全てのテーブルスペースをドロップしなければいけません。

必要とされる ENGINE 条項は、ドロップされるログ ファイル グループが利用するストレージ エンジン名を提供します。MySQL 5.1 では、engine に許可される値は NDBNDBCLUSTER だけです。

MySQL 5.1.6 では DROP LOGFILE GROUP が追加されました。MySQL 5.1 では MySQL クラスタのディスク データ ストレージと一緒の時のみ利用する事ができます。詳しくは 項14.11. 「MySQL Cluster ディスク データ ストレージ」 を参照してください。

12.1.16. DROP TABLESPACE 構文

DROP TABLESPACE tablespace
    ENGINE [=] engine

このステートメントは CREATE TABLESPACE を利用して予め作成されたテーブルスペースをドロップします。(項12.1.10. 「CREATE TABLESPACE 構文」 を参照してください。)

重要:ドロップされるテーブルスペースはいかなるデータ ファイルも含む事はできません。言い換えると、テーブル スペースをドロップする前に、ALTER TABLESPACE ... DROP DATAFILE を利用してそれぞれのデータ ファイルをドロップしなければいけない、という事です。(項12.1.4. 「ALTER TABLESPACE 構文」 を参照してください。)

ENGINE 条項(要求された)はテーブルスペースに利用されるストレージ エンジンを指定します。MySQL 5.1では、engine に受け入れられる値は NDBNDBCLUSTER だけです。

MySQL 5.1.6 では DROP TABLESPACE が追加されました。MySQL 5.1 では MySQL クラスタのディスク データ ストレージと一緒の時のみ利用する事ができます。詳しくは 項14.11. 「MySQL Cluster ディスク データ ストレージ」 を参照してください。

12.1.17. DROP SERVER 構文

DROP SERVER [ IF EXISTS ] server_name

server_name と名づけられたサーバの、サーバ定義をドロップします。mysql.servers テーブル内の対応する行は削除されます。

テーブルの為にサーバをドロップする事は、作成時にこの接続情報を利用した FEDERATED テーブルに影響を与えません。詳しくは 項12.1.11. 「CREATE SERVER 構文」 を参照してください。

DROP SERVER を利用する為に特別な権限は必要ありません。

DROP SERVER は自動コミットを引き起こしません。

12.1.18. RENAME DATABASE 構文

RENAME {DATABASE | SCHEMA} db_name TO new_db_name;

このステートメントはデータベースをリネームします。これは、データベースの ALTERDROP 権限、そして新しいデータベースのCREATE 権限を必要とします。RENAME SCHEMARENAME DATABASE の同義語です。

サーバがこのステートメントを受け取る時、新しいデータベースを作成します。そしてそれは、テーブルと、トリガなどのようなその他のデータベース オブジェクトを新しいデータベースに移動します。それはまた、格納されたルーチンやイベントなどのようなオブジェクトのシステム テーブルに Db カラムを更新します。最後に、サーバは古いデータベースをドロップします。

現在はこれらの制限がありますので注意してください。

  • RENAME DATABASE はシステム テーブル内にリストされたアカウント権限を変更しません。それらは手動で変更しなければいけません。

  • RENAME DATABASE は、格納されたルーチンやイベントを新しいスキーマ名に移動しません。これは、次のような事を意味します。

    • 格納されたルーチンに対しては、INFORMATION_SCHEMA.ROUTINES テーブルの ROUTINE_SCHEMA カラム内の、そして mysql.proc テーブルの db カラムの値の変更を行いません。

    • イベントに対しては、INFORMATION_SCHEMA.EVENTS テーブルの EVENT_SCHEMA カラム内の、そして mysql.event テーブルの db カラムの値の変更を行いません。

このステートメントは、MySQL 5.1.7 で追加されました。

12.1.19. RENAME TABLE 構文

RENAME TABLE tbl_name TO new_tbl_name
    [, tbl_name2 TO new_tbl_name2] ...

このステートメントは1つ、または複数のテーブルのリネームをします。

リネームは自動的に行われますので、その他のスレッドはリネーム作業中はどのテーブルにもアクセスできません。例えば、もし既存テーブル old_table があるとしたら、同じ構成で中身が空の別のテーブル new_table を作成し、その後、次のように既存テーブルと空のテーブルを入れ替える事ができます。(backup_table は存在していないと仮定する):

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

もしこのステートメントが複数のテーブルをリネームすると、残りの作業は左から右に行われます。もし2つのテーブル名の入れ替えをしたければ、このように行う事ができます。(tmp_table が存在しないと仮定する):

RENAME TABLE old_table TO tmp_table,
             new_table TO old_table,
             tmp_table TO new_table;

2つのデータベースが同じファイル システム上にある限り、テーブルを1つのデータベースから別のものに移動するのに RENAME TABLE を利用する事ができます。

RENAME TABLE current_db.tbl_name TO other_db.tbl_name;

テーブルと関連し、RENAME TABLE を利用して別のデータベースに移動されたトリガがあると、ステートメントは Trigger in wrong schema というエラーになります。

RENAME TABLE はまた、別のデータベース内にビューをリネームしようとしなければ、ビューに対しても機能します。

リネームされたテーブルやビューに与えられた権限は、新しい名前に移動しません。それらは手動で変更しなければいけません。

RENAME を実行する時、ロックされたテーブルやアクティブなトランザクションを持つ事はできません。また、元テーブル上に ALTERDROP 権限を、新しいテーブル上には CREATEINSERT 権限を持つ必要があります。

もし MySQL が複合テーブルのリネームをしている最中にエラーが発生すると、全てを元に戻す為に全てのリネームされたテーブルにリバース リネームを行います。

12.2. データ取り扱いステートメント

12.2.1. DELETE 構文

単一テーブル構文:

DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
    [WHERE where_condition]
    [ORDER BY ...]
    [LIMIT row_count]

複合テーブル構文:

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    tbl_name[.*] [, tbl_name[.*]] ...
    FROM table_references
    [WHERE where_condition]

または:

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    FROM tbl_name[.*] [, tbl_name[.*]] ...
    USING table_references
    [WHERE where_condition]

単一テーブル構文に対しては、DELETE ステートメントが tbl_name から行を削除し、削除された行数を返します。もし WHERE 条項が与えられたら、それはどの行を削除するべきかを決定します。WHERE 条項が無ければ、全ての行が削除されます。もし ORDER BY 条項が指定されると、指定された順に行が削除されます。LIMIT 条項は、削除できる行数に制限を設定します。

複合テーブル条項に対しては、DELETE はそれぞれの tbl_name から条件を満たしている行を削除します。この場合、ORDER BYLIMIT を利用する事はできません。

where_condition は削除される各行に対して正しい結果の式です。それは 項12.2.7. 「SELECT 構文」 で述べられている通りに指定されます。

述べられているように、WHERE を持たない DELETE ステートメントは全ての行を削除します。削除された行数を知る必要がない場合にこの作業を速く行うには、TRUNCATE TABLE を利用してください。詳しくは 項12.2.9. 「TRUNCATE 構文」 を参照してください。

もし AUTO_INCREMENT カラムに対して最大値を持つ行を削除すると、その値は MyISAMInnoDB テーブルに再度利用される事はありません。AUTOCOMMIT モードで DELETE FROM tbl_name を利用してテーブルの中の全ての行を削除すると(WHERE 条項なしで)、InnoDBMyISAM 以外は全てのストレージ エンジンに対してシーケンスが始まります。項13.5.6.3. 「AUTO_INCREMENT カラムが InnoDB 内でどのように機能するか」 で紹介されているように、InnoDB テーブルに対するこの動作にはいくつか例外があります。

MyISAM テーブルには、複合カラム キー内の AUTO_INCREMENT セカンダリ カラムを指定する事ができます。この場合、MyISAM テーブルに対しても、シーケンスの先頭から削除された値の再利用が行われます。詳しくは Using AUTO_INCREMENT を参照してください。

DELETE ステートメントは次の修飾因子をサポートします。

  • もし LOW_PRIORITY を指定すると、サーバは別のクライアントがテーブルからの読み込みをしなくなるまで、DELETE の実行を遅らせます。

  • MyISAM テーブルに対しては、もし QUICK キーワードを利用すると、ストレージ エンジンはインデックスをマージしませんので、いくつかの削除操作のスピードが速くなります。

  • IGNORE キーワードは、行削除の作業中に MySQL が全てのエラーを無視するように働きかけます。(解析段階で起きたエラーは通常通りの扱いになります。)IGNORE を利用した為に無視されたエラーは、警告として返されます。

削除操作のスピードは 項6.2.18. 「DELETEステートメントの速度」 で紹介されている要因によっても影響を受ける可能性があります。

MyISAM テーブルでは、削除された行はリンクされたリスト内で保存され、後続の INSERT 操作は古い行の位置を再利用します。利用されていないスペースを再利用しファイル サイズを縮小するには、テーブルを確認する為に OPTIMIZE TABLE ステートメントか myisamchk ユーティリティを利用してください。OPTIMIZE TABLE の方が簡単ですが、myisamchk の方が速いです。項12.5.2.5. 「OPTIMIZE TABLE 構文」項7.4. 「myisamchk ? MyISAM テーブル メンテナンス ユーティリティ」 を参照して下さい。

QUICK 修飾因子は、インデックスが削除操作の為にマージされるかどうかに影響を与えます。DELETE QUICK は、削除された行のインデックス値が後で挿入された行に似ているインデックス値と置き換えられるアプリケーションに、最も有効です。この場合、削除された値によって作られた穴は再利用されます。

DELETE QUICK は、削除された値が、新しい挿入が再び行われるインデックス値の範囲にかかるアンダーフィルされたインデックスのブロックを導く場合には、有効ではありません。この場合、QUICK の利用は、未使用のままインデックス内に残る無駄なスペースを作り出します。ここに、同じようなシナリオの例があります。

  1. インデックスされた AUTO_INCREMENT カラムを含むテーブルを作成します。

  2. テーブル内に多くの行を挿入します。各挿入は、インデックスのハイ エンドに追加されるインデックス値となります。

  3. DELETE QUICK を利用してカラム範囲のロー エンドにある行のブロックを削除します。

このシナリオの中では、削除されたインデックス値に関連するインデックス ブロックはアンダーフィルされますが、QUICK を利用する事によって別のインデックス ブロックとマージされる事はありません。新しい行は削除された範囲内にインデックス値を持たないので、新しい挿入が行われてもそれらはアンダーフィルされたままです。その上、後で QUICK 無しで DELETE を利用しても、アンダーフィルされたブロック内またはその隣に、削除されたインデックス ブロックのいくつかが偶然残っていない限り、それらはアンダーフィルされたままです。このような条件下で、利用されていないインデックス スペースを再利用するには、OPTIMIZE TABLE を利用してください。

もしテーブルからたくさんの行を削除しようとしているのなら、OPTIMIZE TABLE が後に続く DELETE QUICK を利用する事で処理が速くできるかもしれません。これは、たくさんのインデックス ブロックのマージ操作を行うというよりは、インデックスを再構築する作業です。

MySQL 特有の、DELETE の為の LIMIT row_count オプションは、コントロールがクライアントに戻される前に、削除されるべき最大行数をサーバに伝えます。これは、与えられた DELETE ステートメントに時間がかかりすぎない事を保障します。影響される行数が LIMIT 値よりも少なくなるまで DELETE ステートメントを繰り返す事ができます。

もし DELETE ステートメントが ORDER BY 条項を含むなら、行は条項に指示された順番で削除されます。これは、LIMIT を持つ接続詞の中でだけ本当に役に立ちます。例えば、次のステートメントは WHERE 条項にマッチする行を見つけ、timestamp_column を利用してそれらをソートし、そして最初の(一番古い)物を削除します。

DELETE FROM somelog WHERE user = 'jcole'
ORDER BY timestamp_column LIMIT 1;

WHERE 条項内の特別な条件に依存する1つ、または複数のテーブルから行を削除する為に、DELETEステートメントの中で複数のテーブルを指定する事ができます。しかし、複合テーブル DELETE の中で ORDER BYLIMIT を利用する事はできません。table_references 条項は接合箇所に含まれるテーブルをリストします。その構文は 項12.2.7.1. 「JOIN 構文」 で説明されています。

最初の複合テーブル構文には、FROM 条項の前にリストされた、テーブルのマッチする行だけが削除されます。2番目の複合テーブル構文では、FROM 条項(USING 条項の前) の前にリストされた、テーブルのマッチする行だけが削除されます。その効果は、複数のテーブルから同時に行を削除でき、検索の為だけに利用される追加テーブルを持つ事ができるという事です。

DELETE t1, t2 FROM t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;

または:

DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;

これらのステートメントは、削除する行を検索する時に3つのテーブル全てを利用しますが、テーブル t1t2 からのマッチする行だけを削除します。

前出の例はカンマ演算子を利用する内部接合を表しますが、複合テーブルの DELETE ステートメントは、LEFT JOIN のような、SELECT ステートメント内で許容される接合タイプを利用する事ができます。

構文は Access を持つ互換性のテーブル名の後に .* を許容します。

外部キー制限があるテーブルに InnoDB テーブルを含む複合テーブル DELETE ステートメントを利用すると、MySQL のオプチマイザは、それらの親子関係の順番と違う順番でテーブルを処理するかもしれません。この場合、ステートメントは失敗し、ロールバックされます。代わりに、単一テーブルから削除し、他のテーブルが適宜修正されるように InnoDB が働きかける ON DELETE 性能に頼る必要があります。

注意:もしテーブルにエイリアスを付けるなら、そのテーブルを参照する時はそのエイリアスを利用しなければいけません。

DELETE t1 FROM test AS t1, test2 WHERE ...

データベース間をまたがる削除は、複合テーブル削除にサポートされていますが、この場合は、エイリアスを使わずにテーブルを参照する必要があります。例:

DELETE test1.tmp1, test2.tmp2 FROM test1.tmp1, test2.tmp2 WHERE ...

現在は、サブクエリの中で1つのテーブルから削除し、同じテーブルから選択する事はできません。

12.2.2. DO 構文

DO expr [, expr] ...

DO は式を実行しますが結果は返しません。あらゆる点で DOSELECT expr, ... の省略表現ですが、結果を気にしない場合にはスピードが少し速いという利点があります。

DO は、RELEASE_LOCK() のような、副作用を持つ関数と共に利用すると効果的です。

12.2.3. HANDLER 構文

HANDLER tbl_name OPEN [ AS alias ]
HANDLER tbl_name READ index_name { = | >= | <= | < } (value1,value2,...)
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name CLOSE

HANDLER ステートメントは、テーブル ストレージ エンジン インターフェースへの直接アクセスを供給します。これは MyISAMInnoDB テーブルに有効です。

HANDLER ... OPEN ステートメントはテーブルをオープンし、それに続く HANDLER ... READ ステートメントを通してテーブルをアクセス可能にします。このテーブルは他のスレッドと共有されず、スレッドが HANDLER ... CLOSE をコールするか、終了するまでは閉じられません。もしエイリアスを利用してテーブルをオープンすると、別の HANDLER ステートメントを利用しているオープンされたテーブルへの更なる参照時には、テーブル名ではなくエイリアスを利用しなければいけません。

最初の HANDLER ... READ 構文は、指定されたインデックスが与えられた値を満たし WHERE 条件が一致する行をフェッチします。もし複合カラム インデックスがあるなら、インデックス カラム値をカンマで区切られたリストで指示してください。インデックス内の全てのカラムに値を指定するか、インデックス カラムの左端のプリフィックスに値を指定してください。インデックス my_idxcol_acol_b、そして col_c という名前の3つのカラムをこの通りの順番で含むと仮定してください。HANDLER ステートメントはインデックス内の3つ全てのカラム、または左端のプリフィックス内のカラムに値を指定する事ができます。例:

HANDLER ... READ my_idx = (col_a_val,col_b_val,col_c_val) ...
HANDLER ... READ my_idx = (col_a_val,col_b_val) ...
HANDLER ... READ my_idx = (col_a_val) ...

テーブルの PRIMARY KEY を参照する為に HANDLER インターフェースを利用するには、引用識別子の `PRIMARY` を利用してください。

HANDLER tbl_name READ `PRIMARY` ...

2つ目の HANDLER ... READ 構文は WHERE 条件に合うインデックス順でテーブルから行をフェッチします。

2つ目の HANDLER ... READ 構文は WHERE 条件に合うインデックス順でテーブルから行をフェッチします。これは、フル テーブル スキャンが必要な時には HANDLER tbl_name READ index_name よりも速いです。自然な行の順番というのは、MyISAM テーブル データ ファイルの中で行が格納されている順番です。このステートメントは InnoDB テーブルにも機能しますが、別のデータ ファイルがないので同じようなコンセプトはありません。

HANDLER ... READ の全ての形は単列が空いていれば LIMIT 無しでそれをフェッチします。指定した行数を返す為には LIMIT 条項を含んでください。これは、SELECT ステートメントと同じ構文を持ちます。詳しくは 項12.2.7. 「SELECT 構文」 を参照してください。

HANDLER ... CLOSEHANDLER ... OPEN がオープンしたテーブルを閉じます。

HANDLER は若干低レベルなステートメントです。例えば、これは一貫性を持ちません。これは、HANDLER ... OPEN はテーブルのスナップショットを 撮らない、またテーブルを ロックしない という事です。これは、HANDLER ... OPEN ステートメントが発行された後、テーブル データを変更する事ができ(現在のスレッドか別のスレッドを利用して)、そしてそれらの変更点はHANDLER ... NEXTHANDLER ... PREV スキャンで部分的にだけ見る事ができるかもしれない、という事を意味します。

通常の SELECT ステートメントの代わりに、HANDLER インターフェースを利用するのにはいくつかの理由があります。

  • HANDLERSELECT よりも速いです。

    • 指定されたストレージ エンジン ハンドラ オブジェクトは HANDLER ... OPEN に割り当てられます。そのオブジェクトは、そのテーブルの後続 HANDLER ステートメントに再利用されます。それぞれに対して再初期化する必要はありません。

    • 解析はあまり行われません。

    • オプチマイザやクエリ チェックなどのオーバーヘッドはありません。

    • 2つのハンドラ要求間でテーブルがロックされる必要はありません。

    • ハンドラ インターフェースはデータの統一をする必要がありませんので (例えばダーティ リードが許されています)、ストレージ エンジンは SELECT が通常は許容しない最適化機能を利用する事ができます。

  • ISAM のようなインターフェースを利用するアプリケーションに対しては、HANDLER のおかげでそれらを MySQL にポートするのが簡単になります。

  • HANDLER のおかげで、SELECT では難しい(または不可能な)方法でデータベースをスキャンする事ができます。データベースに対話式のユーザ インターフェースを提供するアプリケーションを利用する時には、HANDLER インターフェースの方がより自然な方法です。

12.2.4. INSERT 構文

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    VALUES ({expr | DEFAULT},...),(...),...
    [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]

または:

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    SET col_name={expr | DEFAULT}, ...
    [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]

または:

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]

INSERT は既存テーブルに新しい行を挿入します。INSERT ... VALUESINSERT ... SET 型のステートメントは、明示的に指定された値に基づいて行を挿入します。INSERT ... SELECT 型は別のテーブルから選択された行を挿入します。INSERT ... SELECT については 項12.2.4.1. 「INSERT ... SELECT 構文」 でさらに詳しく説明されています。

古い行に上書きする為に、INSERT の代わりに REPLACE を利用する事ができます。REPLACE は、古い行を複製する固有キー値を含む新しい行の取り扱いの中では INSERT IGNORE と同等になります。新しい行は捨てられるのではなく、古い行を置き換えるのに利用されます。詳しくは 項12.2.6. 「REPLACE 構文」 を参照してください。

tbl_name は行が挿入されるべきテーブルです。ステートメントが値を提供しなければいけないカラムは次のように指定する事ができます。

  • テーブル名の後にカンマで区切られたカラム名のリストを提供する事ができます。この場合、名前が付けられた各カラムの値には VALUES リストか SELECT ステートメントが与えられなければいけません。

  • もし INSERT ... VALUESINSERT ... SELECT にカラム名のリストを指定しなければ、VALUES リストか SELECT ステートメントがテーブル内全てのカラムの値を提供する必要があります。もしテーブル内のカラムの順番がわからなければ、それを見つける為に DESCRIBE tbl_name を利用してください。

  • SET 条項はカラム名を明示的に指示します。

カラム値を与える方法はいくつかあります。

  • もしストリクト SQL モードを利用していない場合、値を明示的に与えられていないカラムはそのデフォルト値(明示的、または暗黙の)に設定されます。例えば、もしテーブル内の全てのカラムに名前を付けないカラムのリストを指定すると、名づけられていないカラムはそのデフォルト値に設定されます。デフォルト値の割り当てについては 項10.1.4. 「データタイプデフォルト値」 で説明しています。項1.8.6.2. 「無効値の制約」 もご参照ください。

    もし、デフォルト値を持たない全てのカラムの値を明示的に指定しない限りエラーを発生させる INSERT ステートメントが必要であれば、ストリクト モードを利用する必要があります。詳しくは 項4.2.6. 「SQL モード」 を参照してください。

  • 明示的にカラムをそのデフォルト値に設定するには、キーワード DEFAULT を利用してください。これはテーブル内の各カラムの値を持たない不完全な VALUES リストの書き込みを防ぐ事ができるので、一部を除く全てのカラムに値を割り当てる INSERT ステートメントの書き込みを簡単にします。そうでなければ、VALUES リスト内のそれぞれの値に対応するカラム名のリストを書かなければいけません。

    また、与えられたカラムのデフォルト値を生成する式の中で利用されるより一般的な形として、DEFAULT(col_name) を利用する事もできます。

  • もしカラム リストと VALUES リストの両方が空なら、INSERT は各カラム セットを利用してそのデフォルト値に行を作成します。

    INSERT INTO tbl_name () VALUES();
    

    ストリクト モードでは、もしどのカラムもデフォルト値を持っていなければエラーが発生します。そうでなければ、MySQL は明示的に指定されたデフォルト値を持たない全てのカラムに対して暗黙のデフォルト値を利用します。

  • カラム値を提供する為に expr 式を指定する事ができます。もし式のタイプがカラムのタイプに合わなければ、タイプの変換が行われる可能性があり、そしてデータのタイプによっては、与えられた値の変換が別の挿入値を生み出す事があります。例えば、文字列 '1999.0e-2' を、INTFLOATDECIMAL(10,6)、または YEAR カラムに挿入すると、それぞれ 199919.992119.992100、そして 1999 が挿入される事になります。INTYEAR カラムに格納された値が 1999 である理由は、文字列から整数への変換時には、文字列の最初の部分の、有効な整数や年として判断される部分だけを見るからです。浮動小数点と固定小数点カラムに対しては、文字列から浮動小数点への変換時には、文字列全体を有効な浮動小数点として判断します。

    expr 式は、値のリストに早いうちに設定された全てのカラムを参照する事ができます。例えば、col2 の値は、既に割り当てられた col1 を参照する事ができるので、上記のような事が可能なのです。

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

    しかし、col1 の値は、col1 の後で割り当てられた col2 を参照する為、次のような物は正当ではありません。

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

    1つの例外が AUTO_INCREMENT 値を持つカラムに関係しています。別の値の割り当て後に AUTO_INCREMENT 値が発生するので、その割り当ての中での AUTO_INCREMENT カラムへの参照は 0 を返すのです。

VALUES 構文を利用する INSERT ステートメントは複数行を挿入する事ができます。これをする為には、それぞれが括弧で囲まれカンマで区切られている、カラム値の複数リストを含んでください。例:

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);

各行の値のリストは括弧で囲まれている必要があります。次のステートメントは、カラム名の数とリストの中の値の数が合わない為、不正となります。

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3,4,5,6,7,8,9);

INSERT の行に影響された値は mysql_affected_rows() C API 関数を利用して取得できます。詳しくは 項23.2.3.1. 「mysql_affected_rows() を参照してください。

もし INSERT ... VALUES ステートメントを複数値リストか INSERT ... SELECT と共に利用すると、そのステートメントはこのフォーマットで文字列情報を戻します。

Records: 100 Duplicates: 0 Warnings: 0

Records はステートメントによって生成された行数を指示します。(Duplicates がゼロ以外の数値になりえる為、実際に挿入された行数でなければいけないという訳ではありません。)既存の固有インデックス値を複製するので、Duplicates は挿入できなかった行数を指示します。Warnings は、何らかの形で問題があった、カラム値挿入の試みの回数を指示します。警告は次のような条件時に発生します。

  • NOT NULL を宣言していたカラムに NULL を挿入する。複合行 INSERT ステートメントや INSERT INTO ... SELECT ステートメントに対しては、カラムはカラム データ タイプの暗黙のデフォルト値に設定されます。数値タイプ、文字列タイプの空の文字列('')、そして日付、時間タイプの 「ゼロ」 値に対してのこの値は 0 です。サーバは単列を戻すかどうかを確認する為に SELECT からの結果セットを検査しない為、INSERT INTO ... SELECT ステートメントは複合行挿入と同じ方法で扱われます。(単列 INSERT に対しては、NULLNOT NULL カラムに挿入された時、警告は発生しません。代わりに、ステートメントはエラーになり失敗します。)

  • 数値カラムを、範囲外の値に設定する。値はその範囲の終点に一番近いところでクリップされます。

  • 数値カラムに '10.34 a' のような値を割り当てる。後続の非数値テキストは取り除かれ、残りの数値部分が挿入されます。もし文字列値がその最初の部分に数値を持たない場合は、そのカラムは 0 に設定されます。

  • 文字列を、カラムの最大長さを上回る文字列カラムに (CHARVARCHARTEXT、または BLOB)挿入する。値はカラムの最大長さまで切り捨てられます。

  • 日付や時間カラムに不正である値を挿入する。カラムはそのタイプにとって適正であるゼロの値に設定されます。

もしC API を利用していれば、mysql_info() 関数を呼び出す事で、情報文字列を得ることができます。詳しくは 項23.2.3.35. 「mysql_info() を参照してください。

もし AUTO_INCREMENT カラムを持つテーブルに INSERT が行を挿入すれば、SQL LAST_INSERT_ID() 関数を利用する事でそのカラムに利用される値を見つける事ができます。C API の内部から、mysql_insert_id() 関数を利用してください。しかし、2つの関数がいつでも全く同じ働きをする訳ではない事に注意してください。AUTO_INCREMENT カラムに関しての、INSERT ステートメントの動作の更なる情報は 項11.10.3. 「情報関数」項23.2.3.37. 「mysql_insert_id() で紹介されています。

INSERT ステートメントは次の修飾因子をサポートします。

  • もし DELAYED キーワードを利用すると、サーバはバッファに挿入される行を置くので、INSERT DELAYED ステートメントを発行するクライアントは即座に再開されます。もしテーブルが使用中であれば、サーバが行を保持します。テーブルがフリーであればサーバは行の挿入を始め、新しいリクエストがないかを調べる為に定期的にテーブルを確認します。もしあれば、遅れた行の列はテーブルが再度フリーになるまでサスペンドされます。項12.2.4.2. 「INSERT DELAYED 構文」 を参照してください。

    サーバは、INSERT ... SELECT

    INSERT ... ON DUPLICATE KEY UPDATE に対して

    DELAYED を無視します。

  • もし LOW_PRIORITY キーワードを利用すると、別のクライアントがテーブルからの読み込みをしなくなるまで、INSERT の実行が遅れます。これには、既存クライアントが読み込みをしている最中、そして INSERT LOW_PRIORITY ステートメントが待っている最中に読み込みを始めてしまう別のクライアントが含まれます。しかし、INSERT LOW_PRIORITY ステートメントを発行するクライアントがリード ヘビー環境の中で長時間(または永遠に)待つ事は可能です。(これは、クライアントにそのまま作業を続けさせる INSERT DELAYED とは逆の機能です。並列挿入ができなくなるので、通常 LOW_PRIORITYMyISAM テーブルと一緒には利用されません。詳しくは 項6.3.3. 「同時挿入」 を参照してください。

  • もし HIGH_PRIORITY を指定すると、サーバが --low-priority-updates オプションでスタートされている場合その効果が無効になります。また、並行挿入も利用されなくなります。

  • もし IGNORE キーワードを利用したら、INSERT ステートメントの実行中に起きたエラーは警告として扱われます。例えば、IGNORE が無いと、テーブル内に既存の UNIQUE インデックスや PRIMARY KEY 値を複製する行に複製キー エラーが起き、そのステートメントは異常終了されます。IGNORE を利用すると、行の挿入はされませんが、エラーも発行されません。もし IGNORE が指定されなければ、データ変換はステートメントに関するエラーを引き起こします。IGNORE を利用すると、不正な値は一番近い値に調節されて挿入され、警告が発生されますがステートメントは異常終了しません。いくつのテーブルが実際に挿入されたのか、mysql_info() C API 関数を利用して調べる事ができます。

  • もし ON DUPLICATE KEY UPDATE を指定し、UNIQUE インデックスか PRIMARY KEY 内で複製値を引き起こす行が挿入されると、古い行の UPDATE が実行されます。詳しくは 項12.2.4.3. 「INSERT ... ON DUPLICATE KEY UPDATE 構文」 を参照してください。

12.2.4.1. INSERT ... SELECT 構文

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]

INSERT ... SELECT を利用すると、1つ、または複数のテーブルから多くの行をすばやく挿入する事ができます。例:

INSERT INTO tbl_temp2 (fld_id)
  SELECT tbl_temp1.fld_order_id
  FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;

次の条件は INSERT ... SELECT ステートメントを保持します。

  • 複製キー違反を引き起こす行を無視する為に IGNORE を指定してください。

  • DELAYEDINSERT ... SELECT と共に無視されます。

  • INSERT ステートメントの対象テーブルはクエリの SELECT 部のFROM 条項内に現れます。(これは MySQL の古いバージョンでは不可能でした。)この場合、MySQL は行を保持する為に SELECT からテンポラリ テーブルを作成し、そして対象テーブルにそれらの行を挿入します。

  • AUTO_INCREMENT カラムは通常通り機能します。

  • バイナリ ログが元テーブルを再作成する為に利用できる事を保障する為に、MySQL は INSERT ... SELECT ステートメントへの並列挿入を許可しません。

  • 現在は、サブクエリの中で1つのテーブルに挿入し、同じテーブルから選択する事はできません。

  • SELECTINSERT が同じテーブルを参照した時に、曖昧なカラム参照の問題を防ぐ為に、SELECT 部分で利用される各テーブルに固有のエイリアスを与え、その部分の中でのカラム名を適切なエイリアスに限定してください。

ON DUPLICATE KEY UPDATE の値部分の中で、SELECT 部分の中で GROUP BY を利用しない限り、別のテーブル内でカラムの参照をする事ができます。値の部分で非固有カラム名を指定しなければいけない、という副作用が1つあります。

12.2.4.2. INSERT DELAYED 構文

INSERT DELAYED ...

INSERT ステートメントの DELAYED オプションは、もし INSERT が完了するのを待つ事ができない、または待つ必要がないクライアントを持っている場合に大変有効となる、スタンダード SQL の MySQL 拡張子です。これは、MySQL をログに利用し、完了までに長時間かかる SELECTUPDATE ステートメントを定期的に起動させる時によく起こる状態です。

クライアントが INSERT DELAYED を利用する時、サーバからすぐに OK が出て、テーブルが別のスレッドによって使用中でなければ行が挿入される為にキューを作ります。

INSERT DELAYED を利用する事のそれ以外の大きな利益は、たくさんのクライアントからの挿入は一緒にまとめられ、ひとつのブロックに書き込まれると言う事です。これは、別々の挿入を何度も行うよりも早く機能します。

INSERT DELAYED は、もしテーブルが他の形で利用されていないのであれば、通常の INSERT よりも遅いという事に注意してください。また、サーバには、遅れている行を持つ各テーブルに別々のスレッドを扱う為の、追加オーバーヘッドもあります。これは、本当に INSERT DELAYED が必要だという事が確実な時だけ利用するべきであるという事を意味します。

キューを作った行は、テーブルに挿入されるまでメモリ内だけで保持されます。これは、もしmysqld を強制的に終了させたり (例えば、kill -9 を利用して)、mysqld が突然停止してしまったりすると、ディスクに書き込まれる前のキューを作った行は全て失われてしまう という事を意味します。

DELAYED の利用に関しては、いくつかの制限があります。

  • INSERT DELAYEDMyISAMMEMORY、そして ARCHIVE テーブルとのみ機能します。項13.4. 「MyISAM ストレージエンジン」項13.7. 「MEMORY (HEAP) ストレージエンジン」、そして 項13.10. 「ARCHIVE ストレージエンジン」 を参照してください。

    もしデータファイル中にフリー ブロックがなければ、MyISAM テーブルには並列 SELECTINSERT ステートメントがサポートされます。これらの条件下では、INSERT DELAYEDMyISAM と一緒に利用しなければいけない事はほとんどありません。

  • INSERT DELAYED は、値リストを指定する INSERT ステートメントにだけ利用されなければいけません。サーバは、INSERT ... SELECTINSERT ... ON DUPLICATE KEY UPDATE に対して DELAYED を無視します。

  • INSERT DELAYED ステートメントがすぐに返されるので、そのステートメントが生成するであろう AUTO_INCREMENT 値を得る為に、行が挿入される前に、LAST_INSERT_ID() を利用する事はできません。

  • DELAYED 行は、実際に挿入されるまでは SELECT ステートメントには見えません。

  • DELAYED は、スレーブにマスタとは異なるデータを持たせる事があるので、スレーブ複製サーバ上では無視されます。

  • テーブルが書き込みロックされ、ALTER TABLE がテーブル構造を変更するのに利用されると、保留中の INSERT DELAYED ステートメントは失われてしまいます。

  • INSERT DELAYED は画面をサポートしません。

次に、INSERTREPLACEDELAYED を利用した時に何が起こるかを詳しく説明しています。この説明の中では、「スレッド」 は INSERT DELAYED ステートメントを受け取ったスレッドで、「ハンドラ」 は特定のテーブルの為に全ての INSERT DELAYED ステートメントを扱うスレッドを表しています。

  • スレッドが DELAYED ステートメントをテーブルに実行した時、もし同じようなハンドラが既に存在していなければ、全ての DELAYED ステートメントをテーブルに生成する為にハンドラ スレッドが作成されます。

  • スレッドは、ハンドラが以前に DELAYED ロックを習得したかどうかを確認します。もし習得していなければ、ハンドラ スレッドに対して習得するよう命令します。もし他のスレッドが READWRITE ロックをテーブル上に持っていても、DELAYED ロックを得る事ができます。しかし、ハンドラはテーブル構造が最新であるかどうかを確認する為に、全ての ALTER TABLE ロックや FLUSH TABLES ステートメントが終了するのを待ちます。

  • スレッドは INSERT ステートメントを実行しますが、行をテーブルに書き込む代わりに、ハンドラ スレッドに管理されているキューに最終行のコピーを置きます。構文エラーは全てスレッドに見つけられ、クライアント プログラムにリポートされます。

  • クライアントは、挿入操作が完了する前に INSERT が返る為、複製行の数や、結果として生じる行の AUTO_INCREMENT 値をサーバから得る事ができません。(もし C API を利用すると、同じ理由で mysql_info() 関数からは意味のある答えが返りません。)

  • 行がテーブルに挿入された時、バイナリ ログはハンドラ スレッドによって更新されます。複合行挿入の場合、最初の行が挿入された時にバイナリ ログが更新されます。

  • delayed_insert_limit 行が書かれる度に、ハンドラはまだ保留中の SELECT ステートメントがないかどうかを確認します。もしあれば、続ける前にそれらを実行させます。

  • ハンドラのキューに行が無くなると、テーブルのロックは外されます。もし新しい INSERT DELAYED ステートメントが delayed_insert_timeout 秒以内に受信されたら、ハンドラは終了します。

  • もし delayed_queue_size 以上の行が、特定のハンドラ キューの中で保留中だったら、 INSERT DELAYED をリクエストしているスレッドは、キューの中にスペースができるまで待ちます。これは、遅れたメモリのキューの為に mysqld が全てのメモリを使わない事を保障する為に行われます。

  • ハンドラスレッドは、Command カラム内の delayed_insert と共に、MySQL プロセス リスト内に現れます。これは、もし FLUSH TABLES ステートメントを実行したり、KILL thread_id を利用したりすると中止されます。しかし、終了する前にまずテーブル内でキューを作っている全ての行を格納します。この最中は、別のスレッドから新しい INSERT ステートメントを受け入れません。もしこの後に INSERT DELAYED ステートメントを実行すると、新しいハンドラ スレッドが作成されます。

    もし起動中の INSERT DELAYED ハンドラがあったら、INSERT DELAYED ステートメントは通常の INSERT ステートメントより高い優先権を持つという事を意味します。その他の更新ステートメントは、INSERT DELAYED キューが空になるか、誰かがハンドラスレッドを終了させるか (KILL thread_id を利用して)、誰かが FLUSH TABLES を実行するまで待たなければいけません。

  • 次の状態変数は INSERT DELAYED ステートメントの情報を提供します。

    状態変数意味
    Delayed_insert_threadsハンドラ スレッド数
    Delayed_writesINSERT DELAYED で書かれた行数
    Not_flushed_delayed_rows書き込みを待つ行数

    SHOW STATUS ステートメントか、mysqladmin extended-status コマンドを実行する事でこれらの変数を見る事ができます。

12.2.4.3. INSERT ... ON DUPLICATE KEY UPDATE 構文

もし ON DUPLICATE KEY UPDATE を指定し、UNIQUE インデックスか PRIMARY KEY 内で複製値を引き起こす行が挿入されると、古い行の UPDATE が実行されます。例えば、もしカラム aUNIQUE として宣言され、それが値 1 を含んでいたら、次の2つのステートメントは同一効果を持ちます。

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;

UPDATE table SET c=c+1 WHERE a=1;

もしその行が新しいレコードとして挿入されると、行に影響される値は1となり、もし既存レコードが更新されると2になります。

もしカラム b も固有であれば、INSERT は代わりにこの UPDATE ステートメントと同等になります。

UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;

もし a=1 OR b=2 がいくつかの行とマッチすれば、1つの 行だけが更新されます。通常、複数の固有インデックスを持つテーブル上で ON DUPLICATE KEY 条項を利用するのは避けるべきです。

INSERT ... UPDATE ステートメントの INSERT 部分からカラム値を参照する為に、UPDATE 条項の中で VALUES(col_name) 関数を利用する事ができます。言い換えると、UPDATE 条項の中の VALUES(col_name) は、挿入される col_name の値を参照し、複製キーの矛盾は起きないという事です。この関数は、時に複合行挿入をする時に有効です。VALUES() 関数は、INSERT ... UPDATE ステートメントの中でだけ意味を持ち、そうでなければ NULL を返します。例:

INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
  ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

そのステートメントは次の2つと同一です。

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=3;
INSERT INTO table (a,b,c) VALUES (4,5,6)
  ON DUPLICATE KEY UPDATE c=9;

もしテーブルが AUTO_INCREMENT カラムを含み INSERT ... UPDATE が行を挿入すると、LAST_INSERT_ID() 関数は AUTO_INCREMENT 値を返します。もしステートメントが代わりに行を更新すると、LAST_INSERT_ID() は無意味になります。しかし、LAST_INSERT_ID(expr) を利用する事でこれに対処する事ができます。idAUTO_INCREMENT カラムだと仮定してください。LAST_INSERT_ID() が更新に意味を持つようにするには、次のように行を挿入してください。

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;

ON DUPLICATE KEY UPDATE を利用する時は DELAYED オプションは無視されます。

12.2.5. LOAD DATA INFILE 構文

LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [FIELDS
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]
    [IGNORE number LINES]
    [(col_name_or_user_var,...)]
    [SET col_name = expr,...]

LOAD DATA INFILE ステートメントは高スピードでテキスト ファイルからテーブルに行を読み込みます。ファイル名は直定数文字列として与えられなければいけません。

LOAD DATA INFILESELECT ... INTO OUTFILE の補数です。(詳しくは 項12.2.7. 「SELECT 構文」 をご確認ください。)テーブルからファイルにデータを書き込むには、SELECT ... INTO OUTFILE を利用してください。テーブルにファイルをリード バックするには、LOAD DATA INFILE を利用してください。両方のステートメントに対して FIELDSLINES 条項の構文は同じです。条項は両方とも任意ですが、もし両方が指定された場合 FIELDSLINES に先行しなければいけません。

INSERTLOAD DATA INFILE の性能と、LOAD DATA INFILE のスピード アップの更なる情報については、項6.2.16. 「INSERTステートメントの速度」 を参照してください。

character_set_database システム変数によって指示された文字セットはかつてファイルの中の情報を解明していました。SET NAMEScharacter_set_client の設定はインプットの解明に影響を与えません。

現在は ucs2 文字セットを利用するデータ ファイルをロードするのは不可能だという事に気をつけてください。

MySQL 5.1.6 以降のバージョンでは、character_set_filesystem システム変数は、ファイル名の解明をコントロールします。

mysqlimport ユーティリティを利用する事でデータ ファイルをロードする事もできます。これは、サーバに LOAD DATA INFILE ステートメントを送信する事で機能します。--local オプションは mysqlimport がクライアント ホストからデータファイルを読み込むよう働きかけます。もしクライアントとサーバが圧縮されたプロトコルをサポートするなら、スピードが遅いネットワークにより良い性能を得る為に --compress オプションを指定する事ができます。詳しくは 項7.14. 「mysqlimport ? データインポートプログラム」 を参照してください。

もし LOW_PRIORITY を利用すると、別のクライアントがテーブルからの読み込みをしなくなるまで、LOAD DATA の実行が遅れます。

並列挿入の条件を満たす(フリーブロックが途中に無いという事) MyISAM テーブルと共に CONCURRENT を指定すると、LOAD DATA の実行中に他のスレッドがテーブルからデータを検索する事ができます。もし他のスレッドがテーブルを同時に利用していなくても、このオプションを利用する事は LOAD DATA の性能に少しだけ影響を与えます。

もし LOCAL キーワードが指定されたら、それは接続の最後にクライアントに関して解明されます。

  • もし LOCAL が指定されると、ファイルはクライアント ホスト上のクライアント プログラムによって読み込まれ、サーバに送られます。ファイルは、その明確な場所を指定する為の完全なパス名として与えられます。もしそのパス名が相対的な物として与えられると、その名前はクライアントプログラムが開始されたディレクトリと比較して解明されます。

  • もし LOCAL が指定されなければ、ファイルはサーバ ホスト上に置かれ、サーバによって直接読み込まれる必要があります。サーバはファイルを置く為に次のルールを利用します。

    • もしファイル名が完全なパス名であれば、サーバはそれをそのまま利用します。

    • もしファイル名が1つ、または複数の主要コンポネントを持つ相対的なパス名であれば、サーバはそのデータ ディレクトリに関連するファイルを検索します。

    • もし主要コンポネントを持たないファイル名が与えられると、サーバはデフォルト データベースのデータベース ディレクトリ内のファイルを探します。

これらのルールは、非 LOCAL の場合、 ./myfile.txt としてのファイル名はサーバーのデータ ディレクトリから読まれ、その一方、myfile.txt としてのファイル名はデフォルト データベースのデータベース ディレクトリから読み込まれるという事を意味しますので、注意してください。例えば、もし db1 がデフォルト データベースなら、ステーメントが db2 データベース内のテーブルにファイルを明示的にロードしたとしても、次の LOAD DATA ステートメントが db1 のデータベース ディレクトリからファイル data.txt を読み込みます。

LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;

ウィンドウズのパス名は、バックスラッシュではなくフォーワードスラッシュで指定されます。もしバックスラッシュを利用すると、それらを2倍にする必要があります。

安全上の理由で、サーバ上にあるテキスト ファイルを読み込む時、ファイルはデータベース ディレクトリ上にあるか、全てによって読み込み可能である必要があります。また、 サーバ ファイル上で LOAD DATA INFILE を利用する時は、FILE 権限が必要です。詳しくは 項4.7.3. 「MySQL 提供の権限」 を参照してください。

LOCAL を利用すると、ファイルのコンテンツはクライアントからサーバに、その接続全体に送られなければいけないので、サーバがファイル ディレクトリにアクセスするのを許可するのよりも少し速度が遅くなります。反対に、ローカル ファイルをロードするのに FILE 特権は必要ありません。

LOCAL は、サーバとクライアントの両方が、これを許容できる場合のみ機能します。例えば、もし mysqld--local-infile=0 と共に開始された場合、LOCAL は機能しません。詳しくは 項4.6.4. 「LOAD DATA LOCAL のセキュリティ関連事項」 を参照してください。

Unix上では、もしパイプから読み込む為に LOAD DATA が必要であれば、次のテクニックを利用する事ができます。(ここでは、テーブルの中に / ディレクトリのリストをロードします。)

mkfifo /mysql/db/x/x
chmod 666 /mysql/db/x/x
find / -ls > /mysql/db/x/x &
mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x

ロードされるデータを生成するコマンドと mysql を、別々のターミナルのどちらかで起動させる、または背景でデータ生成プロセスを起動させなければいけない (上記の例で表されているように)、という事に注意してください。もしこれを実行しないと、パイプはデータが mysql プロセスによって読み込まれるまでブロックします。

REPLACEIGNORE キーワードは、固有のキー値上に既存行を複製するインプット行の扱いをコントロールします。

  • もし REPLACE を指定すると、インプット行は既存行を置き換えます。言い換えると、主キーや固有インデックスに対して同じ値を持つ、既存行であるという事です。詳しくは 項12.2.6. 「REPLACE 構文」 を参照してください。

  • もし IGNORE を指定すると、 固有キー値上の、既存行を複製するインプット行はスキップされます。もしどちらのオプションも指定しなければ、その動作は LOCAL キーワードが指定されたかどうかによって決まります。LOCAL を利用すると、複製キー値が見つかった時点でエラーが発生し、テキスト ファイルの残りは無視されます。LOCAL を使用しなければ、デフォルトの動作は IGNORE が指定された時と同じです。これは、サーバは操作の最中にファイルの送信を中止する事ができないからです。

もしロード操作中に外部キー制約を無視したければ、LOAD DATA を実行する前に SET FOREIGN_KEY_CHECKS=0 ステートメントを発行する事ができます。

もし空の MyISAM テーブル上でLOAD DATA INFILE を利用すると、別のバッチに全ての非ユニーク インデックスが作成されます。(REPAIR TABLE に関して)通常この操作は、インデックスが多くある時に LOAD DATA INFILE のスピードを速くします。いくつかの極端な場合では、テーブルにファイルをロードする前に ALTER TABLE ... DISABLE KEYS を利用してインデックスをオフにしたり、ファイルをロードした後にインデックスを再作成する為に ALTER TABLE ... ENABLE KEYS を利用する事で、インデックスをさらに速く作成できます。詳しくは 項6.2.16. 「INSERTステートメントの速度」 を参照してください。

LOAD DATA INFILESELECT ... INTO OUTFILE ステートメントの両方に対して、FIELDSLINES 条項の構文は同じです。条項は両方とも任意ですが、もし両方が指定された場合 FIELDSLINES に先行しなければいけません。

もし FIELDS 条項を指定すると、少なくてもどれか1つを指定する必要はありますが、その各サブ条項 (TERMINATED BY[OPTIONALLY] ENCLOSED BY、そして ESCAPED BY) もまた任意になります。

もし FIELDS 条項を指定しなければ、デフォルトは、このように書き込んだ場合と同じようになります。

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

もし FIELDS 条項を指定しなければ、デフォルトは、このように書き込んだ場合と同じようになります。

LINES TERMINATED BY '\n' STARTING BY ''

言い換えると、インプットを読み込む時、デフォルトは LOAD DATA INFILE が次のように機能するよう働きかけるという事です。

  • 改行部分のラインの境界を探してください。

  • ライン プリフィックスを飛び越えないでください。

  • タブのところでラインをフィールドに分割してください。

  • フィールドが引用文字によって囲まれていると思わないでください。

  • \’ が先に来るタブ、改行、または ‘\’ を、フィールド値の一部である直定文字として解釈してください。

反対に、デフォルトはアウトプットを書き込む時に SELECT ... INTO OUTFILE が次のように機能するよう働きかけます。

  • フィールドの間にタブを書いてください。

  • 引用文字でフィールドを囲まないでください。

  • フィールド値内で起こるタブのインスタンス、改行、または ‘\’ を避ける為に ‘\’ を利用してください。

  • 行の最後に改行を書き込んでください。

バックスラッシュは、MySQL の中では文字列内の拡張文字ですので、FIELDS ESCAPED BY '\\' を書き込むには、単一バックスラッシュだと認識させる為に2つのバックスラッシュを指定しなければいけません。

注意:もしウィンドウズ システム上でテキスト ファイルを生成したら、ウィンドウズのプログラムは通常ラインのターミネータとして2つの文字を利用するので、ファイルを正確に読み込む為には LINES TERMINATED BY '\r\n' を利用しなければいけないでしょう。WordPad のようないくつかのプログラムは、ファイルを書き込む時 \r をライン ターミネータとして利用するでしょう。そのようなファイルを読み込む時は、LINES TERMINATED BY '\r' を利用してください。

もし読み込みたいライン全てに、共通の無視したいプリフィックスがあれば、そのプリフィックスと、その前にある全ての物 を飛び越える為に LINES STARTING BY 'prefix_string' を利用する事ができます。もしラインがプリフィックスを持たなければ、ライン全体がスキップされます。このステートメントを発行すると仮定すると:

LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test
  FIELDS TERMINATED BY ','  LINES STARTING BY 'xxx';

もしデータ ファイルがこのようになっていたら:

xxx"abc",1
something xxx"def",2
"ghi",3

行は結果として ("abc",1)("def",2) のようになります。ファイル内の3行目は、プリフィックスを含まないのでスキップされます。

IGNORE number LINES オプションはファイルの先頭のラインを無視する為に利用する事ができます。例えば、カラム名を含む冒頭のヘッダ ラインを飛び越える為に IGNORE 1 LINES を利用する事ができます。

LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test IGNORE 1 LINES;

データベースからのデータをファイルに書き込み、その後そのファイルをデータベースに読み返す為に LOAD DATA INFILE と並行して SELECT ... INTO OUTFILE を利用する時、両方のステートメントの field- と line-handling オプションはマッチする必要があります。そうでなければ、LOAD DATA INFILE はファイルの内容を正確に解釈しません。カンマで区切られたフィールドを持つファイルを書き込む為に、SELECT ... INTO OUTFILE を利用すると仮定してください。

SELECT * INTO OUTFILE 'data.txt'
  FIELDS TERMINATED BY ','
  FROM table2;

カンマで区切られたファイルを読み返す為の正しいステートメントは次のようになります。

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

もし代わりに、次に表されているステートメントを利用してファイルを読み込もうとすると、LOAD DATA INFILE にフィールドの間にあるタブを探すよう指示を出すので、そのステートメントは機能しません。

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

各インプット ラインが単一フィールドとして解釈されるという結果がよく出されます。

LOAD DATA INFILE は、外部ソースから得たファイルを読見込むのに利用する事ができます。例えば、多くのプログラムは、ラインがカンマで区切られたフィールドを持ち、2つの引用句で囲まれている というような、カンマで区切られた値(CSV)のフォーマットでデータをエクスポートする事ができます。もしそのようなファイルの中のラインが改行で終了していたら、ここに表されているステートメントはファイルをロードする為に利用するであろう field- と line-handling オプションを説明します。

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

field- または line-handling オプションは空の文字列を指定する事ができます。 ('')もし空でなければ、FIELDS [OPTIONALLY] ENCLOSED BYFIELDS ESCAPED BY 値は単一文字という事になります。FIELDS TERMINATED BYLINES STARTING 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 文字は (CHARBINARYTEXT、または ENUM のような) 文字列データタイプを持つカラムからの値を囲む為だけに利用されます。

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

フィールド値内の ENCLOSED BY 文字の発生は、ESCAPED BY 文字と共にそれらをプリフィックスする事で拡張する事ができるという事を覚えておいて下さい。また、もし空の ESCAPED BY 値を指定すると、LOAD DATA INFILE で正しく読み込む事ができないアウトプットを気づかずに生成してしまう可能性がある事も覚えておいて下さい。例えば、もし拡張文字が空なら、表示されただけの先行するアウトプットは次のように現れます。4つ目のラインの2つ目のフィールドの引用句の後に、フィールドを(誤って)終了させるカンマが含まれている事を確認してください。

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

インプットに関しては、もし ENCLOSED BY 文字があれば、フィールド値の最後から剥ぎ取られます。(OPTIONALLY が指定されているかどうかは関係なくこれは事実です。OPTIONALLY はインプットの解釈に対して影響しません。)ESCAPED BY 文字に先行された ENCLOSED BY 文字の発生は、現在のフィールド値の一部として解釈されます。

もしフィールドが ENCLOSED BY 文字で始まると、その文字のインスタンスはフィールド、またはライン TERMINATED BY シーケンスが後に続いている場合のみ、そのフィールド値を終了させていると判断されます。曖昧さを防ぐ為に、フィールド値内の ENCLOSED BY 文字の発生を2倍にすると、その文字の単一インスタントとして解釈されます。例えば、もし 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 BYLINES TERMINATED BY 値の最初の文字

  • ASCII 0 (実際に拡張文字の後ろに書かれているのは、ゼロの値のバイトではなく、ASCII ‘0’です。)

もし FIELDS ESCAPED BY 文字が空なら、文字が拡張される事はなく、NULL\N ではなく NULL としてアウトプットされます。特に、もしデータ中のにフィールド値が先ほどのリストの中の文字を含んでいる場合は、空の拡張文字を指定するのは良い考えではないかも知れません。

インプットに関しては、もし FIELDS ESCAPED BY 文字が空でなければ、その文字の発生は削除され、後続文字はフィールド値の一部として文字通りに取り込まれます。 例外は、拡張された ‘0’ または ‘N’ です。(例えば、もし拡張文字が ‘\’ なら \0 または \N です。)これらのシーケンスは、ASCII NUL (ゼロの値のバイト) と NULL として解釈されます。NULL の扱いのルールについてはこのセクションの後半で説明します。

\’-escape 構文の更なる情報については、項8.1. 「リテラル値」 を参照してください。

特定の場合には、field- と line-handling オプションは互いに影響しあいます。

  • もし LINES TERMINATED BY が空の文字列で、FIELDS TERMINATED BY がそうでない場合、ラインもまた FIELDS TERMINATED BY で終わります。

  • もし FIELDS TERMINATED BYFIELDS ENCLOSED BY 値の両方が空なら、('')、固定行(区切られていない)フォーマットが利用されます。固定行フォーマットでは、フィールド間で区切り文字は利用されません。(ライン ターミネータを持つ事はできます。)代わりに、フィールド内に全ての値を保持するのに十分なフィールド幅を利用して、カラム値が読み込み、書き込みされます。TINYINTSMALLINTMEDIUMINTINT、そして BIGINT のフィールド幅はそれぞれ、宣言されているディスプレイ幅に関わらず、4、6、8、11、そして20です。

    LINES TERMINATED BY はラインを分割する為に利用されます。もしラインが全てのフィールドを含んでいなければ、残りのカラムはデフォルト値に設定されます。もしライン ターミネータがなければ、これを '' に設定しなければいけません。この場合、テキスト ファイルは各行に対して全てのフィールドを含まなければいけません。

    固定行フォーマットはまた、後ほど説明があるように、NULL 値の扱いに影響を与えます。固定サイズ フォーマットは、もしマルチ バイト文字セットを利用する場合は機能しないという事を覚えておいて下さい。

NULL 値の扱いは、利用中の FIELDSLINES オプションによって変わります。

  • デフォルトの FIELDSLINES 値には、NULL はアウトプットには \N のフィールド値として書かれ、\N のフィールド値は、インプットには NULL として読まれます。(ESCAPED BY 文字は ‘\’ と仮定する。)

  • もし FIELDS ENCLOSED BY が空でなければ、直定数文字 NULL をその値として含むフィールドは NULL 値として読まれます。これは、'NULL' 文字列として読み込まれる FIELDS ENCLOSED BY 文字の間に囲まれた単語 NULL とは異なります。

  • もし FIELDS ESCAPED BY が空なら、NULL は単語 NULL として書き込まれます。

  • 固定行フォーマットでは、(FIELDS TERMINATED BYFIELDS ENCLOSED BY の両方が空の時に利用される)、NULL は空の文字列として書き込まれます。この場合、NULL 値と空の文字列は、ファイルに書き込まれた時には両方とも空の文字列として書き込まれるので、テーブル内では見分けがつかないという事を覚えておいて下さい。もしファイルをリード バックする時にその2つを見分ける必要があれば、固定行フォーマットは利用するべきではありません。

NULLNOT NULL カラムにロードしようとすると、カラムのデータ タイプと警告の為の暗黙のデフォルト値の割り当て、またはストリクト SQL モードでのエラーが発生します。暗黙のデフォルト値に関しては 項10.1.4. 「データタイプデフォルト値」 で説明されています。

LOAD DATA INFILE によってサポートされない場合もあります。

  • 固定サイズ行(FIELDS TERMINATED BYFIELDS ENCLOSED BY の両方が空)と BLOBTEXT カラム。

  • もし、別の物と同じ、またはそのプリフィックスであるセパレータを指定すると、LOAD DATA INFILE はインプットを正確に解釈する事ができません。例えば、次の FIELDS 条項は問題を引きこします。

    FIELDS TERMINATED BY '"' ENCLOSED BY '"'
    
  • もし FIELDS ESCAPED BY が空なら、FIELDS TERMINATED BY 値が後に続く FIELDS ENCLOSED BYLINES TERMINATED BY の発生を含むフィールド値は、LOAD DATA INFILE のフィールドやラインの読み込みを早く止めてしまいます。これは、LOAD DATA INFILE はフィールドやライン値がどこで終わるのかを正しく判断する事ができない為に起こります。

次の例は、persondata テーブルの全てのカラムをロードします。

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

デフォルトでは、LOAD DATA INFILE ステートメントの最後にカラムリストがない場合、インプット ラインが各テーブル カラムに対してフィールドを含みます。もし1つのテーブルのカラムをいくつかロードしたければ、カラム リストを指定してください。

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

インプット ファイル内のフィールドの順番が、テーブル内のカラムの順番と異なる場合は、カラム リストも指定しなければいけません。そうでなければ、MySQL はインプット フィールドとテーブル カラムをどのようにマッチさせるのか判断できません。

カラム リストはカラム名かユーザ変数のどちらかを含みます。ユーザ変数を利用すると、カラムに結果を割り当てる前に SET 条項で値を変換する事ができます。

SET 条項の中のユーザ変数は、いくつかの方法で利用する事ができます。次の例は、t1.column1 の値に対して直接最初のインプット カラムを利用し、そして2番目のインプット カラムを t1.column2 の値に利用される前に、分割操作に影響されるユーザ変数に割り当てます。

LOAD DATA INFILE 'file.txt'
  INTO TABLE t1
  (column1, @var1)
  SET column2 = @var1/100;

SET 条項は、インプット ファイルから派生した物ではない値を提供する事ができます。次のステートメントは、現在の日付と時間に column3 を設定する事ができます。

LOAD DATA INFILE 'file.txt'
  INTO TABLE t1
  (column1, column2)
  SET column3 = CURRENT_TIMESTAMP;

インプット値をユーザ変数に割り当て、変数をテーブル カラムに割り当てない事で、インプット値を廃棄する事ができます。

LOAD DATA INFILE 'file.txt'
  INTO TABLE t1
  (column1, @dummy, column2, @dummy, column3);

カラム/変数リストと SET 条項の利用は、次の制約を受けます。

  • SET 条項の中の割り当ては、割り当て演算子の左側にカラム名だけを持たなければいけません。

  • SET 割り当ての右側でサブクエリを利用する事ができます。カラムに割り当てられる値を返すサブ クエリは、スカラ サブ クエリのみでしょう。また、ロードされたテーブルから選択する為にサブクエリを利用する事はできません。

  • IGNORE 条項に無視されるラインは、カラム/変数リストや SET 条項の為に処理されません。

  • ユーザ変数は表示幅を持たないので、固定行フォーマットを持つデータのロード中には利用する事ができません。

インプット ラインを処理している時、LOAD DATA はそれをフィールドに分割し、カラム/変数リストと SET 条項があれば、それらに従って値を利用します。そして、結果としてできた行がテーブルに挿入されます。もしテーブルに BEFORE INSERTAFTER INSERT トリガがあれば、それらはそれぞれ、行の挿入前か挿入後に起動されます。

もしインプット ラインのフィールドが多すぎたら、余分なフィールドは無視され、警告数が増加されます。

もしインプット ラインのフィールドが少なすぎたら、インプットフィールドがないテーブル カラムがそれらのデフォルト値として設定されます。デフォルト値の割り当てについては 項10.1.4. 「データタイプデフォルト値」 で説明しています。

空のフィールド値は、フィールド値がない場合とは異なって解釈されます。

  • 文字列タイプには、カラムは空の文字列に設定されます。

  • 数値タイプには、カラムは 0 に設定されます。

  • 日付と時間タイプには、カラムはそのタイプに適切な 「zero」 値に設定されます。詳しくは 項10.3. 「日付と時刻タイプ」 を参照してください。

これらは、INSERTUPDATE ステートメントの中で、空の文字列を明示的に文字列、数値、または数値と時間タイプに割り当てた時の結果と同じ値です。

TIMESTAMP カラムは、カラムに NULL 値がある時(\N)、または、TIMESTAMP カラムのデフォルト値が現在のタイム スタンプの時だけ現在の日付と時間に設定され、カラムのデフォルト値はフィールド リストが指定された時に削除されます。

LOAD DATA INFILE は全てのインプットを文字列とみなしますので、INSERT ステートメントと同じ方法で、ENUMSET カラムにも数値の値を利用する事ができます。全ての ENUMSET 値は文字列として指定される必要があります。

BIT 値はバイナリ表記を利用してロードする事はできません。(例えば b'011010')これに対処するには、値を標準整数として指定し、それらの変換には、MySQL が数値タイプの変換を行う為に、SET 条項を利用し、そしてそれらを BIT カラムに正確にロードしてください。

shell> cat /tmp/bit_test.txt
2
127
shell> mysql test
mysql> LOAD DATA INFILE '/tmp/bit_test.txt'
    -> INTO TABLE bit_test (@var1) SET b= CAST(@var1 AS SIGNED);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Deleted: 0  Skipped: 0  Warnings: 0

mysql> SELECT BIN(b+0) FROM bit_test;
+----------+
| bin(b+0) |
+----------+
| 10       |
| 1111111  |
+----------+
2 rows in set (0.00 sec)

LOAD DATA INFILE ステートメントが終了する時、次のフォーマットで情報文字列を返します。

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

もしC API を利用していれば、mysql_info() 関数を呼び出す事で、ステートメントの情報を得る事ができます。詳しくは 項23.2.3.35. 「mysql_info() を参照してください。

LOAD DATA INFILE もまた、インプット行のフィールドが多すぎる、または少なすぎる時に警告を生成するという事を除き、値が INSERT ステートメントを通して挿入された時と同じ状況下で警告が発生します。(項12.2.4. 「INSERT 構文」 を参照してください。) 警告はどこにも格納されません。警告数は、全てが順調であるかどうかを示す為だけに利用されます。

失敗した内容の情報を表す最初の max_error_count 警告のリストを得る為に、SHOW WARNINGS を利用する事ができます。詳しくは 項12.5.4.31. 「SHOW WARNINGS 構文」 を参照してください。

12.2.6. REPLACE 構文

REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name [(col_name,...)]
    VALUES ({expr | DEFAULT},...),(...),...

または:

REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    SET col_name={expr | DEFAULT}, ...

または:

REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name [(col_name,...)]
    SELECT ...

REPLACE は、もしテーブル内の古い行が PRIMARY KEYUNIQUE インデックスの新しい行と同じ値を持っていれば、古い行は新しい行が挿入される前に削除されるという事以外、INSERT と全く同じように機能します。詳しくは 項12.2.4. 「INSERT 構文」 を参照してください。

REPLACE は SQL スタンダードの MySQL 拡張子です。それは挿入、または 削除 と挿入を行います。挿入、または 更新 ? を行うスタンダード SQL ? の別の MySQL 拡張子に関しては、 項12.2.4.3. 「INSERT ... ON DUPLICATE KEY UPDATE 構文」 を参照してください。

テーブルが PRIMARY KEYUNIQUE インデックスを持たなければ、REPLACE ステートメントの利用は何の意味も持たないという事を覚えておいてください。新しい行が別の行を複製するかどうかを決める為に利用するインデックスが無い為、それは INSERT と同等になります。

全てのカラムの値は、REPLACE ステートメントの中で指定された値から取られています。紛失したカラムは、INSERT と同じように、デフォルト値に設定されます。現在の行から値を参照し、それらを新しい行の中で利用する事はできません。もし、SET col_name = col_name + 1 のような割り当てを利用すると、右側のカラム名の参照は DEFAULT(col_name) として扱われるので、その割り当ては SET col_name = DEFAULT(col_name) + 1 と同等になります。

REPLACE を利用する為には、テーブルに対して INSERTDELETE 権限の両方を持つ必要があります。

REPLACE ステートメントは、影響を受けた行数を表す為に総数を返します。これは、削除、挿入された行の総数です。もし単列 REPLACE の総数が1であれば、行が1つ挿入され、削除された行はないという事になります。 もし総数が1よりも大きければ、新しい行が挿入される前に、1つまたはそれ以上の行が削除されたという事になります。もしテーブルが複数の固有インデックスを含んでいれば、単列が複数の古い行を置き換える事が可能であり、そして新しい行は異なる固有のインデックス内の異なる古い行に値を複製します。

影響を受けた行の総数によって、REPLACE が行を追加しただけなのか、それとも行の置き換えも行ったのか、という事を簡単に知る事ができます。総数が1(追加された)か、それよりも大きい(置き換えが行われた)かを確認してください。

もしC API を利用していれば、mysql_affected_rows() 関数を利用する事で、影響を受けた行の総数を得る事ができます。

現在は、サブクエリの中で1つのテーブルに置き換え、同じテーブルから選択する事はできません。

MySQL は次のアルゴリズムを REPLACE (と LOAD DATA ... REPLACE)に利用します。

  1. テーブルに新しい行の挿入を試みてください。

  2. 主キーか固有インデックスに複製キー エラーが起きた為に挿入に失敗したら:

    1. 複製キー値を持つ矛盾した行をテーブルから削除してください。

    2. テーブルに新しい行の挿入をもう一度試みてください。

12.2.7. SELECT 構文

SELECT
    [ALL | DISTINCT | DISTINCTROW ]
      [HIGH_PRIORITY]
      [STRAIGHT_JOIN]
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    select_expr, ...
    [FROM table_references
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [HAVING where_condition]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ...]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [PROCEDURE procedure_name(argument_list)]
    [INTO OUTFILE 'file_name' export_options
      | INTO DUMPFILE 'file_name'
      | INTO @var_name [, @var_name]]
    [FOR UPDATE | LOCK IN SHARE MODE]]

SELECT は、1つまたは複数のテーブルから選択した行を検索するために利用され、UNION ステートメントとサブクエリを含む事ができます。項12.2.7.2. 「UNION 構文」項12.2.8. 「サブクエリ構文」 を参照して下さい。

一番良く利用される SELECT ステートメントの条項はこれらです。

  • select_expr は、検索したいカラムを指示します。少なくても1つの select_expr が必要です。

  • table_references はどのテーブルから行の検索をするかを指示します。その構文は 項12.2.7.1. 「JOIN 構文」 で説明されています。

  • WHERE 条項がもしあれば、それは行が選択される為に満たさなければいけない条件を指示します。 where_condition は選択される行が真であるかを確認する式です。ステートメントは、もし WHERE 条項がなければ全ての行を選択します。

    WHERE 条項の中では、総計 (要約) 関数以外の、MySQL がサポートする関数や演算子の全てを利用する事ができます。詳しくは 章?11. 関数と演算子 を参照してください。

SELECT もまた、別のテーブルへの参照無しで算出された行を検索する為に利用する事ができます。

例:

mysql> SELECT 1 + 1;
        -> 2

テーブルが参照されていない場合に、DUAL をダミー テーブルとして指定する事が許されています。

mysql> SELECT 1 + 1 FROM DUAL;
        -> 2

DUAL は純粋に、全ての SELECT ステートメントが FROM と、別の条項を持津事を要求する人々の為に役立つ物です。MySQL は条項を無視するかもしれません。 MySQL は、もしテーブルが参照されなければ FROM DUAL を要求しません。

通常、利用される条項は構文説明に表されるのと全く同じ順番で与える必要があります。例えば、HAVING 条項は GROUP BY 条項の前、ORDER BY 条項の後に来なければいけません。例外は、INTO 条項が構文の説明どおりに表される事も、FROM 条項の直前に先行して表される事も両方可能であるという事です。

  • select_exprAS alias_name を利用したエイリアスを与える事ができます。そのエイリアスは、式のカラム名として利用され、 GROUP BYORDER BY、または HAVING 条項内で利用する事ができます。例:

    SELECT CONCAT(last_name,', ',first_name) AS full_name
      FROM mytable ORDER BY full_name;
    

    AS キーワードは、select_expr をエイリアスを指定する時には任意です。前出の例はこのように書く事が可能でした。

    SELECT CONCAT(last_name,', ',first_name) full_name
      FROM mytable ORDER BY full_name;
    

    しかし、AS が任意なので、2つの select_expr 式の間のカンマを忘れると、わずかなエラーが発生する事があります。MySQL は2番目をエイリアスだと解釈します。例えば次のステートメントの中で、 columnb はエイリアスとして扱われています。

    SELECT columna columnb FROM mytable;
    

    この理由の為、カラムのエイリアスを指定する時には AS を明示的に利用する癖をつけておくと良いでしょう。

  • WHERE 条項が実行された時にはまだカラム値が決定されていない可能性があるので、WHERE 条項の中でカラムのエイリアスを利用するのは許されていません。 詳しくは 項B.1.5.4. 「Problems with Column Aliases」 を参照してください。

  • FROM table_references はどのテーブルから行の検索をするかを指示します。もし複数のテーブルに名前をつけると、それは結合を実行するという事になります。結合構文の情報に関しては、項12.2.7.1. 「JOIN 構文」 を参照してください。指定された各テーブルにエイリアスを任意で指定する事ができます。

    tbl_name [[AS] alias]
        [{USE|IGNORE|FORCE} INDEX (key_list)]
    

    どのようにインデックスを選択するかについてのオプチマイザ ヒントを与える USE INDEXIGNORE INDEXFORCE INDEX の利用については 項12.2.7.1. 「JOIN 構文」 で説明しています。

    MySQL がテーブル スキャンの代わりにキー スキャンを好むように仕向ける代替法として SET max_seeks_for_key=value を利用する事ができます。詳しくは 項4.2.3. 「システム変数」 を参照してください。

  • データベースを明示的に指定する為に、デフォルト データベース内で tbl_name、または db_name.tbl_name としてテーブルを参照する事ができます。col_nametbl_name.col_name、または db_name.tbl_name.col_name としてカラムを参照する事ができます。参照が曖昧にならなければ、カラムの参照に tbl_namedb_name.tbl_name プリフィックスを指定する必要はありません。さらに明確なカラム参照フォームを必要とする例に関しては、項8.2.1. 「識別子の修飾語」 を参照してください。

  • テーブル参照では tbl_name AS alias_nametbl_name alias_name 利用してエイリアスを指定する事ができます。

    SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
      WHERE t1.name = t2.name;
    
    SELECT t1.name, t2.salary FROM employee t1, info t2
      WHERE t1.name = t2.name;
    
  • アウトプットに選択されたカラムは、カラム名、カラム エイリアス、またはカラム位置を利用して ORDER BYGROUP BY 条項の中で参照する事ができます。カラム位置は整数で、1から始まります。

    SELECT college, region, seed FROM tournament
      ORDER BY region, seed;
    
    SELECT college, region AS r, seed AS s FROM tournament
      ORDER BY r, s;
    
    SELECT college, region, seed FROM tournament
      ORDER BY 2, 3;
    

    逆の順番にソートする為には、ソートに利用している ORDER BY 条項の中で、カラム名に DESC (降順)キーワードを追加してください。デフォルトは昇順です。これは ASC キ−ワードを利用して明示的に指定する事ができます。

    カラム位置の利用は、構文が SQL スタンダードから削除された為に今後廃止される可能性があります。

  • もし GROUP BY を利用すると、アウトプット行は GROUP BY に従って、まるで同じカラムに ORDER BY を持っていたかのようにソートされます。GROUP BY が生成するソートのオーバーヘッドを防ぐには、ORDER BY NULL を追加してください。

    SELECT a, COUNT(b) FROM test_table GROUP BY a ORDER BY NULL;
    
  • MySQL は、条項の中で名づけられたカラムの後ろに ASCDESC を指定する事もできるように、GROUP BY 条項を拡張します。

    SELECT a, COUNT(b) FROM test_table GROUP BY a DESC;
    
  • MySQL は、GROUP BY 条項内で言及されていないフィールドの選択を許可する為に、 GROUP BY の利用を拡張します。もしクエリから期待通りの結果を得る事ができないのであれば、項11.11. 「GROUP BY 句との関数および修飾子の使用」 内の GROUP BY の説明を読んでください。

  • GROUP BYWITH ROLLUP 修飾因子を許容します。詳しくは 項11.11.2. 「GROUP BY 修飾子」 を参照してください。

  • HAVING 条項は、最後の方で項目がクライアントに送られる直前に、最適化無しで適応されます。(LIMITHAVING の後で適応されます。)

    SQL スタンダードは HAVINGGROUP BY 条項の中、または総計関数の中で利用されるカラムだけを参照する事を要求します。しかし、MySQL はこの動作に拡張子をサポートし、HAVINGSELECT リストの中のカラムと外部のサブクエリの中のカラムを参照する事を許容します。

    もし HAVING 条項が曖昧なカラムを参照すると、警告が発生します。次のステートメントの中では、エイリアスとカラム名の両方として利用されている為 col2 は曖昧です。

    SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;
    

    スタンダード SQL の動作には優先権が与えられるので、もし HAVING カラム名が GROUP BY と、アウトプット カラム リスト内のエイリアスカラムの両方で利用されると、優先権は GROUP BY カラム内のカラムに与えられます。

  • HAVING は、WHERE 条項内になければいけない項目に対しては利用しないでください。例えば、次のような物を書かないでください。

    SELECT col_name FROM tbl_name HAVING col_name > 0;
    

    代わりにこのように書いてください。

    SELECT col_name FROM tbl_name WHERE col_name > 0;
    
  • HAVING 条項は WHERE 条項が参照できない総計関数を参照する事ができます。

    SELECT user, MAX(salary) FROM users
      GROUP BY user HAVING MAX(salary) > 10;
    

    (これは MySQL の古いバージョンでは機能しませんでした。)

  • MySQL は複製カラム名を許容します。これは、同じ名前の select_expr が複数存在できるという事です。これはスタンダード SQL の拡張子です。 MySQL はまた GROUP BYHAVINGselect_expr 値を参照する事を許容するので、この結果は曖昧になり得ます。

    SELECT 12 AS a, a FROM t GROUP BY a;
    

    このステートメントの中では、両方のカラムが a という名前を持ちます。グループ分けに正しいカラムを利用する事を保障する為に、各 select_expr に異なる名前を利用してください。

  • MySQL は select_expr 値の中、そして FROM 条項内のテーブル カラムの中を検索する事で ORDER BY 条項内の無条件のカラムやエイリアス参照を解決します。GROUP BYHAVING 条項に対しては、select_expr 値内を検索する前に FROM 条項を検索します。(GROUP BYHAVING に対しては、ORDER BY に対するのと同じルールを利用した MySQL 5.0 以前の動作とは異なります。)

  • LIMIT 条項は SELECT ステートメントに返された行数を制限するのに利用する事ができます。LIMIT は、負数以外の整数定数でなければいけない、1つか2つの数値引数を取ります。(準備されたステートメントを利用している時以外)

    その2つの引数のうち、最初の物は返される最初の行のオフセットを指定し、2つめの物は返される行の最高数を指定します。冒頭の行のオフセットは0です。(1ではありません)

    SELECT * FROM tbl LIMIT 5,10;  # Retrieve rows 6-15
    

    全ての行を一定のオフセットから結果セットの最後まで検索するには、2つめのパラメータに大きい数字を利用する事ができます。このステートメントは96番目の行から最後まで全ての行を検索します。

    SELECT * FROM tbl LIMIT 95,18446744073709551615;
    

    1つの引数で、その値は結果セットの最初から返される行数を指定します。

    SELECT * FROM tbl LIMIT 5;     # Retrieve first 5 rows
    

    言い換えると、LIMIT row_countLIMIT 0, row_count と同等だという事になります。

    用意されたステートメントには、プレースホルダを利用する事ができます。次のステートメントは tbl テーブルから行を1つ返します。

    SET @a=1;
    PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?';
    EXECUTE STMT USING @a;
    

    次のステートメントは tbl テーブルから2行目から6行目を返します。

    SET @skip=1; SET @numrows=5;
    PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?, ?';
    EXECUTE STMT USING @skip, @numrows;
    

    PostgreSQL との互換性に対しては、MySQL はまた LIMIT row_count OFFSET offset 構文もサポートします。

  • SELECTSELECT ... INTO OUTFILE 'file_name' 型は選択された行をファイルに書き込みます。ファイルはサーバ ソフト上に作成されるので、この構文を利用するには FILE 権限を持たなければいけません。 file_name は、/etc/passwd のようなファイルやデータベース テーブルが、その他の物の間で破壊されるのを防ぐ既存ファイルにはなり得ません。MySQL 5.1.6 以降のバージョンでは、character_set_filesystem システム変数は、ファイル名の解明をコントロールします。

    SELECT ... INTO OUTFILE ステートメントはそもそも、サーバ マシン上のテキスト ファイルにテーブルをすばやく捨てさせる事を意図しています。もしサーバ ホストではなく、クライアント ホスト上に結果ファイルを作成したければ、SELECT ... INTO OUTFILE を利用する事はできません。その場合、クライアント ホスト上にファイルを生成する為には、代わりに mysql -e "SELECT ..." > file_name のようなコマンドを利用しなければいけません。

    SELECT ... INTO OUTFILELOAD DATA INFILE の補数です。ステートメントの export_options 部分の構文は、LOAD DATA INFILE ステートメントと共に利用される物と同じ FIELDSLINES 条項で成り立っています。詳しくは 項12.2.5. 「LOAD DATA INFILE 構文」 を参照してください。

    FIELDS ESCAPED BY は、特別な文字をどのように書き込むのかをコントロールします。もし FIELDS ESCAPED BY 文字が空でなければ、それはアウトプット上で次の文字に先行するプリフィックスとして利用されます。

    • FIELDS ESCAPED BY 文字

    • FIELDS [OPTIONALLY] ENCLOSED BY 文字

    • FIELDS TERMINATED BYLINES TERMINATED BY 値の最初の文字

    • ASCII NUL (ゼロの値のバイト;実際に拡張文字の後ろに書かれているのは、ゼロの値のバイトではなく、ASCII ‘0’です。)

    FIELDS TERMINATED BYENCLOSED BYESCAPED BY、または LINES TERMINATED BY 文字は、ファイルを確実に読み返す事ができるように、拡張 されなければいけません。 ASCII NUL は、ポケベルで見やすくする為に拡張されています。

    結果のファイルは SQL 構文と一致する必要がないので、他の物は拡張される必要はありません。

    もし FIELDS ESCAPED BY 文字が空なら、文字が拡張される事はなく、NULL\N ではなく NULL としてアウトプットされます。特に、もしデータ中のにフィールド値が先ほどのリストの中の文字を含んでいる場合は、空の拡張文字を指定するのは良い考えではないかも知れません。

    ここに、多くのプログラムで利用されるカンマで区切られた値(CSV)のフォーマットのファイルを生成する例があります。

    SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
      FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
      LINES TERMINATED BY '\n'
      FROM test_table;
    
  • もし INTO OUTFILE の代わりに INTO DUMPFILE を利用すると、MySQL は、カラムやラインのターミネーションや、拡張操作を行う事無く、ファイルの中に行を1つだけ書き込みます。 これは、もしファイルの中に BLOB 値を格納したいのであれば有効です。

  • INTO 条項は、複数のユーザ定義変数のリストに名前をつける事ができます。選択された値は変数に割り当てられます。変数の数はカラム数と一致しなければいけません。

    ストアド ルーチンの中では、その変数はルーチン パラメータかローカル変数になり得ます。詳しくは 項17.2.7.3. 「SELECT ... INTO ステートメント」 を参照してください。

  • 注意:INTO OUTFILEINTO DUMPFILE によって作成されたファイルは、サーバホスト上で全てのユーザによって書き込まれます。この理由は、MySQL サーバは、それを起動させているアカウントの持ち主であるユーザ以外によって所有されているファイルを作成する事はできない という事です。(これらの理由の為に、mysqldroot として起動する事は絶対にしてはいけません。)ですので、このファイルは内容を真似する事ができるように、誰でも修正ができる物である必要があります。

  • このセクションの最初の SELECT 構文の説明で、ステートメントの終わりの方の INTO 条項が表されています。FROM 条項に先行して、INTO OUTFILEINTO DUMPFILE を直接利用する事も可能です。

  • PROCEDURE 条項は、結果セットの中にデータを処理しなければいけないプロシージャに名前をつけます。(例については、項25.4.1. 「Procedure Analyse」 をご覧ください。)

  • もしページか行ロックを利用するストレージ エンジンと FOR UPDATE を一緒に利用するなら、クエリに検査された行は現在のトランザクションが終わるまで書き込みロックされます。 LOCK IN SHARE MODE を利用すると、他のトランザクションが検査された行を読む事は許容しますが、それらを更新や削除する事は許容しない共通ロックを設定します。詳しくは 項13.5.10.5. 「SELECT ... FOR UPDATESELECT ... LOCK IN SHARE MODE ロック読み取り」 を参照してください。

SELECT キーワードの後で、ステートメントの操作に影響を与える幾つかのオプションを利用する事ができます。

ALLDISTINCT、そして DISTINCTROW オプションは、複製行が返されるべきかどうかを指定します。もしこれらのオプションが何も与えられなければ、デフォルトは ALL です。(全ての一致する行が返されます。)DISTINCTDISTINCTROW は同義語で、結果セットから複製行を削除する指示を出します。

HIGH_PRIORITYSTRAIGHT_JOIN、そして SQL_ で始まるオプションは、スタンダード SQL の MySQL 拡張子です。

  • HIGH_PRIORITYSELECT に、テーブルを更新するステートメントよりも高い優先順位を与えます。これは、スピードがとても速く、一度に実行されなければいけないクエリに対してだけ利用して下さい。読み込みの為にテーブルがロックされている間に発行された SELECT HIGH_PRIORITY クエリは、テーブルがフリーになるのを待っている更新ステートメントがあったとしても実行します。

    HIGH_PRIORITY は、UNION の一部である SELECT ステートメントと一緒には利用できません。

  • STRAIGHT_JOIN は、オプチマイザが FROM 条項内にリストされている順番でテーブルに結合するよう働きかけます。もし最適化ツールが、最適ではない順番でテーブルに接合した時、クエリのスピードを早くする為にこれを利用する事ができます。詳しくは 項6.2.1. 「EXPLAINを使用して、クエリを最適化する」 を参照してください。STRAIGHT_JOIN はまた table_references リストの中でも利用できます。詳しくは 項12.2.7.1. 「JOIN 構文」 を参照してください。

  • SQL_BIG_RESULT は、オプチマイザに結果セットが行を多く持っている事を教える為に GROUP BYDISTINCT と共に利用する事ができます。この場合、MySQL は必要であればディスク ベースのテンポラリ テーブルを直接利用し、GROUP BY 要素上のキーを持つテンポラリ テーブルを利用してソートします。

  • SQL_BUFFER_RESULT は結果がテンポラリ テーブルの中に置かれるよう働きかけます。これは、MySQL がテーブル ロックを早く解除するのを助け、クライアントに結果セットを送るのに時間がかかる場合に補助します。

  • SQL_BIG_RESULT は、オプチマイザに結果セットが小さい事を教える為に GROUP BYDISTINCT と共に利用する事ができます。この場合、MySQL は結果テーブルを格納する為、ソート機能を利用する代わりに高速のテンポラリ テーブルを利用します。通常これは必要ではないでしょう。

  • SQL_CALC_FOUND_ROWS は全ての LIMIT 条項を無視して、結果セットの中にいくつ行があるかを計算するよう MySQL に指示します。 行数は SELECT FOUND_ROWS() を利用して検索する事ができます。詳しくは 項11.10.3. 「情報関数」 を参照してください。

  • 2 or DEMANDquery_cache_type 値を利用している場合、SQL_CACHE は、クエリ キャッシュの中にクエリの結果を格納するよう MySQL に指示します。 このオプションは、UNION かサブクエリを利用するクエリに対して、クエリ中の全ての SELECT に影響を与えます。詳しくは 項4.13. 「MySQL クエリ キャッシュ」 を参照してください。

  • SQL_NO_CACHE は MySQL に対して、クエリ キャッシュ内のクエリの結果を格納しないように指示します。詳しくは 項4.13. 「MySQL クエリ キャッシュ」 を参照してください。UNION かサブクエリを利用するクエリに対して、このオプションはクエリ中の全ての SELECT に影響を与えます。

12.2.7.1. JOIN 構文

MySQL は、SELECT ステートメントの table_references 部分と、複合テーブル DELETEUPDATE ステートメント

に対して、次の JOIN 構文をサポートします。

table_references:
    table_reference [, table_reference] ...

table_reference:
    table_factor
  | join_table

table_factor:
    tbl_name [[AS] alias]
        [{USE|IGNORE|FORCE} INDEX (key_list)]
  | ( table_references )
  | { OJ table_reference LEFT OUTER JOIN table_reference
        ON conditional_expr }

join_table:
    table_reference [INNER | CROSS] JOIN table_factor [join_condition]
  | table_reference STRAIGHT_JOIN table_factor
  | table_reference STRAIGHT_JOIN table_factor ON condition
  | table_reference LEFT [OUTER] JOIN table_reference join_condition
  | table_reference NATURAL [LEFT [OUTER]] JOIN table_factor
  | table_reference RIGHT [OUTER] JOIN table_reference join_condition
  | table_reference NATURAL [RIGHT [OUTER]] JOIN table_factor

join_condition:
    ON conditional_expr
  | USING (column_list)

テーブル参照は、接合式としても知られています。

table_factor の構文は、SQL スタンダードと比較して拡張されます。後者は table_reference だけを許容し、カッコ内のそれらのリストは許容しません。

もし table_reference のリスト内の各カンマが内側の接合と同等であると考えると、これは保守的な拡張子という事になります。例:

SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                 ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

は次の物と同等です:

SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                 ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

MySQL では、CROSS JOININNER JOIN と構文的に同等です。(お互いに置き換える事ができます。)スタンダード SQL では、それらは同等ではありません。INNER JOINON 条項と共に利用され、そうでなければ CROSS JOIN が利用されます。

通常、内側結合演算だけを含む結合式内のカッコは無視する事ができます。MySQL はネスト化した接合をサポートします。(項6.2.10. 「入れ子結合最適化」 を参照してください。)

次のリストには、接合を書く時に考慮に入れる通常の要因が説明されています。

  • テーブル参照では tbl_name AS alias_nametbl_name alias_name を利用してエイリアスを指定する事ができます。

    SELECT t1.name, t2.salary
      FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
    
    SELECT t1.name, t2.salary
      FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
    
  • INNER JOIN, (カンマ)は結合条件がない場合には意味的に同等となります。 両方とも、指示されたテーブルの間にデカルト結果を作り出します。(これは、最初のテーブル内の行1つ1つが、2番目のテーブルの行1つ1つに接合されるという事です。)

    しかし、カンマ演算子の先行は、INNER JOINCROSS JOINLEFT JOIN 等のそれよりも少ないです。もし接合条件がある場合にカンマ接合と別のタイプの接合を混合すると、Unknown column 'col_name' in 'on clause' という形のエラーが発生するかもしれません。この問題の対処法は、このセクションの後半で紹介します。

  • ON 条件文は WHERE 条項の中で利用する事ができる形の条件文です。通常、テーブルをどのように接合するのかを指定する条件には ON 条項を、結果セットの中にどの行が必要であるかを制限するには WHERE 条項を利用する必要があります。

  • もし LEFT JOIN 内の ONUSING 部分内に右側のテーブルに一致する行がなければ、全てのカラムが NULL に設定されている行が右側のテーブルに利用されます。この事実は、別のテーブル内に対応する物を持たないテーブル内の行を見つける為に利用する事ができます。

    SELECT table1.* FROM table1
      LEFT JOIN table2 ON table1.id=table2.id
      WHERE table2.id IS NULL;
    

    この例は、table2 の中に存在しない id 値を持つ table1 内全ての行を見つけます。(table2 内に対応する行を持たない table1 内全ての行)これは、table2.idNOT NULL を宣言したと仮定します。詳しくは 項6.2.9. 「LEFT JOINRIGHT JOIN最適化」 を参照してください。

  • USING(column_list) 条項は、両方のテーブルに存在しなければいけないカラムのリストに名前をつけます。もしテーブル ab の両方がカラム c1c2、そして c3 を含むと、次の接合は二つのテーブルの対応するカラムを比較します。

    a LEFT JOIN b USING (c1,c2,c3)
    
  • 2つのテーブルの NATURAL [LEFT] JOININNER JOIN か、両方のテーブルに存在する全てのカラムに名前を付ける USING 条項を持つ LEFT JOIN と意味的に同等になるよう定義されます。

  • RIGHT JOINLEFT JOIN と同じように機能します。コードがデータベース全体に移植できる状態を保つ為に、RIGHT JOIN の代わりに LEFT JOIN を利用する事をお勧めします。

  • 接合構文の説明で表されている { OJ ... LEFT OUTER JOIN ...} 構文は ODBC を利用した互換性に対してだけ存在します。構文内のカールした中括弧は文字通り書き込まれる必要があります。それらは構文説明の別の部分で利用されているようなメタシンタックスではありません。

  • STRAIGHT_JOIN は、左側のテーブルがいつも右側のテーブルの前に読み込まれるという事以外は JOIN と全く同じです。 これは、接合オプチマイザがテーブルを間違った順番で置いてしまうという(数少ない)場合に利用する事ができます。

接合の例:

SELECT * FROM table1, table2;

SELECT * FROM table1 INNER JOIN table2 ON table1.id=table2.id;

SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id;

SELECT * FROM table1 LEFT JOIN table2 USING (id);

SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id
  LEFT JOIN table3 ON table2.id=table3.id;

テーブルから情報を検索する時、MySQL がどのインデックスを利用するべきか、ヒントを与える事ができます。 USE INDEX (key_list) を指定する事で、MySQL がテーブル内の行を見つける為に、有効なインデックスを1つだけ利用するように指示する事ができます。 既存構文 IGNORE INDEX (key_list) は、MySQL がいくつかの特定のインデックスを利用しないように指示する事ができます。これらのヒントは、MySQL が可能なインデックスのリストの中から、間違ったインデックスを利用している事を、EXPLAIN が表示した時に便利な物です。

テーブル スキャンは とても 高いと仮定されますが、USE INDEX (key_list) のように機能する FORCE INDEX を利用する事もできます。 言い換えると、テーブル内の行を見つける為に与えられたインデックスを利用できない場合、テーブル スキャンを利用する事ができるという事です。

USE INDEXIGNORE INDEX、そして FORCE INDEX は、MySQL がどのようにテーブルの中の行を見つけ、接合を行うのかを決定する時に、どのインデックスが利用されるのかという事にだけ影響を与えます。 それらは、ORDER BYGROUP BY を解決する時にインデックスを利用するかどうかという事に影響を与えます。

USE KEYIGNORE KEY、そして FORCE KEYUSE INDEXIGNORE INDEX、そして FORCE INDEX の同義語です。

例:

SELECT * FROM table1 USE INDEX (key1,key2)
  WHERE key1=1 AND key2=2 AND key3=3;

SELECT * FROM table1 IGNORE INDEX (key3)
  WHERE key1=1 AND key2=2 AND key3=3;

接合処理は MySQL 5.0.12 で変更されました。

注意:自然接合と、外部接合異形を含む USING を利用した接合は、SQL:2003 スタンダードに従って処理されます。その目的は、SQL:2003 に従い NATURAL JOINJOIN ... USING について、MySQL の構文と動作を提携させる事でした。 しかし、接合処理に関してのこれらの変更は、いくつかの接合に関して異なるアウトプット カラムをもたらす可能性があります。また、古いバージョン (5.0.12 以前の物) で正しく機能していたいくつかのクエリも、スタンダードに適合する為に書き直される必要があります。

これらの変更には、主に5つの特徴があります。

  • MySQL が NATURALUSING 接合操作の結果カラムを決定する方法。(従って FROM 条項の結果という事)

  • 選択されたカラムのリストの中への SELECT *SELECT tbl_name.* の拡大。

  • NATURALUSING 接合内でのカラム名の決定。

  • NATURALUSING 接合の JOIN ... ON への変形.

  • JOIN ... ONON 条件内のカラム名の決定。

次のリストに、現在のバージョンと古いバージョンの接合処理の効果について比べた詳細が紹介されています。「以前は」 という言葉は 「MySQL 5.0.12 以前」 という意味です。

  • NATURAL 接合や USING 接合のカラムは以前と異なるかもしれません。特に、余分なアウトプット カラムはもう現れません、そして、SELECT * 拡大のカラムの順番は以前とは異なるかもしれません。

    このステートメントのセットを検討してください。

    CREATE TABLE t1 (i INT, j INT);
    CREATE TABLE t2 (k INT, j INT);
    INSERT INTO t1 VALUES(1,1);
    INSERT INTO t2 VALUES(1,1);
    SELECT * FROM t1 NATURAL JOIN t2;
    SELECT * FROM t1 JOIN t2 USING (j);
    

    以前は、このステートメントはこのアウトプットを産出しました。

    +------+------+------+------+
    | i    | j    | k    | j    |
    +------+------+------+------+
    |    1 |    1 |    1 |    1 |
    +------+------+------+------+
    +------+------+------+------+
    | i    | j    | k    | j    |
    +------+------+------+------+
    |    1 |    1 |    1 |    1 |
    +------+------+------+------+
    

    最初の SELECT ステートメントの中で、カラム j は両方のテーブル内に現れた為に接合カラムになります。という事は、スタンダード SQLによると、それはアウトプット内に2回ではなく1回のみ現れる必要があるという事になります。同じように、2番目の SELECT ステートメントの中で、カラム jUSING 条項の中で名前が付けられ、2回ではなく1回だけアウトプットの中に現れる必要があります。しかし、この両方で余分なカラムは排除されていません。また、スタンダード SQL によると、カラムの順番は正しくありません。

    そして、ステートメントはこのアウトプットを産出します。

    +------+------+------+
    | j    | i    | k    |
    +------+------+------+
    |    1 |    1 |    1 |
    +------+------+------+
    +------+------+------+
    | j    | i    | k    |
    +------+------+------+
    |    1 |    1 |    1 |
    +------+------+------+
    

    余分なカラムは排除され、スタンダード SQL によると、このカラムの順番は正しいです。

    • 最初に、1つ目のテーブルの順番で、2つの接合したテーブルに共通するカラムを合体させました。

    • 次に、テーブルの順番で、最初のテーブル固有のカラムを合体させました。

    • 最後に、テーブルの順番で、2番目のテーブル固有のカラムを合体させました。

    2つの共通カラムを置き換えられる単一結果カラムは、合体操作を通して定義されました。これは、次のステートメントで、t1.at2.a の2つに対して、導き出された1つの接合カラム aa = COALESCE(t1.a, t2.a) として定義される、という事です。

    COALESCE(x, y) = (CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END)
    

    もし接合操作がそれ以外の接合であれば、その接合の結果カラムは、接合されたテーブルの全てのカラムの連続で構成されます。これは以前と同じです。

    外部接合に関する合体したカラム定義の結論は、合体したカラムはもし2つのうち1つのカラムがいつも NULL であれば、非 NULL カラムの値を含む、という事です。もしどちらのカラムも NULL でない、または両方がそうである場合、両方の共通カラムは同じ値を持つので、どちらが合体したカラムの値として選択されるかというのは特に問題にはなりません。これを理解する簡単な方法は、外部接合の合体したカラムは JOIN の内側テーブルの共通カラムによって表される、と考える事です。テーブル t1(a,b)t2(a,c) が次のコンテンツを持つと仮定してください。

    t1    t2
    ----  ----
    1 x   2 z
    2 y   3 w
    

    すると:

    mysql> SELECT * FROM t1 NATURAL LEFT JOIN t2;
    +------+------+------+
    | a    | b    | c    |
    +------+------+------+
    |    1 | x    | NULL |
    |    2 | y    | z    |
    +------+------+------+
    

    ここでは、カラム at1.a の値を含んでいます。

    mysql> SELECT * FROM t1 NATURAL RIGHT JOIN t2;
    +------+------+------+
    | a    | c    | b    |
    +------+------+------+
    |    2 | z    | y    |
    |    3 | w    | NULL |
    +------+------+------+
    

    ここでは、カラム at2.a の値を含んでいます。

    これらの結果を JOIN ... ON を利用した他の同等のクエリと比較してください。

    mysql> SELECT * FROM t1 LEFT JOIN t2 ON (t1.a = t2.a);
    +------+------+------+------+
    | a    | b    | a    | c    |
    +------+------+------+------+
    |    1 | x    | NULL | NULL |
    |    2 | y    |    2 | z    |
    +------+------+------+------+
    
    mysql> SELECT * FROM t1 RIGHT JOIN t2 ON (t1.a = t2.a);
    +------+------+------+------+
    | a    | b    | a    | c    |
    +------+------+------+------+
    |    2 | y    |    2 | z    |
    | NULL | NULL |    3 | w    |
    +------+------+------+------+
    
  • 以前、 USING 条項は、対応するカラムを比較する ON 条項として再度書き込む事ができました。例えば、次の2つの条項は意味的に全く同じでした。

    a LEFT JOIN b USING (c1,c2,c3)
    a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3
    

    今はもうこの2つの条項は同じではありません。

    • どの行が接合条件を満たすかの判断に関しては、両方の接合は意味的に全く同じままです。

    • SELECT * 拡大に対してどのカラムを表示するかの判断に関しては、両方の接合は意味的に全く同じではありません。ON 接合が全てのテーブルから全てのカラムを選択するのに対して、USING 接合は対応するカラムの合体した値を選択します。先行する USING 接合に対しては、SELECT * はこれらの値を選択します。

      COALESCE(a.c1,b.c1), COALESCE(a.c2,b.c2), COALESCE(a.c3,b.c3)
      

      ON 接合に対しては、SELECT * が次の値を選択します。

      a.c1, a.c2, a.c3, b.c1, b.c2, b.c3
      

      内部結合では、両方のカラムが同じ値を持つので COALESCE(a.c1,b.c1)a.c1b.c1 と同じです。外部接合では(LEFT JOIN のような)、2つのうち1つのカラムが NULL になり得ます。そのカラムは結果から排除されます。

    • 多方向自然接合の評価は、NATURALUSING 接合の結果に影響を与え、クエリの再書き込みを必要とするような、大変重要な形で異なっています。それぞれが行を1つ持つ3つのテーブル t1(a,b)t2(c,b)、そして t3(a,c) があると仮定してください。t1(1,2)t2(10,2)、そして t3(7,10) です。また、その3つのテーブル上にこの NATURAL JOIN も持っていると仮定してください。

      SELECT ... FROM t1 NATURAL JOIN t2 NATURAL JOIN t3;
      

      以前は、2つめの接合の左のオペランドは、ネスト化した接合 (t1 NATURAL JOIN t2) とならなければいけない一方、t2 となると考えられていました。 その結果、t3 のカラムは t2 の中だけで共通カラムに関して確認され、そしてもし t3t1 を持つ共通カラムを持っていれば、これらのカラムは等価接合カラムとして利用されません。従って、以前は先行クエリは次の等価接合に変形されていました。

      SELECT ... FROM t1, t2, t3
        WHERE t1.b = t2.b AND t2.c = t3.c;
      

      その接合では、もう1つの等価接合述語 (t1.a = t3.a) がなくなっています。その結果、それはもう1つ行を作成するので、結果は空にはなりません。正しい同等のクエリはこれです。

      SELECT ... FROM t1, t2, t3
        WHERE t1.b = t2.b AND t2.c = t3.c AND t1.a = t3.a;
      

      もし現在の MySQL のバージョンの中で、古いバージョンと同じクエリの結果が必要であれば、自然接合を最初の等価接合として書き換えてください。

    • 以前は、カンマ演算子(,)と JOIN の両方は同じ優先順位だったので、接合式 t1, t2 JOIN t3((t1, t2) JOIN t3) として解釈されました。現在は JOIN が高い優先順位を持つので、式は (t1, (t2 JOIN t3)) として解釈されます。この変更は、ON 条項が接合の演算子内のカラムだけを参照する事ができ、優先順位の変更はそれらの演算子が何であるかについての解釈を変えてしまうので、この条項を利用するステートメントに影響を与えます。

      例:

      CREATE TABLE t1 (i1 INT, j1 INT);
      CREATE TABLE t2 (i2 INT, j2 INT);
      CREATE TABLE t3 (i3 INT, j3 INT);
      INSERT INTO t1 VALUES(1,1);
      INSERT INTO t2 VALUES(1,1);
      INSERT INTO t3 VALUES(1,1);
      SELECT * FROM t1, t2 JOIN t3 ON (t1.i1 = t3.i3);
      

      以前は、(t1,t2) としての t1,t2 の暗黙のグループ分けのおかげで、SELECT は正当でした。現在は JOIN が優先順位を持つので ON 条項の演算子は t2t3 です。t1.i1 がどちらの演算子でもないので、結果は Unknown column 't1.i1' in 'on clause' エラーになります。接合を実行させるには、ON 条項の演算子が (t1,t2)t3 となるように、括弧を利用して最初の2つのテーブルを明示的にグループ分けして下さい。

      SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3);
      

      または、カンマ演算を利用するのを避け、その代わりに JOIN を利用してください。

      SELECT * FROM t1 JOIN t2 JOIN t3 ON (t1.i1 = t3.i3);
      

      この変更は、カンマ演算子とそれよりも高い優先順位を持つ INNER JOINCROSS JOINLEFT JOIN または RIGHT JOIN を混合するステートメントにも適応します。

    • 以前は、ON 条項はその右側で名前が付けられたテーブル内のカラムを参照する事ができました。現在は ON 条項はその演算子だけ参照する事ができます。

      例:

      CREATE TABLE t1 (i1 INT);
      CREATE TABLE t2 (i2 INT);
      CREATE TABLE t3 (i3 INT);
      SELECT * FROM t1 JOIN t2 ON (i1 = i3) JOIN t3;
      

      以前は、SELECT ステートメントは正当でした。現在は、i3 は、ON 条項の演算子ではない t3 内のカラムなので、ステートメントは Unknown column 'i3' in 'on clause' エラーで失敗します。ステートメントは次のように書き換えられなければいけません。

      SELECT * FROM t1 JOIN t2 JOIN t3 ON (i1 = i3);
      
    • NATURALUSING 接合内でのカラム名の決定は、以前とは違います。FROM 条項の外にあるカラム名に対しては、MySQL は以前と比べると上位集合であるクエリを扱います。 それは、以前は MySQL がいくつかのカラムが曖昧であるというエラーを発行したような場合でも、現在はクエリが正確に扱われるという事です。これは、現在は MySQL が NATURALUSING 接合の共通カラムを単一カラムとして扱う為、クエリがそのようなカラムを参照した時、クエリ コンパイラがそれらを曖昧だとは認識しないという事実によるものです。

      例:

      SELECT * FROM t1 NATURAL JOIN t2 WHERE b > 1;
      

      以前は、このクエリは ERROR 1052 (23000) を導いていました。場所条項内の、カラム 'b' が曖昧です。.現在はそのクエリは正しい結果を導きます。

      +------+------+------+
      | b    | c    | y    |
      +------+------+------+
      |    4 |    2 |    3 |
      +------+------+------+
      

      SQL:2003 スタンダードと比較した MySQL の拡張機能の1つは、スタンダードは NATURALUSING 接合(以前のような)の共通(合体した)カラムを修飾する事を許可しなかったのに対して、MySQL はそれを許可するという事です。

12.2.7.2. UNION 構文

SELECT ...
UNION [ALL | DISTINCT] SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]

UNION は、結果を複数 SELECT ステートメントから単一結果セットに結合させる為に利用されます。

最初の SELECT ステートメントからのカラム名は、返された結果のカラム名として利用されます。各 SELECT ステートメントの対応する位置にリストされている選択されたカラムは、同じデータ タイプを持つ必要があります。(例えば、最初のステートメントに選択された最初のカラムは、別のステートメントに選択された最初のカラムと同じタイプを持つ必要があります。)

もし、対応する SELECT カラムのデータ タイプが一致しなければ、UNION 結果内のタイプとカラムの長さは、全ての SELECT ステートメントによって検索された値を考慮する必要があります。例えば、次の物を検討してみてください。

mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10);
+---------------+
| REPEAT('a',1) |
+---------------+
| a             |
| bbbbbbbbbb    |
+---------------+

(MySQL の初期のバージョンでは、最初の SELECT のタイプと長さだけが利用され、2つ目の行は長さ1まで切り捨てられていました。)

SELECT ステートメントは通常の選択ステートメントですが、次の制約があります。

  • 最後の SELECT ステートメントだけが INTO OUTFILE を利用できます。

  • HIGH_PRIORITY は、UNION の一部である SELECT ステートメントと一緒には利用できません。

    もしそれを最初の SELECT に指定しても、効果はありません。もしそれを後に続く SELECT ステートメントに指定すると、構文エラーが起こります。

UNION のデフォルトの動作は、複製行は結果から削除されるという事です。任意の DISTINCT キーワードは、複製行の削除の指定もするので、デフォルト以外に何も効果は持ちません。任意の ALL キーワードを利用すると、複製行の削除は行われず、結果には全ての SELECT ステートメントからの一致する行が含まれます。

UNION ALLUNION DISTINCT を同じクエリの中で混合する事ができます。混合された UNION タイプは DISTINCT ユニオンが全ての ALL ユニオンをその左側に上乗せするような形で扱われます。DISTINCT ユニオンは UNION DISTINCT を利用して明示的に、また後に DISTINCTALL キーワードがない UNION を利用して暗黙的に作成されます。

ORDER BYLIMIT 条項を、UNION 結果全体をソートしたり制限したりする為に利用するには、各 SELECT ステートメントを括弧で囲み、最後の物の後に ORDER BYLIMIT を置いて下さい。次の例は、両方の条項を利用しています。

(SELECT a FROM t1 WHERE a=10 AND B=1)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2)
ORDER BY a LIMIT 10;

この種の ORDER BY はテーブル名を含むカラム参照を利用する事ができません。(それは、tbl_name.col_name フォーマット内の名前です。)その代わりに、最初の SELECT ステートメント内でカラム エイリアスを提供し、ORDER BY 内でそのエイリアスを参照します。(あるいは、そのカラムの位置を利用して ORDER BY 内でカラムを参照します。しかし、カラム位置の使用は今後廃止予定です。)

また、もし格納されるカラムがエイリアスされると、ORDER BY 条項は、カラム名ではなく、そのエイリアスを参照 しなければいけません。次のステートメントの1つ目の物は機能しますが、2つ目は Unknown column 'a' in 'order clause' エラーで失敗します。

(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY b;
(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY a;

個々の SELECTORDER BYLIMIT を適用するには、SELECT を囲む括弧内に条項を置いて下さい。

(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);

デフォルトの UNION が不規則な順番の行セットを作り出す為、個々の SELECT ステートメントへの ORDER BY の利用は、最終結果の中で行がどのような順番で現れるのかを暗示しません。もし ORDER BYLIMIT と共に現れると、検索の為に選択された行のサブセットを SELECT に決定する為に利用されますが、それは最終的な UNION の結果内の行の順番に影響を与えるとは限りません。もし ORDER BYSELECT 内に LIMIT 無しで現れても、何の効果も持たない為最適化されて切り離されます。

UNION の結果内の行が、各 SELECT によって1つずつ検索された行で構成されるようにする為には、各 SELECT からソート カラムとして利用する為の追加カラムを選択し、最後の SELECT の後に ORDER BY を追加してください。

(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col;

さらに、個々の SELECT の結果の中でソートの順番を維持する為には、ORDER BY 条項に補助的なカラムを追加してください。

(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col, col1a;

12.2.8. サブクエリ構文

サブクエリは、別のステートメント内の SELECT ステートメントです。

MySQL 4.1 から、MySQL 特有のいくつかの特徴と同様に、SQL スタンダードが要求する全てのサブクエリ型と演算子がサポートされています。

ここに、同じようなサブクエリの例があります。

SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);

この例の中では、SELECT * FROM t1 ...外部クエリ (または 外部ステートメント)であり、(SELECT column1 FROM t2)サブクエリ です。これは、サブクエリが外部クエリ内で ネスト化された という事であり、実際、サブクエリを別のサブクエリ内で、相当な深さまでネスト化する事が可能です。サブクエリは必ずカッコ内に表示されなければいけません。

サブクエリの主な利点は次のような物になります。

  • それらは、ステートメントのそれぞれの部分を分離させる事ができるように、構造化された クエリを許容します。

  • それらは、複雑な接合や合併を要求されないように、演算を行う為の代替法を提供します。

  • 多くの人の意見によると、それらは複雑な接合や合併と比べると、読み込みやすいという事です。実際これは、初期 SQL の 「Structured Query Language.」 の創案を人々に与えたサブクエリの発明でした。

ここに、SQL スタンダードによって指定され、MySQL 内でサポートされているサブクエリ構文に関する主なポイントを説明するステートメントの例があります。

DELETE FROM t1
WHERE s11 > ANY
(SELECT COUNT(*) /* no hint */ FROM t2
WHERE NOT EXISTS
(SELECT * FROM t3
WHERE ROW(5*t2.s1,77)=
(SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM
(SELECT * FROM t5) AS t5)));

サブクエリは、スカラ(単一値)、単一行、単一カラム、またはテーブル(1つ、または複数カラムの、1つ、または複数行) を返す事ができます。これらはスカラ、カラム、行、そしてテーブル サブクエリと呼ばれます。次のセクションで説明されているように、頻繁に特定の種類の結果を返すサブクエリは、特定のコンテキストの中だけで利用する事ができます。

サブクエリを利用する事ができるステートメントのタイプには、いくつかの制限があります。サブクエリは、普通の SELECT が含む事のできるキーワードや条項を全て含む事ができます。それは DISTINCTGROUP BYORDER BYLIMIT、接合、インデックスヒント、UNION 構成、コメント、関数などです。

制限の1つは、サブクエリの外部ステートメントが SELECTINSERTUPDATEDELETESET、または DO のうちのどれか1つでなければいけないという事です。その他の制限は、現在はサブクエリの中でテーブルを変更したり、同じテーブルから選択する事ができないという事です。これは、DELETEINSERTREPLACEUPDATE、そして(サブクエリは SET 条項内で利用できる為) LOAD DATA INFILE のようなステートメントに適応します。

サブクエリ構文の特定型に関する性能問題を含む、サブクエリ利用に関する制限のさらなる総合的な説明に関しては、 項D.3. 「サブクエリの規制」 で紹介されています。

12.2.8.1. スカラ演算子としてのサブクエリ

簡単に言うと、サブクエリは単一値を戻すスカラ サブクエリという事になります。スカラ サブクエリは単純な演算子で、単一カラム値や直定数が正当であればほとんどどこでも利用する事ができ、データ タイプ、長さ、 NULL になり得るかどうかという指示など、全ての演算子が持つ特徴も全て持っています。ここにその例があります。

CREATE TABLE t1 (s1 INT, s2 CHAR(5) NOT NULL);
INSERT INTO t1 VALUES(100, 'abcde');
SELECT (SELECT s2 FROM t1);

この SELECT 内のサブクエリは、CHAR のデータ タイプを持ち、長さが5で、CREATE TABLE 時にデフォルトと同等の文字セットと照合が実施されており、そしてカラム内の値が NULL になり得るという指示を持つ単一値('abcde')を返します。実際は、ほとんどのサブクエリが NULL になり得ます。もし例で使用されたテーブルが空であれば、サブクエリの値は NULL になるでしょう。

スカラ サブクエリを利用できないコンテキストがいくつかあります。もしステートメントが直定数値だけを許容するなら、サブクエリを利用する事はできません。例えば、LIMIT が直定整数引数を要求し、LOAD DATA INFILE が直定数文字列ファイル名を要求します。これらの値を供給するのにサブクエリを利用する事はできません。

次のセクションにある、より質素な構造を含む (SELECT column1 FROM t1) の例を見る時、自分自身のコードが、それよりもさらに多様で、複雑な構造を含んでいると想像してください。

2つテーブルを作成すると仮定します。

CREATE TABLE t1 (s1 INT);
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (s1 INT);
INSERT INTO t2 VALUES (2);

次に、SELECT を実行します。

SELECT (SELECT s1 FROM t2) FROM t1;

2 の値を持つカラム s1 を含む行が t2 にあるので、その結果は 2 となります。

スカラ サブクエリは式の一部になり得ますが、もしそのサブクエリが関数に引数を与える演算子だとしても、括弧を忘れないでください。 例:

SELECT UPPER((SELECT s1 FROM t1)) FROM t2;

12.2.8.2. サブクエリを利用した比較

サブクエリの最もよく利用される方法はこの形の中にあります。

non_subquery_operand comparison_operator (subquery)

comparison_operator がこれらの演算子の1つであるところではこうです。

=  >  <  >=  <=  <>

例:

  ... 'a' = (SELECT column1 FROM t1)

かつては、サブクエリが正当であるたった1つの場所は比較の右側でしたし、いまだにいくつかの古い DBMS がこれを主張しています。

ここに、接合と共に実行できない共通形サブクエリ比較の例があります。これは、テーブル t2 の最大値と同等の、テーブル t1 内の全ての値を検出します。

SELECT column1 FROM t1
WHERE column1 = (SELECT MAX(column2) FROM t2);

ここに、テーブルの1つに対する凝集を含む為、接合と共に利用する事ができないもうひとつの例があります。これは、与えられたカラムの中で2回現れる値を含む、テーブル t1 の中の全ての行を検出します。

SELECT * FROM t1 AS t
WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);

これらの演算子の1つを利用して実行された比較には、= は行サブクエリと共に利用できるという例外がありますが、サブクエリはスカラを返さなければいけません。詳しくは 項12.2.8.5. 「行サブクエリ」 を参照してください。

12.2.8.3. ANYIN、そして SOME を持つサブクエリ

構文:

operand comparison_operator ANY (subquery)
operand IN (subquery)
operand comparison_operator SOME (subquery)

比較演算子の後に続かなければいけない ANY キーワードは、「もしサブクエリが返すカラム内の値の ANY に対する比較が TRUE であれば、TRUE を返す」 という事を意味します。例:

SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2);

テーブル (10) を含むテーブル t1 内に行があると仮定してください。10 以下である値 7t2 の中にあるので、もしテーブル t2(21,14,7) を含むなら、その式は TRUE です。もしテーブル t2(20,10) を含むか、テーブル t2 が空であれば、その式は FALSE です。もしテーブル t2(NULL,NULL,NULL) を含むなら、その式は UNKNOWN です。

サブクエリと共に利用される時、IN という言葉は = ANY のエイリアスとなります。従って、これら2つのステートメントは同じになります。

SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 IN    (SELECT s1 FROM t2);

式のリストと共に利用される時、IN= ANY は同義語ではありません。IN は式のリストを取る事ができますが、= ANY はできません。詳しくは 項11.1.3. 「比較関数と演算子」 を参照してください。

NOT IN<> ANY のエイリアスではありませんが、<> ALL のエイリアスです。詳しくは 項12.2.8.4. 「ALL を持つサブクエリ」 を参照してください。

SOME という言葉は ANY のエイリアスです。従って、これら2つのステートメントは同じになります。

SELECT s1 FROM t1 WHERE s1 <> ANY  (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2);

SOME が利用される事はほとんどありませんが、なぜこれが役に立つのか、この例が表しています。通常、英語で 「a はどの b とも同等ではない」 と言うと、「 a と等しい b は無い」 と解釈されますが、SQL 構文ではそのような意味ではないのです。その構文は、「a と同等ではない b がいくつかある」 と意味します。<> SOME を代わりに利用すると、そのクエリが本当に意味している事を全員がきちんと理解する助けになります。

12.2.8.4. ALL を持つサブクエリ

構文:

operand comparison_operator ALL (subquery)

比較演算子の後に続かなければいけない ALL という言葉は、「もしサブクエリが返すカラム内の値の ALL に対する比較が TRUE であれば、TRUE を返す」 という事を意味します。例:

SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2);

テーブル (10) を含むテーブル t1 内に行があると仮定してください。10t2 の中の3つの値全てよりも大きいので、もし t2(-5,0,+5) を含むなら、その式は TRUE です。10 よりも大きい単一値 12 がテーブル t2 にあるので、もしテーブル t2(12,6,NULL,-100) を含むなら、その式は FALSE です。もしテーブル t2(0,NULL,1) を含むなら、その式は 不明 (NULL) です。

最後に、もしテーブル t2 が空なら、その結果は TRUE です。従って、テーブル t2 の時、次のステートメントは TRUE です。

SELECT * FROM t1 WHERE 1 > ALL (SELECT s1 FROM t2);

しかし、テーブル t2 が空の時、このステートメントは NULL です。

SELECT * FROM t1 WHERE 1 > (SELECT s1 FROM t2);

そして、テーブル t2 が空の時、次のステートメントは NULL です。

SELECT * FROM t1 WHERE 1 > ALL (SELECT MAX(s1) FROM t2);

通常、NULL 値を含むテーブル空のテーブル は 「 エッジ ケースです。」サブクエリ コードを書き込む時、必ずそれら2つの可能性を考慮したかどうか、確認してください。

NOT IN<> ALL のエイリアスです。従って、これら2つのステートメントは同じになります。

SELECT s1 FROM t1 WHERE s1 <> ALL (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 NOT IN (SELECT s1 FROM t2);

12.2.8.5. 行サブクエリ

この時点までの話は、単一値や値のカラムを返すサブクエリなどのような、スカラやカラム サブクエリに関しての物でした。行サブクエリ は単列を戻し、ひいては複数のカラム値を返す事ができるサブクエリ異型です。ここに2つ例があります。

SELECT * FROM t1 WHERE (1,2) = (SELECT column1, column2 FROM t2);
SELECT * FROM t1 WHERE ROW(1,2) = (SELECT column1, column2 FROM t2);

もしテーブル t2column1 = 1column2 = 2 の場所に行を持っていれば、ここにあるクエリは両方 TRUE です。

(1,2)ROW(1,2) は時々 row constructors と呼ばれます。それら2つは同等の物です。それらは、別のコンテキストの中でも正当です。例えば、次の2つのステートメントは意味的に同等です。(1つ目は MySQL 5.1.12 まで最適化する事ができませんが)

  SELECT * FROM t1 WHERE (column1,column2) = (1,1);
  SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;

行コンストラクタは通常、2つ以上のカラムを返すサブクエリを持つ比較に対して利用します。例えば、次のクエリは要求に答え、「テーブル t2 にも存在する テーブル t1 内の全ての行を検出します。

SELECT column1,column2,column3
FROM t1
WHERE (column1,column2,column3) IN
(SELECT column1,column2,column3 FROM t2);

12.2.8.6. EXISTSNOT EXISTS

もしサブクエリが行を返せば、EXISTS subqueryTRUE で、NOT EXISTS subqueryFALSE です。例:

SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);

もともと、EXISTS サブクエリは SELECT * で開始しますが、SELECT 5SELECT column1、またそれ以外のどんな物でも開始する事ができます。MySQL はそのようなサブクエリの中では SELECT リストを無視するので、何も変わらないのです。

先ほどの例では、もし t2NULL 値しか含まない物でも良いので、何かの行を含むのなら、EXISTS の条件は TRUE となります。[NOT] EXISTS サブクエリは通常相互関係を持つので、実際はこれはよくあるような例ではありません。ここに、もう少し現実的な例があります。

  • 複数の町には、どんな種類のお店がありますか?

    SELECT DISTINCT store_type FROM stores
      WHERE EXISTS (SELECT * FROM cities_stores
                    WHERE cities_stores.store_type = stores.store_type);
    
  • 町ではないところには、どんな種類のお店がありますか?

    SELECT DISTINCT store_type FROM stores
      WHERE NOT EXISTS (SELECT * FROM cities_stores
                        WHERE cities_stores.store_type = stores.store_type);
    
  • 全ての町には、どんな種類のお店がありますか?

    SELECT DISTINCT store_type FROM stores s1
      WHERE NOT EXISTS (
        SELECT * FROM cities WHERE NOT EXISTS (
          SELECT * FROM cities_stores
           WHERE cities_stores.city = cities.city
           AND cities_stores.store_type = stores.store_type));
    

最後の例は、二重にネスト化された NOT EXISTS クエリです。それは、NOT EXISTS 条項の中に NOT EXISTS 条項を持っている、という事です。これは、正式に次の質問 「Stores にはないお店がある町は存在しますか」? という質問に答えます。しかし、ネスト化した NOT EXISTS が、次の質問 「x は全ての yTRUE ですか?」 に答える、と言う方が簡単です。

12.2.8.7. 相関サブクエリ

相関サブクエリ は、外部クエリ内にも現れるテーブルの参照を含むサブクエリです。例:

SELECT * FROM t1 WHERE column1 = ANY
(SELECT column1 FROM t2 WHERE t2.column2 = t1.column2);

サブクエリの FROM 条項がテーブル t1 に言及しなくても、サブクエリは t1 のカラムへの参照を含むという事を覚えておいて下さい。ですので、MySQL はサブクエリの外側を見て、外部クエリ内の t1 を見付けます。

テーブル t1column1 = 5column2 = 6 の場所で行を含み、一方、 テーブル t2column1 = 5column2 = 7 の場所で行を含むと仮定してください。単純な式 ... WHERE column1 = ANY (SELECT column1 FROM t2)TRUE となるでしょうが、例の中では、サブクエリ内の WHERE 条項は FALSE ですので、((5,6)(5,7) と同等ではない為) このサブクエリ全体としては FALSE です。

スコープ ルール: MySQL は内側から外側まで評価します。例:

SELECT column1 FROM t1 AS x
WHERE x.column1 = (SELECT column1 FROM t2 AS x
WHERE x.column1 = (SELECT column1 FROM t3
WHERE x.column2 = t3.column1));

このステートメントの中では、SELECT column1 FROM t2 AS x ...t2 をリネームするので、x.column2 はテーブル t2 内のカラムでなければいけません。SELECT column1 FROM t1 ...とても遠くにある 外部クエリなので、これはテーブル t1 内のカラムではありません。

HAVINGORDER BY 条項内のサブクエリに対しては、MySQL は外部選択リストからもカラム名を探します。

特定の場合には、相関サブクエリは最適化されます。例:

val IN (SELECT key_val FROM tbl_name WHERE correlated_condition)

そうでなければ、それらは役に立たず、スピードも遅くなりがちです。クエリを接合として書き換える事で、性能を向上させる事ができるかもしれません。

相関サブクエリは、外部クエリからの総計関数の結果を参照する事ができません。

12.2.8.8. FROM 条項内のサブクエリ

サブクエリは SELECT ステートメントの FROM 条項内で正当です。実際の構文はこれです。

SELECT ... FROM (subquery) [AS] name ...

[AS] name 条項は強制なので、FROM 条項内の全てのテーブルは名前を持つ必要があります。subquery 選択リスト内の全てのカラムは固有の名前を持たなければいけません。このマニュアルの中で 「派生テーブル」 という言葉が利用されている他の場所で、この構文の説明を見付ける事ができます。

説明する為に、このテーブルを持っていると仮定してください。

CREATE TABLE t1 (s1 INT, s2 CHAR(5), s3 FLOAT);

ここに、この例のテーブルを利用して、FROM 条項の中でサブクエリを利用する方法の説明があります。

INSERT INTO t1 VALUES (1,'1',1.0);
INSERT INTO t1 VALUES (2,'2',2.0);
SELECT sb1,sb2,sb3
FROM (SELECT s1 AS sb1, s2 AS sb2, s3*2 AS sb3 FROM t1) AS sb
WHERE sb1 > 1;

結果: 2, '2', 4.0.

ここに別の例があります。グループ分けされたテーブルの、合計セットの平均を知りたいと仮定します。これは機能しません。

SELECT AVG(SUM(column1)) FROM t1 GROUP BY column1;

しかし、このクエリは要求された情報を提供します。

SELECT AVG(sum_column1)
FROM (SELECT SUM(column1) AS sum_column1
FROM t1 GROUP BY column1) AS t1;

サブクエリの中で利用されたカラム名(sum_column1) が外部クエリの中で認められている事に注意してください。

FROM 条項内のサブクエリは、スカラ、カラム、行、そしてテーブルを返す事ができます。FROM 条項内のサブクエリは、JOIN 演算の ON 条項内で利用されない限り、相関サブクエリになる事ができません。

FROM 条項内のサブクエリは、EXPLAIN ステートメント(派生テンポラリ テーブルが作られた) に対しても実行する事ができます。これは、上位レベルクエリが最適化の段階で全てのテーブルの情報を必要とする為に起こります。

12.2.8.9. サブクエリ エラー

これらはサブクエリにだけ適応するエラーです。このセクションでは、それらについて説明していきます。

  • サポートされていないサブクエリ構文

    ERROR 1235 (ER_NOT_SUPPORTED_YET)
    SQLSTATE = 42000
    Message = "This version of MySQL does not yet support
    'LIMIT & IN/ALL/ANY/SOME subquery'"
    

    これは、次の形のステートメントはまだ機能しないと言う意味です。

    SELECT * FROM t1 WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1)
    
  • サブクエリからの不正カラム数

    ERROR 1241 (ER_OPERAND_COL)
    SQLSTATE = 21000
    Message = "Operand should contain 1 column(s)"
    

    このエラーは、このような場合に起こります。

    SELECT (SELECT column1, column2 FROM t2) FROM t1;
    

    もし比較する事が目的であれば、複合カラムを帰すサブクエリを利用すると良いでしょう。詳しくは 項12.2.8.5. 「行サブクエリ」 を参照してください。しかし、別のコンテキスト内では、サブクエリはスカラ演算子でなければいけません。

  • サブクエリからの不正行数

    ERROR 1242 (ER_SUBSELECT_NO_1_ROW)
    SQLSTATE = 21000
    Message = "Subquery returns more than 1 row"
    

    このエラーは、サブクエリが複数の行を返すステートメントで起こります。次の例を考えてみて下さい。

    SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
    

    もし SELECT column1 FROM t2 が行を1つだけ返せば、その前のクエリは機能します。もしサブクエリが複数の行を返せば、エラー 1242が起きます。その場合、クエリは次のように書き直されなければいけません。

    SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2);
    
  • サブクエリ内の不正使用されたテーブル

    Error 1093 (ER_UPDATE_TABLE_USED)
    SQLSTATE = HY000
    Message = "You can't specify target table 'x'
    for update in FROM clause"
    

    このエラーは次のような場合に起きます。

    UPDATE t1 SET column2 = (SELECT MAX(column1) FROM t1);
    

    サブクエリは、SELECT ステートメント同様 UPDATEDELETE ステートメント内で正当なので、UPDATE ステートメント内で、割り当ての為にサブクエリを利用する事ができます。しかし、同じテーブルを(この場合、テーブル t1)サブクエリの FROM 条項と更新ターゲットの両方に対して利用する事はできません。

トランザクション ストレージ エンジンに対しては、サブクエリの失敗は、ステートメント全体の失敗を引き起こします。非トランザクション ストレージ エンジンに対しては、エラーが起こる前に行われたデータ修正が保持されます。

12.2.8.10. 最適化サブクエリ

開発が進行中なので、最適化についての情報は長期的に信頼性があります。次のリストは、利用してみたいいくつかの興味深いトリックを紹介しています。

  • サブクエリ内の行数や行の順番に影響を与えるサブクエリ条項を利用してください。例:

    SELECT * FROM t1 WHERE t1.column1 IN
    (SELECT column1 FROM t2 ORDER BY column1);
    SELECT * FROM t1 WHERE t1.column1 IN
    (SELECT DISTINCT column1 FROM t2);
    SELECT * FROM t1 WHERE EXISTS
    (SELECT * FROM t2 LIMIT 1);
    
  • サブクエリと接合を置き換えてください。例えば、次の例を

    SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN (
    SELECT column1 FROM t2);
    

    この次の物と置き換えます。

    SELECT DISTINCT t1.column1 FROM t1, t2
    WHERE t1.column1 = t2.column1;
    
  • サブクエリをサポートしない古いバージョンの MySQL の互換性で、いくつかのサブクエリは接合に変形する事ができます。しかし、いくつかの場合で、サブクエリを接合に変換する事で性能を向上させる事ができます。詳しくは 項12.2.8.11. 「MySQL 初期バージョンにおいて、サブクエリの接合としての書き換え」 を参照してください。

  • 条項をサブクエリの外から中に移動させて下さい。例えば、次の例を

    SELECT * FROM t1
    WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);
    

    この次のクエリの代わりに利用します。

    SELECT * FROM t1
    WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);
    

    別の例として、このクエリを、

    SELECT (SELECT column1 + 5 FROM t1) FROM t2;
    

    この次のクエリの代わりに利用します。

    SELECT (SELECT column1 FROM t1) + 5 FROM t2;
    
  • 相関サブクエリの代わりに行サブクエリを利用してください。例えば、次の例を

    SELECT * FROM t1
    WHERE (column1,column2) IN (SELECT column1,column2 FROM t2);
    

    この次のクエリの代わりに利用します。

    SELECT * FROM t1
    WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1
    AND t2.column2=t1.column2);
    
  • a <> ALL (...) ではなく NOT (a = ANY (...)) を利用してください。

  • x=1 OR x=2 ではなく x = ANY (table containing (1,2)) を利用してください。

  • EXISTS ではなく = ANY を利用してください。

  • 必ず1つの行を返す相関サブクエリに対しては、IN は必ず = よりも遅いです。例えば、次の例を

    SELECT * FROM t1 WHERE t1.col_name
    = (SELECT a FROM t2 WHERE b = some_const);
    

    この次のクエリの代わりに利用します。

    SELECT * FROM t1 WHERE t1.col_name
    IN (SELECT a FROM t2 WHERE b = some_const);
    

これらのトリックは、プログラムを早くしたり、遅くしたりする可能性があります。BENCHMARK() 関数のような MySQL 機能を利用すると、今の状況を改善する為のアイデアを見付ける事ができます。詳しくは 項11.10.3. 「情報関数」 を参照してください。

MySQL 自体が行う最適化のいくつかは次のような物です。

  • MySQL は非相関サブクエリを一度だけ実行します。EXPLAIN を利用して、与えられたサブクエリが本当に非相関であるかどうかを確認してください。

  • MySQL は、サブクエリ中の選択リスト カラムがインデックスされる可能性の利点を利用する為に INALLANY、そして SOME サブクエリを書き換えます。

  • MySQL は、EXPLAIN が特別な接合タイプ(unique_subquery または index_subquery)として表現する、インデックス検索機能を利用した次の形のサブクエリを置き換えます。

    ... IN (SELECT indexed_column FROM single_table ...)
    
  • MySQL は、NULL 値か空のセットが関連していない限り、MIN() または MAX() を含む式を利用した次の形の式を強化します。

    value {ALL|ANY|SOME} {> | < | >= | <=} (non-correlated subquery)
    

    例えば、次の WHERE 条項ですが、

    WHERE 5 > ALL (SELECT x FROM t)
    

    オプチマイザによってこのように扱われるでしょう。

    WHERE 5 > (SELECT MAX(x) FROM t)
    

MySQL がどのようにサブクエリを変形させるか」 というタイトルの章が、MySQL 内部マニュアルの http://dev.mysql.com/doc/ で参照可能です。

12.2.8.11. MySQL 初期バージョンにおいて、サブクエリの接合としての書き換え

MySQL の初期バージョンでは(MySQL 4.1以前)、INSERT ... SELECT ...REPLACE ... SELECT ... の形のネスト化されたクエリだけがサポートされていました。MySQL 5.1 ではそうでないとしても、値のセットの中でメンバーシップをテストする別の方法があるという事も事実です。また、場合によっては、クエリをサブクエリ無しで再書き込みする事だけでなく、先ほどの別のテクニックを利用した方がより効果的であるというのも事実です。その1つが IN() コンストラクトです。

例えば、次の例は

SELECT * FROM t1 WHERE id IN (SELECT id FROM t2);

次のように書き換えられます。

SELECT DISTINCT t1.* FROM t1, t2 WHERE t1.id=t2.id;

次のようなクエリは、

SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2);
SELECT * FROM t1 WHERE NOT EXISTS (SELECT id FROM t2 WHERE t1.id=t2.id);

IN() を利用して次のように書き換えられます。

SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id
WHERE table2.id IS NULL;

サーバの方が上手最適化する事ができるかもしれないので、? MySQL サーバだけに特有であるというわけではない、LEFT [OUTER] JOIN はそれに同等のサブクエリよりも早いかもしれません。 SQL-92 以前は外部接合が存在しなかったので、特定の作業をする為には、サブクエリが唯一の方法でした。現在は、MySQL サーバやその他のデータベース システムが様々なタイプの外部接合を提供しています。

MySQL サーバは、1つのテーブル、または複数のテーブルから一度に出される情報に基づき、行を効果的に削除する為に利用する事ができる複合テーブル DELETE ステートメントをサポートします。複合テーブル UPDATE ステートメントもまたサポートされています。

12.2.9. TRUNCATE 構文

TRUNCATE [TABLE] tbl_name

TRUNCATE TABLE はテーブルを完全に空にします。論理的には、これは全ての行を削除する DELETE ステートメントと同等ですが、いくつかの条件下では、違いがあります。

もしテーブルを参照する外部キー制約があれば、InnoDB テーブルに対しては、TRUNCATE TABLEDELETE にマップされ、そうでなければ、高速切断(テーブルのドロップと再作成)が利用されます。外部キー制約の有無に関わらず、AUTO_INCREMENT カウンタが TRUNCATE TABLE によってリセットされます。

その他のストレージ エンジンに対しては、MySQL 5.1 の中では次のような方法で、TRUNCATE TABLEDELETE が異なっています。

  • 切り捨て操作は、テーブルをドロップ、再作成します。それは、行を1つ1つ削除するよりも処理が速くできます。

  • 切り捨て操作はトランザクション セーフではありませんので、実行中のトランザクションやテーブル ロックの途中で行おうとするとエラーが発生します。

  • 削除された行数は返されません。

  • テーブル フォーマット ファイル tbl_name.frm が有効である限り、データやインデックス ファイルが破損しても、テーブルは TRUNCATE TABLE を利用して空のテーブルとして再作成する事ができます。

  • テーブル ハンドラは最後に利用された AUTO_INCREMENT 値を記憶していませんが、また最初から数えます。通常はシーケンス値を再利用しない MyISAMInnoDB にも同じ事が言えます。

  • パーティション テーブルと共に利用される時には、 TRUNCATE TABLE はその分割を保管します。それは、パーティション定義(.par)ファイルは影響を受けませんが、データとインデックス ファイルはドロップされ、再作成されるという意味です。

  • テーブルの切捨てが DELETE を利用しない為、TRUNCATE ステートメントは ON DELETE トリガを呼び出しません。

TRUNCATE TABLE は、MySQL 5.1.16 以降から DROP 権限を必要とします。(5.1.16 以前では DELETE 権限を必要としています。

TRUNCATE TABLE は MySQL に導入されたオラクル SQL 拡張子です。

12.2.10. UPDATE 構文

単一テーブル構文:

UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
    SET col_name1=expr1 [, col_name2=expr2 ...]
    [WHERE where_condition]
    [ORDER BY ...]
    [LIMIT row_count]

複合テーブル構文:

UPDATE [LOW_PRIORITY] [IGNORE] table_references
    SET col_name1=expr1 [, col_name2=expr2 ...]
    [WHERE where_condition]

単一テーブル構文には、UPDATE ステートメントは新しい値を利用して tbl_name 内に既存行のカラムを更新します。SET 条項は、どのカラムを変更し、それらにはどの値が与えられるべきかという事を指示します。もし WHERE 条項が与えられたら、それはどの行を更新するべきかを決定します。WHERE 条項が無ければ、全ての行が更新されます。もし ORDER BY 条項が指定されると、指定された順に行が更新されます。LIMIT 条項は、更新できる行数に制限を設定します。

複合テーブル構文には、UPDATE が、条件を満たす table_references で名づけられたそれぞれのテーブルの行を更新します。この場合、ORDER BYLIMIT を利用する事はできません。

where_condition は更新される各行に対して正しい結果の式です。それは 項12.2.7. 「SELECT 構文」 で述べられている通りに指定されます。

UPDATE ステートメントは次の修飾因子をサポートします。

  • もし LOW_PRIORITY キーワードを利用すると、別のクライアントがテーブルからの読み込みをしなくなるまで、UPDATE の実行が遅れます。

  • もし IGNORE キーワードを利用すると、更新中にエラーが発生しても更新ステートメントは異常終了しません。複製キーの矛盾が起きた行は更新されません。データ変換エラーを起こす値にカラムが更新された行は、代わりに一番近い有効値に更新されます。

もし式の中で tbl_name からカラムにアクセスするなら、UPDATE はカラムの現在の値を利用します。例えば、次のステートメントは age カラムを現在の値よりも1大きく設定します。

UPDATE persondata SET age=age+1;

単一テーブル UPDATE 割り当ては通常左から右に評価されます。複合テーブルの更新に関しては、割り当てが特定の順番で行われるという保証はありません。

もし現在カラムが持つ値に設定するなら、MySQL はそれに気づくので更新はしません。

NULL に設定する事で NOT NULL を宣言されたカラムを更新すると、カラムはそのデータ タイプに適切なデフォルト値に設定され、警告カウントはインクリメントされます。数値タイプ、文字列タイプの空の文字列('')、そして日付と時刻タイプの「ゼロ」 値のデフォルト値は 0 です。

UPDATE は実際に変更された行数を返します。mysql_info() C API 関数は、一致し更新された行数と、UPDATE の最中に起きた警告数を返します。

UPDATE の領域を制限する為に LIMIT row_count を利用する事ができます。LIMIT 条項は行に一致した制限です。ステートメントは、実際に変更されたかどうかに関わらず、WHERE 条項の条件を満たす row_count 行を見付けるとすぐに止まります。

もし UPDATE ステートメントが ORDER BY 条項を含むなら、行は条項に指示された順番で更新されます。これは、エラーが起こるかもしれない特定の場合に有効です。テーブル t が固有インデックスを持つカラム id を含むと仮定してください。次のステートメントは、行が更新される順番によって、複製キー エラーとなり失敗するかもしれません。

UPDATE t SET id = id + 1;

例えば、もしテーブルが id カラム内に1と2を含み、2が3に更新される前に1が2に更新されると、エラーが起きます。 この問題を防ぐには、大きい id 値を持つ行が、小さい値を持つ行よりも先に更新されるように ORDER BY 条項を追加してください。

UPDATE t SET id = id + 1 ORDER BY id DESC;

複合テーブルをカバーする UPDATE 演算を行う事もできます。.しかし、複合テーブル UPDATE と共に ORDER BYLIMIT を利用する事はできません。table_references 条項は接合箇所に含まれるテーブルをリストします。その構文は 項12.2.7.1. 「JOIN 構文」 で説明されています。ここに1つ例があります。

UPDATE items,month SET items.price=month.price
WHERE items.id=month.id;

前出の例はカンマ演算子を利用する内部接合を表しますが、複合テーブルの UPDATE ステートメントは、LEFT JOIN のような、SELECT ステートメント内で許容される接合タイプを利用する事ができます。

実際に更新された複合テーブル UPDATE の中で参照されたカラムに対してだけ、UPDATE 権限が必要です。読み込みはされても、変更はされないカラムには、SELECT 権限だけが必要です。

外部キー制限があるテーブルに InnoDB テーブルを含む複合テーブル UPDATE ステートメントを利用すると、MySQL のオプチマイザは、それらの親子関係の順番と違う順番でテーブルを処理するかもしれません。この場合、ステートメントは失敗し、ロールバックされます。代わりに、単一テーブルを更新し、他のテーブルが適宜修正されるように InnoDB が働きかける ON UPDATE 性能に頼ってください。

詳しくは 項13.5.6.4. 「FOREIGN KEY 制約」 を参照してください。

現在は、サブクエリの中で1つのテーブルを更新し、同じテーブルから選択する事はできません。

12.3. MySQL ユーティリティ ステートメント

12.3.1. DESCRIBE 構文

{DESCRIBE | DESC} tbl_name [col_name | wild]

DESCRIBE はテーブル内のカラムについて情報を提供します。これは、SHOW COLUMNS FROM へのショートカットです。これらのステートメントもまたビューの情報を表示します。(詳しくは 項12.5.4.4. 「SHOW COLUMNS 構文」 を参照してください。)

col_name は、カラム名、または SQL ‘%’ を含む文字列、そして文字列と一致する名前を持つカラムにだけアウトプットを取得する ‘_’ ワイルドカード文字になる事ができます。文字列がスペースやその他の特別な文字を含んでいない限り、それを引用句で囲む必要はありません。

mysql> DESCRIBE city;
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| Id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name       | char(35) | NO   |     |         |                |
| Country    | char(3)  | NO   | UNI |         |                |
| District   | char(20) | YES  | MUL |         |                |
| Population | int(11)  | NO   |     | 0       |                |
+------------+----------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

Field はカラム名を指示します。

Null フィールドは NULL 値がカラムの中に格納する事ができるかどうかを指示します。

Key フィールドはカラムがインデックスされるかどうかを指示します。PRI の値は、カラムがそのテーブルの主キーの一部であるかどうかを指示します。UNI はそのカラムが UNIQUE インデックスの一部である事を指示します。MUL 値は与えられた値のカラム内での複合発生が許容されている事を指示します。

MULUNIQUE インデックス上に表示されるひとつの理由は、いくつかのカラムが複合 UNIQUE インデックスを形成するという事です。カラムの組み合わせが固有であっても、それぞれのカラムは与えられた値の複合発生を保持する事ができます。複合インデックスの中では、インデックスの左端のカラムだけが Key フィールド内でエントリーを持つという事に注意してください。

Default フィールドは、カラムに割り当てられたデフォルト値を指示します。

Extra フィールドは与えられたカラムについて有効な追加情報を含んでいます。表示された例の中で、Extra フィールドは Id カラムが AUTO_INCREMENT キーワードを利用して作成されたという事を指示しています。

CREATE TABLE ステートメントに基づいていると思っていた物とデータ タイプがもし異なっていたら、MySQL はデータ タイプを変更する事があるという事に注意してください。詳しくは 項12.1.8.1. 「サイレント カラム仕様変更」 を参照してください。

DESCRIBE ステートメントにはオラクルの互換性が提供されています。

SHOW CREATE TABLESHOW TABLE STATUS ステートメントもテーブルについての情報を提供します。詳しくは 項12.5.4. 「SHOW 構文」 を参照してください。

12.3.2. HELP 構文

HELP 'search_string'

HELP ステートメントは MySQL リファレンス マニュアルからオンライン情報を返します。その正しい操作の為には mysql データベース内のヘルプ テーブルが、ヘルプ トピック情報で初期化さる必要があります。(項4.2.8. 「サーバ サイド ヘルプ」 を参照してください。)

HELP ステートメントは、ヘルプ テーブルの中で与えられた検索文字列を検索し、その結果を表示します。検索文字列は、大文字と小文字を区別しません。

HELP ステートメントはいくつかの検索文字列タイプを理解します。

  • 一般的なレベルでは、最高レベルのヘルプ カテゴリのリストを検索する為に contents を利用してください。

    HELP 'contents'
    
  • Data Types のような与えられたヘルプカテゴリ内のトピック リストには、カテゴリ名を利用してください。

    HELP 'data types'
    
  • ASCII() 関数や CREATE TABLE ステートメントのような特定のヘルプ トピックには、関連キーワードを利用してください。

    HELP 'ascii'
    HELP 'create table'
    

言い換えると、検索文字列はカテゴリ、多くのトピック、または単一トピックに一致するという事です。あらかじめ、与えられた検索文字列が、項目リストや単一ヘルプ トピックのヘルプ情報を返すかどうかを知る事はできません。しかし、結果セットの中のカラムと行数を調べる事で、HELP がどのような答えを返したのかを知る事ができます。

次の説明は結果セットが取る事ができる形を指示します。ステートメント例のアウトプットは、mysql クライアントを利用する時に見る事ができる為になじみのある 「tabular」 や 「vertical」 フォーマットを利用して表示されますが、mysql 自体は HELP 結果セットを違う方法で再フォーマットする事に注意してください。

  • 空の結果セット

    検索文字列に一致する物が見つかりませんでした。

  • 3つのカラムを持つ単列を含む結果セット

    これは、検索文字列がヘルプ トピックにヒットをもたらしたという意味です。結果は3つのカラムを持っています。

    • name:トピック名。

    • description:トピックに対しての記述的なヘルプテキスト。

    • example:使用法例。このカラムは空白である可能性があります。

    例:HELP 'replace'

    下記をもたらします。

    name: REPLACE
    description: Syntax:
    REPLACE(str,from_str,to_str)
    
    Returns the string str with all occurrences of the string from_str
    replaced by the string to_str. REPLACE() performs a case-sensitive
    match when searching for from_str.
    example: mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww');
            -> 'WwWwWw.mysql.com'
    
  • 2つのカラムを持つ複合行を含む結果セット

    これは、検索文字列がたくさんのヘルプ トピックに一致したという意味です。結果セットはヘルプ トピック名を指示します。

    • name:ヘルプ トピック名

    • is_it_category:もしその名前がヘルプ カテゴリを表していれば Y、もしそうでなければ N。もしそうでなければ、HELP ステートメントへの引数として指定された時の name 値は、名づけられた項目に対する説明を含む単列結果セットをもたらす必要があります。

    例:HELP 'status'

    下記をもたらします。

    +-----------------------+----------------+
    | name                  | is_it_category |
    +-----------------------+----------------+
    | SHOW                  | N              |
    | SHOW ENGINE           | N              |
    | SHOW INNODB STATUS    | N              |
    | SHOW MASTER STATUS    | N              |
    | SHOW PROCEDURE STATUS | N              |
    | SHOW SLAVE STATUS     | N              |
    | SHOW STATUS           | N              |
    | SHOW TABLE STATUS     | N              |
    +-----------------------+----------------+
    
  • 3つのカラムを持つ複合行を含む結果セット

    これは、検索文字列がカテゴリに一致するという事を意味します。結果セットはカテゴリ入力を含んでいます。

    • source_category_name:ヘルプカテゴリ名。

    • name:カテゴリまたはトピック名

    • is_it_category:もしその名前がヘルプ カテゴリを表していれば Y、もしそうでなければ N。もしそうでなければ、HELP ステートメントへの引数として指定された時の name 値は、名づけられた項目に対する説明を含む単列結果セットをもたらす必要があります。

    例:HELP 'functions'

    下記をもたらします。

    +----------------------+-------------------------+----------------+
    | source_category_name | name                    | is_it_category |
    +----------------------+-------------------------+----------------+
    | Functions            | CREATE FUNCTION         | N              |
    | Functions            | DROP FUNCTION           | N              |
    | Functions            | Bit Functions           | Y              |
    | Functions            | Comparison operators    | Y              |
    | Functions            | Control flow functions  | Y              |
    | Functions            | Date and Time Functions | Y              |
    | Functions            | Encryption Functions    | Y              |
    | Functions            | Information Functions   | Y              |
    | Functions            | Logical operators       | Y              |
    | Functions            | Miscellaneous Functions | Y              |
    | Functions            | Numeric Functions       | Y              |
    | Functions            | String Functions        | Y              |
    +----------------------+-------------------------+----------------+
    

12.3.3. USE 構文

USE db_name

USE db_name ステートメントは、MySQL に対して、後に続くステートメントのデフォルト データベースとして db_name データベースを利用するように指示します。そのデータベースは、そのセッションが終わるまで、または別の USE ステートメントが発行されるまでデフォルトのままです。

USE db1;
SELECT COUNT(*) FROM mytable;   # selects from db1.mytable
USE db2;
SELECT COUNT(*) FROM mytable;   # selects from db2.mytable

USE ステートメントを利用して特定のデータベースをデフォルトにする事によって、別のデータベースの中でテーブルにアクセスする時に邪魔をする事はありません。次の例は、db1 データベースから author テーブルへ、そして db2 データベースから editor テーブルへアクセスします。

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

USE ステートメントには Sybase の互換性が提供されています。

12.4. MySQL トランザクションとロッキング関連のステートメント

MySQL は SET AUTOCOMMITSTART TRANSACTIONCOMMIT、そして ROLLBACK のようなステートメントを通してローカル トランザクション(与えられたクライアント接続内の)をサポートします。詳しくは 項12.4.1. 「START TRANSACTIONCOMMIT、そして ROLLBACK 構文」 を参照してください。XA トランザクション サポートは、MySQL が分散型のトランザクションにも参加できるように働きかけます。詳しくは 項12.4.7. 「XA トランザクション」 を参照してください。

12.4.1. START TRANSACTIONCOMMIT、そして ROLLBACK 構文

START TRANSACTION | BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET AUTOCOMMIT = {0 | 1}

START TRANSACTIONBEGIN ステートメントは新しいトランザクションを始めます。COMMIT は、その変更を恒久的な物にし、現在のトランザクションを行います。ROLLBACK はその変更をキャンセルし、現在のトランザクションをロールバックします。SET AUTOCOMMIT ステートメントは現在の接続にデフォルト自動コミット モードを無効に、そして有効にします。

任意の WORK キーワードは、CHAINRELEASE 条項のように COMMITROLLBACK に対してサポートされています。CHAINRELEASE はトランザクション完了に対する追加コントロールに利用されます。completion_type システム変数の値はデフォルトの完了動作を決定します。詳しくは 項4.2.3. 「システム変数」 を参照してください。

AND CHAIN 条項は、現在のトランザクションが終わったらすぐに新しいトランザクションが始まるよう働きかけ、その新しいトランザクションは終わったばかりのトランザクションと同じ分離レベルを持ちます。RELEASE 条項は、現在のトランザクションを終了した後、サーバが現在のクライアント接続を切るよう働きかけます。NO キーワードを含む事は、もし completion_type システム変数がデフォルトで変更やリリース完了を引き起こすよう設定されれば有効となる、CHAINRELEASE 完了を食い止めます。

デフォルトにより、MySQL は自動コミットモードが有効な状態で起動します。これは、テーブルを更新(変更)するステートメントを実行したとたん、MySQL がディスク上に更新を格納する、という意味です。

もしトランザクション セーフ ストレージ エンジン(InnoDBNDB Cluster のような物)を利用していたら、次のステートメントを利用して自動コミットモードを無効にする事ができます。

SET AUTOCOMMIT=0;

AUTOCOMMIT 変数をゼロに設定する事で自動コミット モードを無効にした後、ディスクに変更を格納する為には COMMIT を、またはもしそのトランザクションの最初から行ってきた変更を無視したければ ROLLBACK を利用しなければいけません。

一連のステートメントに対して自動コミット モードを無効にする為には、START TRANSACTION ステートメントを利用してください。

START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;

START TRANSACTION を利用すると、自動コミットは COMMITROLLBACK を利用してトランザクションを終了するまで無効のままです。そして自動コミット モードはその前の状態に戻ります。

BEGINBEGIN WORK は、トランザクションを始める START TRANSACTION のエイリアスとしてサポートされています。START TRANSACTION はスタンダード SQL 構文で、アドホック トランザクションを始める方法として推奨されています。

重要:MySQL クライアント アプリケーションを書く為に利用されている多くの API (JDBC のような)は、トランザクションを始める為に、クライアントから START TRANSACTION ステートメントを送る代わりに利用する事ができる(場合によっては利用しなければならない)独自の方法を提供します。更なる情報については、章?23. APIとライブラリー か、ご利用の API の説明書を参照してください。

BEGIN ステートメントは、BEGIN ... END 複合ステートメントを開始する BEGIN キーワードの利用とは異なります。後者はトランザクションを開始しません。詳しくは 項17.2.5. 「BEGIN ... END 複合ステートメント構文」 を参照してください。

このようにトランザクションを開始する事もできます。

START TRANSACTION WITH CONSISTENT SNAPSHOT;

WITH CONSISTENT SNAPSHOT 条項は、一貫性のある読み取りが可能であるストレージ エンジンに対して、それを開始します。現在は、これは InnoDB にだけ適応しています。その効果は、InnoDB テーブルから SELECT が後に続く START TRANSACTION を発行することと同じです。詳しくは 項13.5.10.4. 「一貫非ロック読み取り」 を参照してください。

WITH CONSISTENT SNAPSHOT 条項は現在のトランザクションの分離レベルを変更しないので、現在の分離レベルが一貫性のある読み取りを許容する物である場合のみ(REPEATABLE READSERIALIZABLE)、一貫性のあるスナップショットを提供します。

トランザクションを開始すると、未解決のトランザクションを引き起こします。詳細については、項12.4.3. 「暗黙のコミットを引き起こすステートメント」 をご参照ください。

トランザクションを開始すると、LOCK TABLES を利用して行ったテーブル ロックを、まるで UNLOCK TABLES を実行したかのように解除してしまいます。トランザクションを開始しても、FLUSH TABLES WITH READ LOCK を利用して行われたグローバル リード ロックの解除はしません。

一番良い結果を得る為には、単一トランザクショナル ストレージ エンジンによって管理されたテーブルだけを利用してトランザクションを行うべきです。そうでなければ、次のような問題が起きます。

  • もし複数のトランザクション セーフ ストレージ エンジンのテーブルを利用していて(InnoDBFalcon のような)、またトランザクションの分離レベルが SERIALIZABLE でないならば、1つのトランザクションが行われた時に同じテーブルを利用する別の実行中のトランザクションが、最初のトランザクションによって行われた変更だけを見るという事が可能です。これは、トランザクションのアトミック性が、混合エンジンに保障されておらず、矛盾した結果になり得るという事です。(もし混合エンジン トランザクションが頻繁でなければ、必要に応じて分離レベルを SERIALIZABLE に設定する為に、1つのトランザクション単位で SET TRANSACTION ISOLATION LEVEL を利用する事ができます。)

  • もし非トランザクション セーフ テーブルをトランザクション内で利用すれば、自動コミットの状態に関わらず、それらのテーブルへの変更は一度に格納されます。

    もし非トランザクション テーブルをトランザクション内で更新した後に ROLLBACK ステートメントを発行すると、ER_WARNING_NOT_COMPLETE_ROLLBACK 警告が発生します。トランザクション セーフ テーブルへの変更はロールバックされますが、非トランザクション セーフ テーブルへの変更はされません。

各トランザクションは COMMIT によって、1つの塊でバイナリ ログの中に格納されています。ロールバックされたトランザクションはログされません。(例外:非トランザクション テーブルへの変更はロールバックされません。もしロールバックされたトランザクションが、非トランザクション テーブルへの変更を含んでいたら、それらのテーブルへの変更が複製される事を保障する為に、最後にそのトランザクション全体が ROLLBACK ステートメントでログされます。)詳しくは 項4.11.4. 「バイナリ ログ」 を参照してください。

SET TRANSACTION ISOLATION LEVEL を利用してトランザクションの分離レベルを変更する事ができます。詳しくは 項12.4.6. 「SET TRANSACTION 構文」 を参照してください。

ロールバックは、ユーザーが明示的に求めなくても行われる、ゆっくりとした操作になり得ます。 (例えば、エラーが発生した時。)この為、SHOW PROCESSLIST は、明示的、暗黙的な(ROLLBACK SQL ステートメント)ロールバックの最中の接続に対する State カラム内の Rolling back を表示します。

12.4.2. ロールバックできないステートメント

いくつかのステートメントはロールバックできません。通常、それらはデータベースを作成したりドロップしたりする物や、テーブルやストアド ルーチンを作成、ドロップ、変更する物のような、データ定義言語(DDL)ステートメントを含みます。

そのような物をトランザクション内に含まないようにデザインする必要があります。もしロールバックできないトランザクション内で、早いうちにステートメントを発行し、そして別のステートメントがその後失敗すると、そのような場合 ROLLBACK ステートメントを発行する事によってそのトランザクション全体の効果をロールバックする事はできません。

12.4.3. 暗黙のコミットを引き起こすステートメント

次の各ステートメント(そしてそれらの同義語)は、まるでステートメントを実行する前に COMMIT を行ったかのように、暗黙にトランザクションを終了します。

  • ALTER FUNCTION, ALTER PROCEDURE, ALTER TABLE, BEGIN, CREATE DATABASE, CREATE FUNCTION, CREATE INDEX, CREATE PROCEDURE, CREATE TABLE, DROP DATABASE, DROP FUNCTION, DROP INDEX, DROP PROCEDURE, DROP TABLE, LOAD DATA INFILE LOCK TABLES, RENAME TABLE, SET AUTOCOMMIT=1, START TRANSACTION, TRUNCATE TABLE, UNLOCK TABLES.

  • MySQL 5.1.3 から、ALTER VIEWCREATE TRIGGERCREATE USERCREATE VIEWDROP TRIGGERDROP USERDROP VIEW、そして RENAME USER ステートメントは暗黙的なコミットを引き起こすようになりました。

  • UNLOCK TABLES は、もしテーブルが現在 LOCK TABLES でロックされていたらトランザクションを行います。これは、FLUSH TABLES WITH READ LOCK ステートメントがテーブル レベル ロックを取得しない為、これに続く UNLOCK TABLES に対しては行われません。

  • InnoDB 内の CREATE TABLE ステートメントは単一トランザクションとして生成されます。これは、ユーザからの ROLLBACK はトランザクションの最中にユーザが作成した CREATE TABLE ステートメントを解除しないという意味です。

  • CREATE TABLEDROP TABLE は、もし TEMPORARY キーワードが利用されたらトランザクションを実行しません。(これは、コミットを引き起こさない CREATE INDEX のようなテンポラリ テーブルへのその他の操作には当てはまりません。)

  • MySQL 5.1.15 から、CREATE TABLE ... SELECT はステートメントが実行される前後に暗黙的なコミットを引き起こすようになりました。しかし、CREATE TEMPORARY TABLE ... SELECT には何のコミットも起きません。

  • MySQL 5.1.11 以前では、LOAD DATA INFILE は全てのストレージ エンジンに対して暗黙的なコミットを引き起こしました。MySQL 5.1.12 からは、 NDB ストレージエンジンを利用しているテーブルに対してだけ暗黙的なコミットを引き起こすようになりました。更なる情報については、バグ #11151を参照してください。

  • MySQL 5.1.15 以降では、非テンポラリ テーブルを作成している時 CREATE TABLE ... SELECT ステートメントは暗黙的なコミットを含みます。これは、ロールバック後にマスタ上でテーブルを作成する事ができてもバイナリログ内での記録に失敗する為スレーブには複製されない、という複製の最中での発行を防ぐ為の物です。更なる情報については、バグ #22865を参照してください。

トランザクションはネスト化されません。これは、START TRANSACTION ステートメントかその同義語の1つを発行する時点でのトランザクションに対して実行される、暗黙的な COMMIT の結果です。

トランザクションが ACTIVE 状態の間は、暗黙的な作業を引き起こすステートメントは XA トランザクションでは利用する事はできません。

12.4.4. SAVEPOINTROLLBACK TO SAVEPOINT 構文

SAVEPOINT identifier
ROLLBACK [WORK] TO SAVEPOINT identifier
RELEASE SAVEPOINT identifier

InnoDB は SQL ステートメント SAVEPOINTROLLBACK TO SAVEPOINTRELEASE SAVEPOINT そして ROLLBACK の任意 WORK キーワードをサポートします。

SAVEPOINT ステートメントは identifier の名前を利用して、名前が付けられたトランザクション セーブポイントを設定します。もし現在のトランザクションが同名のセーブポイントを持っていれば、古いセーブポイントは削除され新しいものが設定されます。

ROLLBACK TO SAVEPOINT ステートメントは、名づけられたセーブポイントにトランザクションをロールバックします。セーブポイントの設定後に行に対して現在のトランザクションが行った変更はロールバック内で解除されますが、InnoDB はセーブポイントの後にメモリに格納された新しい行ロックのリリースは 行いません。(新しく挿入された行には、その行内に格納されているトランザクション ID によってロック情報が保持されるので、そのロックはメモリの中で別々に格納される訳ではないという事に注意してください。この場合、行ロックは取り消しの中でリリースされます。)名づけられたセーブポイントよりも後で設定されたセーブポイントは削除されます。

もし ROLLBACK TO SAVEPOINT ステートメントが次のエラーを返したら、指定された名前のセーブポイントは存在しないという事を意味します。

ERROR 1181: Got error 153 during ROLLBACK

RELEASE SAVEPOINT ステートメントは、現在のトランザクションのセーブポイント セットから、名づけられたセーブポイントを除外します。コミットもロールバックも起きません。もしセーブポイントが存在しなければ、これはエラーになります。

もし COMMIT や、セーブポイントに名前をつけない ROLLBACK を実行すると、現在のトランザクションの全てのセーブポイントは削除されます。

MySQL 5.0.17 から、ストアド ファンクションが呼び出されたりトリガが作動した時に、新しいセーブポイント レベルが作成されます。以前のレベルのセーブポイントは無効になる為、新しいレベルとの間でセーブポイントの衝突が起きません。ファンクションやトリガが終了する時に、それらが作成したセーブポイントはリリースされ、以前のセーブポイント レベルが保持されます。

12.4.5. LOCK TABLESUNLOCK TABLES 構文

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

LOCK TABLES は、現在のスレッドに対してベース テーブル (ビュー以外) をロックします。もしテーブルが1つでも他のスレッドによってロックされていたら、それは全てのロックを入手するまでブロックします。

UNLOCK TABLES は現在のスレッドによって行われたロックを全て明示的にリリースします。スレッドが別の LOCK TABLES を発行した時、またはサーバへの接続が閉じられた時に、現在のスレッドにロックされている全てのテーブルは暗黙的にロック解除されます。 UNLOCK TABLES はまた、FLUSH TABLES WITH READ LOCK を利用してグローバル リード ロックを取得した後に、そのロックをリリースする為に利用されます。(FLUSH TABLES WITH READ LOCK ステートメントによってリード ロックされている全てのデータベース内の全てのテーブルをロックする事ができます。詳しくは 項12.5.5.2. 「FLUSH 構文」 を参照してください。これは、もし Veritas のような時間内にスナップショットを撮る事ができるファイルシステムを持っていると、バックアップを取るのが大変便利な方法になります。)

LOCK TABLES を利用する為には、関連するテーブルに対して LOCK TABLES 権限と SELECT 権限を持つ必要があります。

LOCK TABLES を利用する主な理由は、テーブルを更新する際にトランザクションをエミュレートしたり、スピードを早くしたりする事です。後ほどもう少し詳しく説明します。

テーブル ロックは、別のクライアントによる不適切な読み込みや書き込みに対してのみ保護します。ロックを保持しているクライアントは、それがリード ロックだとしても、DROP TABLE のようなテーブル レベル操作を行う事ができます。切り捨て操作はトランザクション セーフではないので、もし、アクティブなトランザクションの実行中や、テーブル ロックを保持している最中にクライアントがそれを行おうとすると、エラーが発生します。

LOCK TABLES とトランザクション テーブルを共に利用する際には、次の事に注意してください。

  • LOCK TABLES はトランザクション セーフではないので、テーブルをロックしようとする前に、全てのアクティブなトランザクションを暗黙的にコミットします。また、トランザクションの開始をすると(例えば START TRANSACTION を利用して)、明示的に UNLOCK TABLES を実行します。(詳しくは 項12.4.3. 「暗黙のコミットを引き起こすステートメント」 を参照してください。)

  • LOCK TABLESInnoDB のようなトランザクション テーブルと共に利用する正しい方法は、AUTOCOMMIT = 0 を設定し、トランザクションを明示的にコミットするまでは UNLOCK TABLES をコールしないという方法です。LOCK TABLES をコールする時、InnoDB は内部的にそれ自身のテーブル ロックを取り、そして MySQL もそれ自身のテーブル ロックを取ります。InnoDB は次のコミットでテーブル ロックを解除しますが、MySQL がそのテーブル ロックを解除するには、 UNLOCK TABLES をコールする必要があります。InnoDBLOCK TABLES のコールの後そのテーブル ロックを即座にリリースし、その為にデッドロックが簡単に起きてしまうので、AUTOCOMMIT = 1 を持つべきでは有りません。もし AUTOCOMMIT=1 であれば、古いアプリケーションの不必要なデッドロックを防ぐ為に、InnoDB テーブル ロックを全く取得しないという事に注意してください。

  • ROLLBACK は MySQL の非トランザクション テーブル ロックを解除しません。

  • FLUSH TABLES WITH READ LOCK は、グローバル リード ロックは取得しますがテーブル ロックはしないので、テーブル ロックと暗黙的なコミットに関しては LOCK TABLESUNLOCK TABLES と同じような動作の制約は受けません。詳しくは 項12.5.5.2. 「FLUSH 構文」 を参照してください。

LOCK TABLES を利用する時、ステートメントの中で利用する予定の全てのテーブルをロックしなければいけません。LOCK TABLES はビューをロックしないので、もし今実行している操作がビューを利用するなら、それらのビューが依存する全てのベース テーブルもロックしなければいけません。LOCK TABLES ステートメントで取得したロックが有効な間は、そのステートメントによってロックされていないテーブルにアクセスする事はできません。また、単一クエリの中でロックされたテーブルを複数回使用する事はできません。各エイリアスに対して別々にロックを取得する必要がある場合には、代わりにエイリアスを利用してください。

mysql> LOCK TABLE t WRITE, t AS t1 WRITE;
mysql> INSERT INTO t SELECT * FROM t;
ERROR 1100: Table 't' was not locked with LOCK TABLES
mysql> INSERT INTO t SELECT * FROM t AS t1;

もしステートメントがエイリアスを利用してテーブルを参照するなら、同じエイリアスを利用してテーブルをロックする必要があります。エイリアスを指定しないでテーブルをロックする事はできません。

mysql> LOCK TABLE t READ;
mysql> SELECT * FROM t AS myalias;
ERROR 1100: Table 'myalias' was not locked with LOCK TABLES

反対に、もしエイリアスを利用してテーブルをロックすると、そのエイリアスを利用してステートメント内でそのテーブルを参照する必要があります。

mysql> LOCK TABLE t AS myalias READ;
mysql> SELECT * FROM t;
ERROR 1100: Table 't' was not locked with LOCK TABLES
mysql> SELECT * FROM t AS myalias;

もしスレッドがテーブル上で READ ロックを取得したら、そのスレッド(そしてそれ以外の全てのスレッド)はテーブルからは読み込む事しかできません。もしスレッドがテーブル上で WRITE ロックを取得したら、そのロックを保持するスレッドのみがそのテーブルに書き込みができます。ロックが解除されるまで、その他のスレッドはテーブルの読み込み、書き込みからブロックされます。

READ LOCALREAD の違いは、READ LOCAL は、ロックされている間に非対立 INSERT ステートメント(並列挿入)が実行される事を許容するという事です。しかし、もしロックを保持している間に MySQL の外部でデータベース ファイルを複製しようとすると、これを利用する事はできません。 InnoDB テーブルに対しては、READ LOCALREAD と同じです。

WRITE ロックは通常、更新がなるべく速く行われるよう、READ ロックよりも高い優先順位を持ちます。これは、もし1つのスレッドが READ ロックを取得し、そして別のスレッドが WRITE ロックをリクエストすると、後続の READ ロックリクエストは、WRITE スレッドがロックを得て、それをリリースするまで待つ、という意味になります。WRITE ロックを待っているスレッドの前に、別のスレッドが READ ロックを取得するのを許容する為に、LOW_PRIORITY WRITE を利用する事ができます。READ ロックを持つスレッドが無い時に、時間が残っている事が確実である時だけ、LOW_PRIORITY WRITE ロックを利用しなければいけません。(例外:トランザクション モード(自動コミット = 0)の InnoDB テーブルに対しては、LOW_PRIORITY WRITE ロックは通常の WRITE ロックのように機能し、待機中の READ ロックに先行します。)

LOCK TABLES は次のように機能します。

  1. ロックされる全てのテーブルを内部定義順に並べ替えます。ユーザの立場からは、この順番は定義されていません。

  2. もしそのテーブルが読み込みと書き込みの両方についてロックされるなら、読み込みロックの前に書き込みロックを行ってください。

  3. スレッドが全てのロックを得るまで、テーブル1つずつにロックをして下さい。

.この方法は、テーブル ロックにデッドロックが起きない事を保証します。:しかし、この方法について知っておかなければいけない事があります。もしテーブルに対して LOW_PRIORITY WRITE ロックを利用していたら、MySQL は READ ロックを必要とするスレッドがなくなるまで、この特定のロックを待つ、という意味になります。スレッドが WRITE ロックを得て、ロック テーブル リストの中の次のテーブルのロックを得るのを待っている時、他の全てのスレッドは WRITE ロックが解除されるのを待ちます。もしこれが、ご利用のアプリケーションにとって深刻な問題となってしまったら、いくつかのテーブルをトランザクション セーフ テーブルに変換する事を考慮するべきです。

テーブル ロックを待っているスレッドを終了させる為に、KILL を安全に使用する事ができます。詳しくは 項12.5.5.3. 「KILL 構文」 を参照してください。

INSERT が別のスレッドによって実行されてしまう為、INSERT DELAYED と共に利用しているテーブルをロック してはいけない という事に注意してください。

通常、全ての単一 UPDATE ステートメントはアトミックなので、テーブルをロックする必要はありません。別のスレッドが現在実行中の SQL ステートメントの邪魔をする事はできません。しかし、テーブルをロックする事が利益をもたらす場合もいくつかあります。

  • MyISAM テーブル セット上でたくさんの操作を行おうとしているのであれば、利用する予定のテーブルをロックしたほうが操作が速くできます。UNLOCK TABLES がコールされるまで、MySQL はロックされたテーブルのキー キャッシュをフラッシュしないので、MyISAM テーブルをロックすると、挿入、更新、削除のスピードを速くします。通常、キー キャッシュは各 SQL ステートメントの後でフラッシュされます。

    テーブルをロックする事のマイナス面は、READ ロックされたテーブル(ロックを保持している物も含む)を更新できるスレッドが無く、またロックを保持しているテーブル以外は WRITE ロックされたテーブルにアクセスできるスレッドが無いという事です。

  • 非トランザクション ストレージ エンジンに対してテーブルを利用している場合に、もし SELECTUPDATE の間に別のスレッドがテーブルを変更しない事を保証したければ、LOCK TABLES を利用する必要があります。ここに表されている例は、安全に実行する為に LOCK TABLES を必要とします。

    LOCK TABLES trans READ, customer WRITE;
    SELECT SUM(value) FROM trans WHERE customer_id=some_id;
    UPDATE customer
      SET total_value=sum_from_previous_statement
      WHERE customer_id=some_id;
    UNLOCK TABLES;
    

    LOCK TABLES 無しで、別のスレッドが SELECTUPDATE ステートメントの実行の間に、trans テーブル内に新しい行を挿入する事が可能です。

多くの場合、相対更新(UPDATE customer SET value=value+new_value)または LAST_INSERT_ID() 関数を利用する事で、LOCK TABLES の利用を避ける事ができます。詳しくは 項1.8.5.3. 「トランザクションとアトミックオペレーション」 を参照してください。

ユーザ レベルの通知ロック機能 GET_LOCK()RELEASE_LOCK() を利用する事で、テーブルのロックを避ける事ができる場合があります。これらのロックははサーバ内のハッシュ テーブルの中に保存され、スピードを速くする目的で pthread_mutex_lock()pthread_mutex_unlock() を利用して実施されます。詳しくは 項11.10.4. 「その他の関数」 を参照してください。

ロックの規定に関しての更なる情報は 項6.3.1. 「MySQL のテーブルロック方法」 を参照してください。

注意:もしロックされたテーブル上に ALTER TABLE を利用すると、ロックが解除される可能性があります。詳しくは 項B.1.7.1. 「Problems with ALTER TABLE を参照してください。

12.4.6. SET TRANSACTION 構文

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

このステートメントは、次のトランザクションにグローバルに分離レベルを設定したり、現在のセッションに分離レベルを設定したりします。

SET TRANSACTION のデフォルト動作は、次の(まだ始まっていない)トランザクションの分離レベルを設定する事です。もし GLOBAL キーワードを利用すると、そのステートメントはその時点以降に作成された全ての新しい接続に対して、デフォルトのトランザクション レベルをグローバルに設定します。既存接続には影響はありません。これには SUPER 権限が必要です。SESSION キーワードの利用は、現在の接続上で今後行われる全てのトランザクションに対して、デフォルト トランザクション レベルを設定します。

InnoDB トランザクション分離レベルの説明に関しては、項13.5.10.3. 「InnoDBTRANSACTION ISOLATION LEVEL を参照してください。InnoDB は MySQL 5.1 内でこれらそれぞれのレベルをサポートします。デフォルト レベルは REPEATABLE READ です。

mysqld に冒頭のデフォルト グローバル分離レベルを設定する為には、--transaction-isolation オプションを利用してください。詳しくは 項4.2.2. 「コマンド オプション」 を参照してください。

12.4.7. XA トランザクション

InnoDB ストレージ エンジンでは、XA トランザクションがサポートされています。MySQL XA インプリメンテーションは X/Open CAE ドキュメント Distributed Transaction Processing:XA 仕様 に基づいています。この文書はオープン グループによって出版されていて、http://www.opengroup.org/public/pubs/catalog/c193.htm で入手可能です。現在の XA インプリメンテーションの制限については、 項D.5. 「XA トランザクションの規制」 で説明されています。

クライアント側には、特別な事は何も要求されません。MySQL サーバへの XA インターフェースは、XA キーワードで始まる SQL ステートメントで構成されています。MySQL クライアント プログラムは、SQL ステートメントを送り、XA ステートメント インターフェースの動作を理解する事が可能である必要があります。それらは最近のクライアント ライブラリに違反してリンクされる必要はありません。古いクライアント ライブラリもまた機能します。

現在、MySQL コネクタの中では、MySQL コネクタ/J 5.0.0 が XA ディレクトリをサポートします。 (XA SQL ステートメント インターフェースを扱うクラス インターフェースを利用して)

XA は分散型のトランザクションをサポートします。それは、複数の別々のトランザクション リソースを、グローバル トランザクションに参加させる事ができる能力です。トランザクション リソースは RDBMS である事が多いのですが、別の種類である可能性もあります。

グローバル トランザクションは、それら自身の中でトランザクションのアクションをいくつか含んでいますが、それらは全て、グループとして成功するか、グループとしてロールバックされる必要があります。要するに、これは複数の ACID トランザクションが、ACID 特性を持つグローバル操作のコンポーネントとして一斉に実行されるように ACID 特性を 「1レベル上げる」 という事です。(しかし、分散型のトランザクションには、ACID 特性を達成する為に、SERIALIZABLE 分離レベルを利用しなければいけません。非分散型のトランザクションには REPEATABLE READ の利用で十分ですが、分散型のトランザクションに対しては十分では有りません。)

分散型トランザクションのいくつかの例

  • アプリケーションは、メッセージ サービスと RDBMS を合体させる統合ツールとして機能します。アプリケーションは、メッセージの送信、検索、さらにトランザクションのデータベースも巻き込んで処理を行うトランザクションが、全て確実にグローバル トランザクションの中で行われるようにします。これを 「トランザクションの電子メール」 だと考える事ができます。

  • アプリケーションは、複数のサーバを含むアクションが、各サーバに対する別々のローカル トランザクションではなく、グローバル トランザクションの一部として発生する、MySQL サーバやオラクル サーバ(または複合 MySQL サーバ)のような、異なるデータベースを含むアクションを実行します。

  • 銀行は、RDBMS 内に口座情報を保持し、現金自動支払機(ATM)を通してお金を配布、受け取りします。ATM のアクションは口座に正確に反映されなければいけませんが、これは RDBMS だけでは行えません。グローバル トランザクション マネージャーが、金融取引全体の整合性を保障する為に、現金 ATM とデータベース リソースを統合します。

グローバル トランザクションを利用するアプリケーションは、1つ、または複数のリソース マネージャと、1つのトランザクション マネージャを含んでいます。

  • リソース マネージャ(RM)はトランザクションのリソースにアクセスを供給します。データベース サーバはリソース マネージャの1つです。RM によって管理されたトランザクションをコミットしたり、ロールバックしたりする事が可能なはずです。

  • トランザクション マネージャ(TM)はグローバル トランザクションの一部であるトランザクションを調整します。これは、これらの各トランザクションを扱う RM と通信します。グローバル トランザクション内の各トランザクションは、グローバル トランザクションの 「ブランチ」 です。グローバル トランザクションと、それらのブランチは、後ほど紹介される名づけスキームによって識別されます。

XA MySQL の MySQL インプリメンテーションは、MySQL サーバがグローバル トランザクション内で XA トランザクションを扱うリソース マネージャとして機能する事を可能にします。MySQL サーバに接続するクライアントプログラムは、トランザクション マネージャとして機能します。

グローバル トランザクションを実行するには、どのコンポネントが関係しているかを知り、それらをそれぞれ、コミットまたはロールバックできる時にポイントまで持ってくる事が必要です。 各コンポネントがそれぞれの能力についてどのようなレポートをするかによって、それらは全て1つのアトミック グループとしてコミット、またはロールバックしなければいけません。 それは、全てのコンポネントがコミットするか、または全てのコンポネントがロールバックするという事です。グローバル トランザクションを管理するには、コンポネントか、接続ネットワークが失敗する可能性があるという事を考慮に入れておく事が必要です。

グローバル トランザクションを実行するプロセスは、二相コミットを利用します。(2PC)これは、グローバル トランザクションのブランチによって行われるアクションが実行された後に起こります。

  1. 第一段階で、全てのブランチが準備されます。それは、TM からコミットの準備の命令が出るという事です。通常、これはブランチが管理する各 RM が、安定したストレージの中にブランチの為のアクションを記録するという事を意味します。ブランチは、それらが利用可能かどうかを指示し、その結果は第二段階に利用されます。

  2. 第二段階では、TM が RM にロールバックを行うかどうかの指示を出します。もし全てのブランチの準備が整った時それらがコミットが可能だという連絡を出せは、それら全てにコミットの指示が出されます。もしブランチの準備が整った時にどれか1つでもコミットが不可能であるという連絡があれば、全てのブランチにロールバックの指示が出されます。

場合によっては、グローバル トランザクションは単相コミットを利用します。(1PC)例えば、トランザクション マネージャがたった1つのトランザクション リソースで成り立っているグローバル トランザクションを見つけたら(それを単一ブランチといいます)、そのリソースには準備とコミットを同時にするように指示が出されます。

12.4.7.1. XA トランザクション SQL 構文

MySQL 内で XA トランザクションを行うには、次のステートメントを利用してください。

XA {START|BEGIN} xid [JOIN|RESUME]

XA END xid [SUSPEND [FOR MIGRATE]]

XA PREPARE xid

XA COMMIT xid [ONE PHASE]

XA ROLLBACK xid

XA RECOVER

XA START に対しては、JOINRESUME 条項はサポートされていません。

XA END に対しては、SUSPEND [FOR MIGRATE] 条項はサポートされていません。

各 XA ステートメントは XA キーワードで始まり、それらのほとんどが xid 値を必要とします。xid は XA トランザクション識別子です。それは、ステートメントがどのトランザクションに適応するのか指示します。 xid 値はクライアントから提供されるか、MySQL サーバから発生します。xid 値は1つから3つの部分を持っています。

xid: gtrid [, bqual [, formatID ]]

gtrid はグローバル トランザクション識別子、bqual はブランチ修飾子、そして formatIDgtridbqual 値によって利用されるフォーマットを識別する数値です。構文によって指示されているように、bqualformatID は任意です。デフォルトの bqual 値は、指示されていない限り '' です。デフォルトの formatID 値は、指示されていない限り1です。

gtridbqual は文字列直定数である必要があり、それぞれが最長64バイトです(文字数ではない)。gtridbqual の指定方法は、いくつかあります。引用された文字列('ab')、16進数列 (0x6162X'ab')、またはビット値(b'nnnn')を利用する事ができます。

formatID は符号無しの整数です。

gtridbqual 値は、MySQL サーバに内在する XA サポート ルーチンによって、バイトで解釈されます。 しかし、XA ステートメントを含む SQL ステートメントが解析されると、サーバはいくつかの特定の文字セットと共に機能します。安全の為に、 gtridbqual を16進数列として書いてください。

xid 値は一般的にトランザクション マネージャによって生成されます。ある TM によって生成された値は、別の TM によって生成された値とは異なります。規定の TM は XA RECOVER ステートメントによって返された値のリスト内にある、それ自身の xid 値を識別できなければいけません。

XA START xid は、規定の xid 値を利用して XA トランザクションをスタートします。各 XA トランザクションは固有の xid 値を持つ必要があるので、その値は同時に XA トランザクションによって利用されてはいけません。一意性は gtridbqual 値を利用して評価されます。XA トランザクションに続く全ての XA ステートメントは、XA START ステートメント内で規定されているように、同じ xid 値を利用して指定されなければいけません。もし、それらのステートメントのどれかを利用しながら、既存 XA トランザクションに対応しない xid 値を指定すると、エラーが起こります。

ひとつ、または複数の XA トランザクションは同じグローバル トランザクションの一部になる事ができます。規定のグローバル トランザクション内の全ての XA トランザクションは、xid 値内で同じ gtrid 値を利用しなければいけません。この理由により、規定の XA トランザクションがどのグローバル トランザクションの一部であるかをはっきりさせる為に、gtrid 値はグローバルに一意である必要があります。xid 値の bqual 部は、グローバル トランザクションの中で、各 XA トランザクションに対して異なっている必要があります。(bqual 値が異なっている必要があるという要求は、現在の MySQL XA インプリメンテーションの制限です。これは XA 仕様の一部ではありません。)

XA RECOVER ステートメントは、PREPARED 状態にある MySQL サーバ上の XA トランザクションに情報を返します。(詳しくは 項12.4.7.2. 「XA トランザクションの状態」 をご確認ください。)アウトプットは、どのクライアントがスタートしたかに関わらず、サーバ上の XA トランザクションなどの行を含みます。

XA RECOVER アウトプット行はこのような形になります。('abc''def'、そして 7 部分で成り立っている xid 値の例):

mysql> XA RECOVER;
+----------+--------------+--------------+--------+
| formatID | gtrid_length | bqual_length | data   |
+----------+--------------+--------------+--------+
|        7 |            3 |            3 | abcdef |
+----------+--------------+--------------+--------+

アウトプット カラムは次の意味を持っています。

  • formatID はトランザクション xidformatID 部です。

  • gtrid_lengthxidgtrid 部の、バイトでの長さです。

  • bqual_lengthxidbqual 部の、バイトでの長さです。

  • dataxidgtridbqual 部の連結です。

12.4.7.2. XA トランザクションの状態

次の状態での XA トランザクションの進歩

  1. XA トランザクションをスタートさせる為に XA START を利用し、それを ACTIVE な状態にして下さい。

  2. ACTIVE XA トランザクションには、トランザクションを形成する SQL ステートメントを発行し、それから XA END ステートメントを発行してください。XA END はトランザクションを IDLE の状態にします。

  3. IDLE XA トランザクションには、XA PREPARE ステートメントか XA COMMIT ... ONE PHASE ステートメントのどちらかを発行できます。ONE PHASE ステートメント:

    • XA PREPARE はトランザクションを

      PREPARED の状態にします。

    • この時点の XA RECOVER ステートメントは、XA RECOVERPREPARED な状態にある全ての XA トランザクションをリストにする為、そのアウトプットの中にトランザクションの xid 値を含みます。

    • XA COMMIT ... ONE PHASE はトランザクションを準備し、コミットします。xid 値は、トランザクションが終了する為 XA RECOVER によってリストされません。

  4. PREPARED XA トランザクションに対して、トランザクションをコミットし、終了させる為に XA COMMIT ステートメントを発行するか、またはトランザクションをロールバックして終了させる為に XA ROLLBACK を発行できます。

ここに、行をテーブルにグローバル トランザクションの一部として挿入するシンプルな XA トランザクションの例があります。

mysql> XA START 'xatest';
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO mytable (i) VALUES(10);
Query OK, 1 row affected (0.04 sec)

mysql> XA END 'xatest';
Query OK, 0 rows affected (0.00 sec)

mysql> XA PREPARE 'xatest';
Query OK, 0 rows affected (0.00 sec)

mysql> XA COMMIT 'xatest';
Query OK, 0 rows affected (0.00 sec)

既存のクライアント接続のコンテキストの中で、XA トランザクションとローカル トランザクション(非 XA)は、お互いに 排他的です。例えば、もし XA トランザクションを始める為に XA START が発行されたら、XA トランザクションがコミットされるかロールバックされるまで、ローカル トランザクションはスタートできません。逆に、もしローカル トランザクションが START TRANSACTION でスタートされたら、トランザクションがコミットされるかロールバックされるまで、XA トランザクションは利用できません。

もしXA トランザクションが ACTIVE な状態であれば、暗黙的なコミットを引き起こすステートメントの発行はできないという事に注意してください。XA トランザクションをロールバックする事はできないので、これはXA 規約に違反するという事になります。もしこのようなステートメントを実行しようとすると、次のようなエラーが発生します。

ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed
when global transaction is in the ACTIVE state

ステートメントが上記のどの注意事項に当てはまるのかは、項12.4.3. 「暗黙のコミットを引き起こすステートメント」 でリストアップされています。

12.5. データベース管理ステートメント

12.5.1. アカウント管理ステートメント

MySQL アカウント情報は mysql データベースのテーブルに格納されています。このデータベースとアクセス コントロール システムについては 章?4. データベース管理 で詳しく説明されていますので、更なる詳細についてはこれを参照して下さい。

重要:MySQL のいくつかのリリース版は、新しい権限や特徴を追加する為に供与テーブルの構造の変更を紹介しています。MySQL の新しいバージョンを更新する時はいつでも、新しい機能を有効に利用できるようにする為に、供与テーブルを最新の構造に更新しなければいけません。詳しくは 項4.5.4. 「mysql_upgrade ? MySQL アップグレードのテーブル チェック」 を参照してください。

MySQL Enterprise 製造環境では、ユーザ アカウントへの変更を慎重に分析する事が大切です。MySQL ネットワーク モニタリングとアドバイス サービス はユーザの権限が変更される度にそれを通知します。追加情報については http://www-jp.mysql.com/products/enterprise/advisors.html を参照してください。

12.5.1.1. CREATE USER 構文

CREATE USER user [IDENTIFIED BY [PASSWORD] 'password']
    [, user [IDENTIFIED BY [PASSWORD] 'password']] ...

CREATE USER ステートメントは新しい MySQL アカウントを作成します。それを利用する為には、mysql データベースにグローバル CREATE USER 権限か INSERT 権限を持つ必要があります。それぞれのアカウントに対して、CREATE USER は権限を持たない mysql.user テーブル内に新しい行を作成します。もしアカウントが既に存在すると、エラーが発生します。各アカウントは、例えば、'jeffrey'@'localhost' のように GRANT ステートメントと同じフォーマットを利用して名づけられます。もしアカウント名のユーザ名部分だけを指定すると、ホスト名の '%' 部分が利用されます。アカウント名の指定についての追加情報に関しては、項12.5.1.3. 「GRANT 構文」 を参照してください。

アカウントには、任意の IDENTIFIED BY 条項を利用してパスワードを与える事ができます。user 値とパスワードは、GRANT ステートメントと同じ方法で与える事ができます。特に、プレーン テキスト内でパスワードを指定するには、PASSWORD キーワードを省略してください。パスワードを、PASSWORD() 関数によって返されたようにハッシュ化された値として指定するには、PASSWORD キーワードを含んでください。詳しくは 項12.5.1.3. 「GRANT 構文」 を参照してください。

12.5.1.2. DROP USER 構文

DROP USER user [, user] ...

DROP USER ステートメントは1つ、または複数の MySQL アカウントを削除します。それは、全ての供与テーブルからアカウントの権限行を削除します。このステートメントを利用する為には、mysql データベースにグローバル CREATE USER 権限か DELETE 権限を持つ必要があります。各アカウントは、例えば、'jeffrey'@'localhost' のように GRANT ステートメントと同じフォーマットを利用して名づけられます。もしアカウント名のユーザ名部分だけを指定すると、ホスト名の '%' 部分が利用されます。アカウント名の指定についての追加情報に関しては、項12.5.1.3. 「GRANT 構文」 を参照してください。

DROP USER を利用すると、アカウントとその権限を次のように削除する事ができます。

DROP USER user;

重要:DROP USER は自動的にユーザ セッションを閉じません。それよりも、オープン セッションを持つユーザがドロップした時には、そのユーザのセッションが閉じられるまでそのステートメントは効果を発揮しません。一度セッションが閉じられると、そのユーザはドロップされ、そのユーザが次にログインしようとすると失敗します。これには意図があります。

DROP USER は、ユーザが作成したデータベース オブジェクトを自動的に削除したり、無効にしたりしません。これは、テーブル、ビュー、ストアド ルーチン、トリガ、そしてイベントに適応します。

12.5.1.3. GRANT 構文

GRANT priv_type [(column_list)] [, priv_type [(column_list)]] ...
    ON [object_type] {tbl_name | * | *.* | db_name.*}
    TO user [IDENTIFIED BY [PASSWORD] 'password']
        [, user [IDENTIFIED BY [PASSWORD] 'password']] ...
    [REQUIRE
        NONE |
        [{SSL| X509}]
        [CIPHER 'cipher' [AND]]
        [ISSUER 'issuer' [AND]]
        [SUBJECT 'subject']]
    [WITH with_option [with_option] ...]

object_type =
    TABLE
  | FUNCTION
  | PROCEDURE

with_option =
    GRANT OPTION
  | MAX_QUERIES_PER_HOUR count
  | MAX_UPDATES_PER_HOUR count
  | MAX_CONNECTIONS_PER_HOUR count
  | MAX_USER_CONNECTIONS count

GRANT ステートメントは、システム管理者が MySQL ユーザ アカウントを作成し、アカウントに権利を与える事を可能にします。GRANT を利用する為には、GRANT OPTION 権限を持ち、また自分が供与している権限を持つ必要があります。REVOKE ステートメントは、アカウント管理者が権限を削除する事に関連し、それを可能にします。詳しくは 項12.5.1.5. 「REVOKE 構文」 を参照してください。

MySQL アカウント情報は mysql データベースのテーブルに格納されています。このデータベースとアクセス コントロール システムについては 章?4. データベース管理 で詳しく説明されていますので、更なる詳細についてはこれを参照して下さい。

重要:MySQL のいくつかのリリース版は、新しい権限や特徴を追加する為に供与テーブルの構造の変更を紹介しています。MySQL の新しいバージョンを更新する時はいつでも、新しい機能を有効に利用できるようにする為に、供与テーブルを最新の構造に更新しなければいけません。詳しくは 項4.5.4. 「mysql_upgrade ? MySQL アップグレードのテーブル チェック」 を参照してください。

もし供与テーブルが、大文字と小文字が混在するデータベースかテーブル名を含む権限行を保持し、lower_case_table_names システム変数がゼロではない値に設定されたら、REVOKE をこれらの権限を廃止する為に利用する事はできません。供与テーブルを直接コントロールする必要があるかも知れません。(GRANTlower_case_table_names が設定された時にそのような行を作成しませんが、そのような行は変数を設定する前に作成されていた可能性があります。)

権限はいくつかのレベルで供与する事ができます:

  • グローバル レベル

    既存サーバ上では、グローバル権限は全てのデータベースに適応します。これらの権限は mysql.user テーブル内に格納されています。GRANT ALL ON *.*REVOKE ALL ON *.* はグローバル権限だけを供与、廃止します。

  • データベース レベル

    データベース権限は既存データベース内の全てのオブジェクトに適応します。これらの権限は mysql.dbmysql.host テーブル内に格納されています。GRANT ALL ON db_name.*REVOKE ALL ON db_name.* はグローバル権限だけを供与、廃止します。

  • テーブル レベル

    テーブル権限は既存テーブル内の全てのカラムに適応します。これらの権限は mysql.tables_priv テーブル内に格納されています。GRANT ALL ON db_name.tbl_nameREVOKE ALL ON db_name.tbl_name はグローバル権限だけを供与、廃止します。

  • カラム レベル

    カラム権限は既存テーブル内の単一カラムに適応します。これらの権限は mysql.columns_priv テーブル内に格納されています。REVOKE を利用している時は、供与されたカラムと同じカラムを指定する必要があります。

  • ルーチン レベル

    CREATE ROUTINEALTER ROUTINEEXECUTE、そして GRANT 権限はストアド ルーチンに適応します。(ファンクションとプロシージャ)それらは、グローバルとデータベース レベルで供与されます。また、CREATE ROUTINE 以外は、これらの権限は各ルーチンに対してルーチン レベルで供与する事ができ、mysql.procs_priv テーブル内で格納されます。

object_type 条項は、次のオブジェクトがテーブル、ストアド ファンクション、またはストアド ルーチンの時には TABLEFUNCTION、または PROCEDURE 条項として指定されなければいけません。

GRANTREVOKE ステートメントに対しては、priv_type は次の表にある物として指定する事ができます。

権限意味
ALL [PRIVILEGES]GRANT OPTION 以外の全てのシンプルな権限を設定します。
ALTERALTER TABLE の使用を可能にします。
ALTER ROUTINEストアド ルーチンの変更、ドロップを可能にします。
CREATECREATE TABLE の使用を可能にします。
CREATE ROUTINEストアド ルーチンの作成を可能にします。
CREATE TEMPORARY TABLESCREATE TEMPORARY TABLE の使用を可能にします。
CREATE USERCREATE USERDROP USERRENAME USER、そして REVOKE ALL PRIVILEGES の使用を可能にします。
CREATE VIEWCREATE VIEW の使用を可能にします。
DELETEDELETE の使用を可能にします。
DROPDROP TABLE の使用を可能にします。
EVENTイベントスケジューラがイベントを作成するのを可能にします。
EXECUTEユーザがストアドルーチンを起動させるのを可能にします。
FILESELECT ... INTO OUTFILELOAD DATA INFILE の使用を可能にします。
INDEXCREATE INDEXDROP INDEX の使用を可能にします。
INSERTINSERTの使用を可能にします。
LOCK TABLESSELECT 権限を持つテーブル上の LOCK TABLES の使用を可能にします。
PROCESSSHOW FULL PROCESSLIST の使用を可能にします。
REFERENCESインプリメントされていません。
RELOADFLUSH の使用を可能にします。
REPLICATION CLIENTユーザがスレーブとマスタの場所を問い合わせる事を可能にします。
REPLICATION SLAVE複製スレーブが必要とします。 (マスタからバイナリ ログ イベントを読み込む為)
SELECTSELECT の使用を可能にします。
SHOW DATABASESSHOW DATABASES は全てのデータベースを表示します。
SHOW VIEWSHOW CREATE VIEWの使用を可能にします。
SHUTDOWNmysqladmin shutdown の使用を可能にします。
SUPERCHANGE MASTERKILLPURGE MASTER LOGS、そして SET GLOBAL ステートメントの使用を可能にし、 the mysqladmin debug コマンドはmax_connections が達成していても接続を (一回) 許可します。
TRIGGERユーザがトリガを作成、ドロップするのを可能にします。
UPDATEUPDATE の使用を可能にします。
USAGE権限が無い」 の同義語です。
GRANT OPTION権限を与えるのを可能にします。

EVENTTRIGGER 権限は MySQL 5.1.6 で追加されました。 トリガはテーブルと関連しているので、トリガを作成したり、ドロップしたりするには、トリガではなくテーブルに TRIGGER 権限を持つ必要あります。(MySQL 5.1.6 以前では SUPER 権限はトリガを作成したりドロップしたりする為に必要でした。)

REFERENCES 権限は現在は利用されていません。

USAGE は、権限を持たないユーザを作成した時に指定する事ができます。

アカウントがどんな権限を持つのかを決定する為には SHOW GRANTS を利用してください。詳しくは 項12.5.4.16. 「SHOW GRANTS 構文」 を参照してください。

ON *.* 構文を利用してグローバル権限を、または、ON db_name.* 構文を利用してデータベース権限を割り当てる事ができます。もし ON * を指定し、デフォルト データベースを選択したら、権限はそのデータベース内に供与されます。(警告: もし ON * を指定し、デフォルト データベースを選択 しなければ 、供与される権限はグローバルになります。

FILEPROCESSRELOADREPLICATION CLIENTREPLICATION SLAVESHOW DATABASESSHUTDOWN、そして SUPER 権限は、グローバルとしてのみ供与される(ON *.* 構文を利用して)管理権限です。

その他の権限は、グローバルに、またはより特定なレベルで供与する事ができます。

テーブルに指定できる priv_type 値は、SELECTINSERTUPDATEDELETECREATEDROPGRANT OPTIONINDEXALTERCREATE VIEWSHOW VIEW そして TRIGGER です。

カラムに指定できる priv_type 値は (column_list 条項を利用する時)、SELECTINSERT、そして UPDATE です。

ルーチン レベルで指定できる priv_type 値は ALTER ROUTINEEXECUTE、そして GRANT OPTION です。CREATE ROUTINE は、最初にルーチンを作成する時にこの権限を持たなければいけないので、ルーチン レベル権限ではありません。

GRANT ALL は、与えようとしているレベルに存在する権限のみをグローバル、データベース、テーブル、そしてルーチン レベルに対して割り当てます。例えば、GRANT ALL ON db_name.* はデータベース レベル ステートメントなので、 FILE のようなグローバルのみの権限は供与しません。

MySQL は、存在しないデータベース オブジェクト上にも権限を与える事を許容します。そのような場合、供与される権限は CREATE 権限を含む必要があります。この動作は意図的であり、また後で作成されるデータベース オブジェクトに対するユーザ アカウントと権限を、データベース管理者が準備する事を可能にします。

重要:MySQL は、テーブルやデータベースをドロップする時に、自動的に権限を廃止しません。しかし、もしルーチンをドロップすると、そのルーチンに供与された全てのルーチン レベル権限は廃止されます。

注意:‘_’ と ‘%’ ワイルドカードは、権限をグローバル、またはデータベース レベルで供与する GRANT ステートメント内でデータベース名を指定する時に許容されます。 これは例えば、データベース名の一部として ‘_’ 文字を利用したければ、ワイルドカードのパターンに一致する追加データベースにアクセスする事を不可能にする為に、GRANT ステートメント内でこれを ‘\_’ として指定必要がるという事を意味します。例えば、GRANT ... ON `foo\_bar`.* TO ... のようになります。

任意ホストからユーザに供与権を適応させる為に、MySQL は user_name@host_name の形で user 値を指定する事をサポートします。もし user_namehost_name 値が引用されていない識別子として正当であれば、それを引用する必要はありません。しかし、引用句は特別な文字(‘-’ 等のような)を含む user_name 文字列、または特別な文字やワイルドカード文字(‘%’ 等のような)を含む host_name 文字列を指定するのに必要です。例えば、'test-user'@'test-hostname' のようになります。ユーザ名とホスト名を別々に引用してください。

ホスト名の中でワイルドカードを指定する事ができます。例えば、user_name@'%.loc.gov' は、loc.gov ドメイン内のどのホストに対しても user_name に適応し、user_name@'144.155.166.%'144.155.166 クラス C サブネット内のどのホストに対しても、user_name に適応します。

シンプルな形 user_name は、user_name@'%' の同義語です。

MySQL はユーザ名内でワイルドカードをサポートしません。.匿名のユーザは、User='' を持つエントリを mysql.user テーブル内に挿入する事、または GRANT を利用してユーザを空の名前で作成する事で定義されます。

GRANT ALL ON test.* TO ''@'localhost' ...

引用された値、引用データベース、テーブル、カラム、そしてルーチン名を識別子として指定する時は、バッククォートを利用しています。(‘`’)ホスト名、ユーザ名、そしてパスワードを文字列として、単一引用句(‘'’)を利用して引用してください。

警告:匿名ユーザが MySQL サーバに接続する事を許可するなら、全てのローカル ユーザにも user_name@localhost として権限を供与する必要があります。そうでなければ、名づけられたユーザがローカル マシンから MySQL サーバにログインしようとした時に、mysql.user テーブル内(MySQL インストールの最中に作成された物)の localhost の匿名ユーザ アカウントが利用されます。 詳細に関しては 項4.7.5. 「アクセス制御の段階 1: 接続確認」 を参照して下さい。

匿名ユーザをリスト アップしてある次のクエリを実行する事によって、これが当てはまるかどうかを決定する事ができます。

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

もし先ほど説明した問題を防ぐ為に、ローカル匿名ユーザ アカウントを削除したければ、次のステートメントを利用してください。

DELETE FROM mysql.user WHERE Host='localhost' AND User='';
FLUSH PRIVILEGES;

GRANT は最大60文字のホスト名をサポートします。データベース、テーブル、カラム、そしてルーチン名は最大64文字です。ユーザ名は最大16文字です。注意:ユーザ名の許容長さは、mysql.user テーブルを変更しても変える事はできません。もしそれをすると、ユーザが MySQL サーバにログインできなくなってしまうような、予想不可能な動作に陥る可能性があります。項4.5.4. 「mysql_upgrade ? MySQL アップグレードのテーブル チェック」 に説明のある、MySQL AB で規定されている方法を利用する以外は、mysql データベース内のテーブルは、どんな方法でも絶対に変更してはいけません。

テーブル、カラム、ルーチンの権限は、各権限レベルの権限の論理的な OR として相加的に形成されています。例えば、もし mysql.user テーブルが、ユーザはグローバル SELECT 権限を持つ、と指定すると、その権限はデータベース、テーブル、またはカラムレベルのエントリによって否定する事はできません。

カラムの権限は次のように計算する事ができます。

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

ほとんどの場合、たった1つの権限レベルでユーザに対して権利を供与する為、実際にはこれほど複雑では有りません。権限チェックの方法の詳細については、項4.7. 「MySQL アクセス権限システム」 で紹介されています。

もし mysql.user テーブルに存在しないユーザ名/ホスト名の組み合わせに権限を供与するのであれば、エントリが追加されそれは DELETE ステートメントで削除されるまでそこに残ります。言い換えると、GRANTuser テーブル エントリを作成するかもしれませんが、REVOKE はそれらを削除しません。 従ってそれは DROP USERDELETE を明示的に利用して行わなければいけません。

警告:もし新しいユーザを作成して IDENTIFIED BY 条項を指定しないと、そのユーザはパスワードを持ちません。これはとても不安定です。しかし、新規ユーザに空ではないパスワードを提供する為に IDENTIFIED BY が与えられない限り、GRANT が新規ユーザを作成するのを防ぐ為に NO_AUTO_CREATE_USER SQL モードを有効にする事ができます。

MySQL Enterprise MySQL ネットワーク モニタリングとアドバイス サービスは、パスワードが無いユーザ アカウントを明確に防いでいます。更なる情報については、http://www-jp.mysql.com/products/enterprise/advisors.html を参照してください。

もし新規ユーザが作成されたり、グローバル供与権限を持っていたら、ユーザのパスワードは、IDENTIFIED BY 条項があればそれによって指定された物に設定されます。もしユーザが既にパスワードを持っていたら、それは新しい物と置き換えられます。

パスワードは SET PASSWORD ステートメントで設定する事もできます。詳しくは 項12.5.1.6. 「SET PASSWORD 構文」 を参照してください。

IDENTIFIED BY 条項内では、パスワードは直定数パスワード値でなければいけません。PASSWORD() 関数を SET PASSWORD ステートメントに対する時と同じように使用する必要はありません。例:

GRANT ... IDENTIFIED BY 'mypass';

もしパスワードを明確なテキストで送信したく無い場合、PASSWORD() がそのパスワードに返すハッシュ化された値が分かっていれば、キーワード PASSWORD の前にハッシュ化された値を指定する事ができます。

GRANT ...
IDENTIFIED BY PASSWORD '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4';

C プログラムの中では、make_scrambled_password() C API 関数を利用する事で、ハッシュ化された値を得る事ができます。

もしデータベースに権限を供与すると、mysql.db テーブル内のエントリが必要に応じて作成されます。もしデータベースの全ての権限が REVOKE で削除されると、このエントリも削除されます。

SHOW DATABASES 権限は SHOW DATABASE ステートメントを発行する事によって、アカウントがデータベース名を見る事を可能にします。この権限を持たないアカウントは、それらが権限を持つデータベースだけを見て、また、もしサーバが --skip-show-database オプションでスタートされていれば、ステートメントを利用する事は全くできません。

MySQL Enterprise SHOW DATABASES 権限は、MySQL サーバ上で全てのデータベースを見る必要があるユーザにだけ与えられます。MySQL ネットワーク モニタリングとアドバイス サービスの読者は、サーバが --skip-show-database オプション無しでスタートされた時に変更されます。追加情報については http://www-jp.mysql.com/products/enterprise/advisors.html を参照してください。

もしユーザがテーブルに何の権限も持たなければ、ユーザがテーブルのリストを要求した時(例えば、SHOW TABLES ステートメントを利用して)テーブル名は表示されません。

WITH GRANT OPTION 条項は、ユーザが指定された権限レベルで持つ権限を、別のユーザに与える事ができる機能を与えます。異なる権限を持つ2つのユーザは権限を接合できる事があるので、どのユーザに GRANT OPTION 権限を与えるのか注意する必要があります。

自分が持たない権限を別のユーザに与える事はできません。GRANT OPTION 権限によって、自分が持つ権限を割り当てる機能のみ与えられます。

特定の権限レベルでユーザに GRANT OPTION 権限を与える時は、そのユーザがそのレベルで持つどんな権限も、(または将来与えられる物も)そのユーザから別のユーザに与える事ができるので、注意が必要です。ユーザにデータベース上で INSERT 権限を与えると仮定してください。その時もし SELECT 権限をデータベース上で与え、WITH GRANT OPTION を指定すると、そのユーザは別のユーザに SELECT 権限だけではなく INSERT も与える事ができます。その時もしデータベース上でユーザに UPDATE 権限を与えると、そのユーザは INSERTSELECT、そして UPDATE を与える事ができるようになります。

非管理者ユーザに対しては、ALTER 権限をグローバルに与えたり、またはそれを mysql データベースに与えたりするべきでは有りません。もしそれをしてしまうと、残りのテーブルによってそのユーザが権限システムを破壊する事が可能になってしまいます!

MAX_QUERIES_PER_HOUR countMAX_UPDATES_PER_HOUR count、そして MAX_CONNECTIONS_PER_HOUR count オプションは、1時間の間にユーザが行う事ができるクエリ、更新、そしてログインの数を制限します。(クエリ キャッシュから結果が与えられるクエリは MAX_QUERIES_PER_HOUR 制限に対してカウントしません。)もし count0 なら(デフォルト)、そのユーザには制限がないという意味になります。

MAX_USER_CONNECTIONS count オプションは、そのアカウントが作成する事ができる同時接続の最大数を制限します。もし count0 なら(デフォルト)、max_user_connections システム変数はそのアカウントの同時接続数を決定します。

注意:既存権限に影響を与えずに、既に存在するユーザにこれらのリソース制限オプションを指定するには、GRANT USAGE ON *.* ... WITH MAX_... を利用して下さい。

詳しくは 項4.8.4. 「ユーザ リソースの制限」 を参照してください。

MySQL は、ユーザ名とパスワードに基づいた通常認証に加え、X509 証明拡張子を確認する事ができます。 SSL 関連オプションを MySQL アカウントに指定するには GRANT ステートメントの REQUIRE 条項を利用してください。(MySQL を利用した SSL 利用の背景情報については、項4.8.7. 「接続安全」 を参照してください。)

与えられたアカウントの接続を制限するには、いくつかの異なる方法があります。

  • REQUIRE NONE は、アカウントが SSL や X509 要求を持たないという事を指示します。もし SSL 関連 REQUIRE オプションが指定されれば、これがデフォルトになります。もしユーザ名とパスワードが有効なら、暗号化されていない接続が許可されます。しかし、クライアントのオプションにより、もしそのクライアントが正しい証明とキー ファイルを持っていれば、暗号化された接続もまた利用できます。それは、クライアントは SSL コマンドオプションを指定する必要がなく、その場合接続は暗号化されていない物になる、という事です。暗号化された接続を利用するには、クライアントは --ssl-ca オプションか、または --ssl-ca--ssl-key、または --ssl-cert オプションの3つ全てを指定する必要があります。

  • REQUIRE SSL オプションは、サーバに対して、SSL 暗号化接続だけをアカウントに許容するよう指示を出します。

    GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
      IDENTIFIED BY 'goodsecret' REQUIRE SSL;
    

    接続するには、クライアントは --ssl-ca オプションを指定し、また追加で --ssl-key--ssl-cert オプションを指定する必要があります。

  • REQUIRE X509 は、クライアントが有効な証明書を持つ必要があるが、その証明書、発行者、そして題目は何でもかまわないという事を意味します。要求されるのは、CA 証明の1つによってそのサインを検証できなければいけない、という事だけです。

    GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
      IDENTIFIED BY 'goodsecret' REQUIRE X509;
    

    接続するには、クライアントは --ssl-ca--ssl-key--ssl-cert オプションを指定する必要があります。

    これは REQUIRE オプションが X509 の意味を含む為、ISSUERSUBJECT にとっても同じ事が言えます。

  • REQUIRE ISSUER 'issuer' は、クライアントが CA 'issuer' によって発行された有効な X509 証明を提示するよう、接続に制限を与えます。もしクライアントが、有効ではあるが異なる発行者による証明を提示したら、サーバは接続を拒否します。X509 証明の利用は、必ず暗号化を暗示しますので、SSL オプションはこの場合必要ありません。

    GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
      IDENTIFIED BY 'goodsecret'
      REQUIRE ISSUER '/C=FI/ST=Some-State/L=Helsinki/
        O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com';
    

    'issuer' 値は単一文字列として入力されなければいけない事を覚えておいて下さい。

  • REQUIRE SUBJECT 'subject' は、クライアントがサブジェクト subject を含む有効な X509 証明を提示する接続に制限を与えます。もしクライアントが、有効ではあるが異なるサブジェクトによる証明を提示したら、サーバは接続を拒否します。

    GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
      IDENTIFIED BY 'goodsecret'
      REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
        O=MySQL demo client certificate/
        CN=Tonu Samuel/Email=tonu@example.com';
    

    'subject' 値は単一文字列として入力されなければいけない事を覚えておいて下さい。

  • REQUIRE CIPHER 'cipher' は十分な強さの暗号とキー長さが利用される事が保証されていなければいけません。SSL 自体は、短い暗号キーを利用している古いアルゴリズムが利用されると、弱くなる事があります。このオプションを利用すると、接続を許可する為に特定の暗号方法が利用されるように依頼する事ができます。

    GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
      IDENTIFIED BY 'goodsecret'
      REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';
    

SUBJECTISSUER、そして CIPHER オプションを、次のように REQUIRE 条項の中で組み合わせる事ができます。

GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
  IDENTIFIED BY 'goodsecret'
  REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
    O=MySQL demo client certificate/
    CN=Tonu Samuel/Email=tonu@example.com'
  AND ISSUER '/C=FI/ST=Some-State/L=Helsinki/
    O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com'
  AND CIPHER 'EDH-RSA-DES-CBC3-SHA';

AND キーワードは REQUIRE オプションとの間では任意です。

オプションの順番は重要では有りませんが、2回指定できるオプションはありません。

mysqld がスタートする時、全ての権限はメモリの中に読み込まれます。詳細に関しては 項4.7.7. 「権限の変更が反映するタイミング」 を参照して下さい。

1つのユーザに対してテーブル、カラム、またはルーチン権限を利用していると、サーバはテーブル、カラム、そしてルーチン権限を全てのユーザに対して分析し、その為に MySQL のスピードが少し遅くなります。同じように、もしユーザに対してクエリ、更新または接続の数を制限すると、サーバはそれらの値を監視しなければいけません。

SQL と MySQL GRANT バージョンとの最大の違いは次のような物です。

  • MySQL では、権限はユーザ名だけではなく、ホスト名とユーザ名の組み合わせと関連しています。

  • スタンダード SQL はグローバル、またはデータベース レベル権限を持たず、MySQL がサポートする全ての権限タイプのサポートもしません。

  • MySQL はスタンダード SQL UNDER 権限をサポートしません。

  • スタンダード SQL 権限は、階層的な様式で構造されています。もしユーザを削除すると、そのユーザが持つ全ての権限が与えられ、削除されます。もし DROP USER を利用するなら、MySQL でも同じです。詳しくは 項12.5.1.2. 「DROP USER 構文」 を参照してください。

  • スタンダード SQL では、テーブルをドロップすると、そのテーブルの全ての権限は削除されます。スタンダード SQL では、権限を削除すると、その権限に基づいて与えられた全ての権限もまた削除されます。MySQL では、明示的な REVOKE ステートメントだけの利用、または MySQL 供与テーブル内に格納された値の複製でドロップできます。

  • MySQL では、テーブル内のいくつかのカラムに対してだけ INSERT 権限を持つ事が可能です。この場合、INSERT 権限を持っていないそれらのカラムを削除するのであれば、テーブル上で INSERT ステートメントを実行する事ができます。削除されたカラムは、もしストリクト SQL モードが有効でなければ、暗黙的なデフォルト値に設定されます。ストリクト モードでは、もし削除されたカラムがデフォルト値を持たなければ、ステートメントは却下されます。(スタンダード SQL は、全てのカラムに INSERT 権限を持つように要求します。)項4.2.6. 「SQL モード」 で、ストリクト モードについて説明されています。項10.1.4. 「データタイプデフォルト値」 で暗黙のデフォルト値について説明されています。

12.5.1.4. RENAME USER 構文

RENAME USER old_user TO new_user
    [, old_user TO new_user] ...

RENAME USER ステートメントは既存 MySQL アカウントをリネームします。それを利用する為には、mysql データベースにグローバル CREATE USER 権限か UPDATE 権限を持つ必要があります。もし古いアカウントが存在しない時、または新しいアカウントが存在する時はエラーが発生します。各アカウントは、例えば、'jeffrey'@'localhost' のように GRANT ステートメントと同じフォーマットを利用して名づけられます。もしアカウント名のユーザ名部分だけを指定すると、ホスト名の '%' 部分が利用されます。アカウント名の指定についての追加情報に関しては、項12.5.1.3. 「GRANT 構文」 を参照してください。

RENAME USER は、ユーザが作成したデータベース オブジェクトを自動的に移動させたり、リネーム前にユーザが持っていた権限を移動させたりしません。これは、テーブル、ビュー、ストアド ルーチン、トリガ、そしてイベントに適応します。

12.5.1.5. REVOKE 構文

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

REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...

REVOKE ステートメントは、システム管理者が MySQL アカウントから権限を削除する事を可能にします。REVOKE を利用する為には、GRANT OPTION 権限を持ち、また自分が削除しようとしている権限を持っている必要があります。 各アカウントは、例えば、'jeffrey'@'localhost' のように GRANT ステートメントと同じフォーマットを利用して名づけられます。もしアカウント名のユーザ名部分だけを指定すると、ホスト名の '%' 部分が利用されます。アカウント名の指定についての追加情報に関しては、項12.5.1.3. 「GRANT 構文」 を参照してください。

どのレベルにどの権限が存在するのか、許容 priv_type 値、そしてユーザとパスワードを指定する為の構文については、項12.5.1.3. 「GRANT 構文」 を参照してください。

もし供与テーブルが、大文字と小文字が混在するデータベースかテーブル名を含む権限行を保持し、lower_case_table_names システム変数がゼロではない値に設定されたら、REVOKE をこれらの権限を廃止する為に利用する事はできません。供与テーブルを直接コントロールする必要があるかも知れません。(GRANTlower_case_table_names が設定された時にそのような行を作成しませんが、そのような行は変数を設定する前に作成されていた可能性があります。)

全ての権限を削除するには、名づけられた全てのユーザに対して、全てのグローバル、データベース、テーブル、そしてカラム レベルの権限をドロップする次の構文を利用してください。

REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...

この REVOKE 構文を利用する為には、mysql データベースにグローバル CREATE USER 権限か UPDATE 権限を持つ必要があります。

REVOKE は権限を削除しますが、user テーブル エントリのドロップはしません。それは DELETEDROP USER を利用して明示的に行う必要があります。(項12.5.1.2. 「DROP USER 構文」 を参照してください。)

12.5.1.6. SET PASSWORD 構文

SET PASSWORD [FOR user] = PASSWORD('some password')

SET PASSWORD ステートメントは既存 MySQL ユーザ アカウントにパスワードを割り当てます。

FOR 条項無しで、このステートメントは現在のユーザにパスワードを設定します。非匿名アカウントを利用しているサーバに接続したクライアントは、そのアカウントのパスワードを変更する事ができます。

このステートメントは、FOR 条項を利用して、現在のサーバ ホスト上の特定のアカウントにパスワードを設定します。mysql データベースの UPDATE 権限を持つクライアントだけがこれを実行できます。user 値は、user_namehost_name が、mysql.user テーブル エントリの UserHost カラム内でリストされているのと全く同じである user_name@host_name フォーマット内で与えられる必要があります。 例えば、もし 'bob''%.loc.gov'UserHost カラム値と共にエントリを持っていたら、 ステートメントを次のように書くでしょう。

SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');

これは、次のステートメントと同等です。

UPDATE mysql.user SET Password=PASSWORD('newpass')
  WHERE User='bob' AND Host='%.loc.gov';
FLUSH PRIVILEGES;

注意:もし MySQL 4.1 または pre-4.1 クライアント プログラムを利用するそれ以降のサーバに接続していたら、項4.7.9. 「MySQL 4.1 のパスワードハッシュ」 を読むまでは、前出の SET PASSWORDUPDATE ステートメントを利用しないでください。MySQL 4.1 で変更されたパスワード フォーマット、そして特定の状況下では、もしパスワードを変更するとその後サーバに接続する事ができなくなる、という事が起こり得ます。

SELECT CURRENT_USER() を実行する事によって、どのアカウントとしてサーバが認証したのかを見る事ができます。

12.5.2. テーブル メンテナンス ステートメント

12.5.2.1. ANALYZE TABLE 構文

ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...

ANALYZE TABLE はテーブルのキーの分布を分析、格納します。分析の最中に、テーブルは MyISAM のリード ロックを利用してロックされます。InnoDB には、テーブルは書き込みロックでロックされます。このステートメントは MyISAMInnoDB テーブルと共に機能します。MyISAM テーブルにとっては、このステートメントは myisamchk --analyze を利用する事と同じです。

解析が InnoDB 内でどのように機能するのかという事に関する情報については、項13.5.16. 「InnoDB テーブル上の制約」 を参照してください。

MySQL は、定数以外の何かに対して接合を実行した時、どの順番でテーブルが接合されるべきかを決める為に格納されたキー分布を利用します。

このステートメントはテーブルに SELECTINSERT 権限を要求します。

ANALYZE TABLE は次のカラムを利用して結果セットを返します。

カラム
Tableテーブル名
Opいつも analyze
Msg_typestatuserrorinfo、または warning の1つ
Msg_textメッセージ

SHOW INDEX ステートメントを利用して格納されたキー分布を確認する事ができます。詳しくは 項12.5.4.17. 「SHOW INDEX 構文」 を参照してください。

もしテーブルが前回の ANALYZE TABLE ステートメント以降変更されていなければ、そのテーブルは再解析されません。

ANALYZE TABLE ステートメントは、任意の NO_WRITE_TO_BINLOG キーワード(またはそのエイリアス LOCAL)が利用されない限り、バイナリ ログに書きこまれます。これは、複製マスタとして機能している MySQL サーバ上で利用される ANALYZE TABLE ステートメントが、複製スレーブにデフォルトで複製される為に行われます。

12.5.2.2. BACKUP TABLE 構文

BACKUP TABLE tbl_name [, tbl_name] ... TO '/path/to/backup/directory'

注意:このステートメントは廃止予定です。オンライン バックアップ機能を提供する、より良い代替を準備中です。その間、mysqlhotcopy スクリプトを代わりに利用する事ができます。

BACKUP TABLE は、バッファされた変更をディスクにフラッシュした後、テーブルを格納するのに必要な最低数のテーブル ファイルをバックアップ ディレクトリにコピーします。このステートメントは MyISAM テーブルにしか機能しません。それは .frm 定義と .MYD データフ ァイルをコピーします。.MYI インデックス ファイルは、それら2つのファイルから回復する事ができます。ディレクトリは、完全なパス名として指定されなければいけません。テーブルを復旧させるには、RESTORE TABLE を利用してください。

バックアップの最中に、バックアップされるのに従って、各テーブルに対して1つずつリード ロックが行われます。もしいくつかのテーブルをスナップショットとしてバックアップしたければ(バックアップ操作の最中にそれらが変更されるのを防ぎながら)まずグループ内の全てのテーブルに対してリード ロックを取得する為に、LOCK TABLES ステートメントを発行してください。

BACKUP TABLE は次のカラムを利用して結果セットを返します。

カラム
Tableテーブル名
Opいつも backup
Msg_typestatuserrorinfo、または warning の1つ
Msg_textメッセージ

12.5.2.3. CHECK TABLE 構文

CHECK TABLE tbl_name [, tbl_name] ... [option] ...

option = {FOR UPGRADE | QUICK | FAST | MEDIUM | EXTENDED | CHANGED}

CHECK TABLE はテーブルのエラーを確認します。CHECK TABLEMyISAMInnoDB、そして ARCHIVE テーブルにのみ機能します。MySQL 5.1.9 から、CHECKCSV テーブルにも有効になりました。 項13.11. 「CSV ストレージエンジン」 を参照してください。MyISAM テーブルに対しては、キー統計もまた更新されます。

CHECK TABLE は、既に存在していないビュー定義内で参照されるテーブルなどのような、ビューの問題も確認できます。

CHECK TABLE は次のカラムを利用して結果セットを返します。

カラム
Tableテーブル名
Opいつも check
Msg_typestatuserrorinfo、または warning の1つ
Msg_textメッセージ

ステートメントは各確認済テーブルにたくさんの情報行を作成する可能性がある事に注意してください。最後の行は statusMsg_type 値を持ち、Msg_text は通常 OK になります。もし OKTable is already up to date が得られなければ、通常はテーブルの修復を起動する必要があります。詳しくは 項4.9.4. 「テーブル保守とクラッシュ リカバリ」 を参照してください。Table is already up to date は、そのテーブルのストレージ エンジンが、そのテーブルを確認する必要は無いと指示しているという意味です。

FOR UPGRADE オプションは、名づけられたテーブルが現在の MySQL バージョンと互換性があるか確認します。このオプションは MySQL 5.1.7 で追加されました。サーバは FOR UPGRADE を利用し、作成された時以降、各テーブルに対してデータ タイプやインデックスに互換性の無い変更があったかどうかを確認します。もし無ければ、その確認は成功です。反対に、もし非適応性があれば、サーバはテーブルに対して総確認を行います。(少々時間がかかります。)もし総確認が成功すれば、サーバはテーブルの .frm ファイルに現在の MySQL バージョン番号をマークします。.frm ファイルをマークする事で、同じバージョンのサーバによるそのテーブルの今後の確認が早くなる事が保証されます。

データタイプの格納フォーマットが変更されたか、そのソート順が変更された為に、非適合性が発生する可能性があります。私たちの目的はそれらの変更を避ける事ですが、時として各リリースの間に、非適合性よりもさらに深刻である問題を修正する事の方が大切な事もあります。

現在は、FOR UPGRADE でこれらの非適合性が見つかっています。

  • MySQL 4.1 と 5.0 の間で、InnoDBMyISAM テーブルの為の TEXT カラム内の最後の空白のインデックス順が変更されました。

  • 新しい DECIMAL データタイプの格納方法は MySQL 5.0.3 と 5.0.5 の間に変更されました。

それ以外のチェックポイントは次のテーブルに表されています。これらのオプションは MyISAM テーブルの確認だけに適応し、InnoDB テーブルとビューでは無視されます。

タイプ意味
QUICK不正リンクの確認の為に行をスキャンしないでください。
FAST適切に閉じられていないテーブルだけを確認してください。
CHANGED最後の確認以降変更されたか、または正常に閉じられていないテーブルだけを確認してください。
MEDIUM削除されたリンクが有効である事を検証する為に行をスキャンしてください。これは行のキー チェックサムも計算し、それをキーの為に計算されたチェックサムを利用して検証します。
EXTENDED各行の全てのキーに対して総キー参照を行ってください。これはテーブルが100%整合性がある事を保証しますが、時間がかかる作業です。

もし QUICKMEDIUM、または EXTENDED のどのオプションも指定されなければ、動的フォーマットである MyISAM テーブルのデフォルトの確認タイプは MEDIUM になります。これは、テーブル上で myisamchk --medium-check tbl_name を起動させるのと同じ結果になります。CHANGEDFAST が指定されない限り、静的フォーマットの MyISAM テーブルのデフォルトの確認タイプは、MEDIUM です。その場合、デフォルトは QUICK です。行はめったに破壊されないので、CHANGEDFAST の行スキャンは省かれます。

テーブルが正しく閉じられているかどうかの確認の為に簡単なチェックを行っている次の例のように、確認オプションを組み合わせる事も可能です。

CHECK TABLE test_table FAST QUICK;

注意:場合によっては CHECK TABLE でテーブルが変更されます。これは、テーブルが 「corrupted」 や 「not closed properly」 と印されているにも関わらず、CHECK TABLE がそのテーブル内に何の問題も発見できない時に起こります。この場合、CHECK TABLE はテーブルに OK の印をつけます。

もしテーブルが破損すると、その問題はデータ部分ではなく、ほとんどインデックス内にあるでしょう。これまでに紹介された全ての確認タイプはインデックスをくまなく確認するので、ほとんどのエラーを見つける事ができるはずです。

もし OK であると思われるテーブルを確認したければ、確認オプションは利用しない、または利用するのであれば QUICK オプションを利用しなければいけません。急いでいる為、QUICK がデータ ファイル中に何のエラーも発見しないかもしれないという小さいリスクを負う事ができる場合には、後者を利用してください。(ほとんどの場合、通常の利用条件下であれば、MySQL はデータ ファイル中に何らかのエラーを発見するはずです。その場合、そのテーブルは 「corrupted」 と印が付けられ、修復されるまでは利用できなくなります。)

FASTCHANGED は、テーブルを頻繁に確認したい場合に、スクリプト(例えば、cron から実行されるように)から利用されるようになっています。ほとんどの場合、FASTCHANGED より好まれます。(MyISAM コード内にバグを見つけた可能性がある場合のみ、この方法は好ましくありません。)

通常確認を起動した後で、MySQL が行を更新したりキーで行を見つけたりする時に、テーブルから変なエラーが発生する場合のみEXTENDED が利用されます。これは通常確認が成功した場合は、めったに起こらないでしょう。

CHECK TABLE によって報告されたいくつかの問題は自動的に修復されません。

  • Found row where the auto_increment column has the value 0.

    これは、 AUTO_INCREMENT インデックス カラムが0の値を含むテーブル内に行を持っている事を意味します。(UPDATE ステートメントを利用して、カラムを明示的に 0 に設定する事で、AUTO_INCREMENT カラムが 0 である行を作成する事が可能です。)

    これ自体はエラーではないのですが、このテーブルを一度ダンプしそれを復旧させる、またはテーブル上に ALTER TABLE を実行する事を決めた時に問題を引き起こします。この場合、AUTO_INCREMENT カラムは、複製キー エラーのような問題を引き起こす可能性がある AUTO_INCREMENT カラムのルールに従って値を変更します。

    警告を除去するには、カラム値を0以外の値に設定する為に UPDATE ステートメントを実行してください。

12.5.2.4. CHECKSUM TABLE 構文

CHECKSUM TABLE tbl_name [, tbl_name] ... [ QUICK | EXTENDED ]

CHECKSUM TABLE はテーブル チェックサムを報告します。

QUICK を利用すると、ライブ テーブル チェックサムが有効であればそれが報告され、有効でなければ NULL を利用できます。これはとても速いです。ライブ チェックサムは、テーブルを作成した時に CHECKSUM=1 テーブル オプションを指定する事によって有効になります。これは現在は MyISAM テーブルにだけサポートされています。詳しくは 項12.1.8. 「CREATE TABLE 構文」 を参照してください。

EXTENDED を利用すると、テーブル全体が一行ごとに読まれ、チェックサムが計算されます。 大きいテーブルでは時間がかかります。

もし QUICKEXTENDED のどちらも指定されない場合、テーブル ストレージ エンジンがライブ チェックサムをサポートし、またそうでない場合にはテーブルをスキャンするのであれば、MySQL がライブ チェックサムを返します。

存在しないテーブルに対しては、CHECKSUM TABLENULL を返し、警告を生成します。

チェックサムの値はテーブル行フォーマットによって決まります。もし行フォーマットが変更されれば、チェックサムもまた変更されます。例えば、VARCHAR の格納フォーマットは MySQL 4.1 と 5.0 の間に変更されたので、もし4.1のテーブルが MySQL 5.0 にアップグレードされると、チェックサム値も変更されるでしょう。

12.5.2.5. OPTIMIZE TABLE 構文

OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...

もしテーブルの大部分を削除したり、変数長行で何箇所もテーブルを変更した場合は(VARCHARVARBINARYBLOB、または TEXT カラムを持つテーブル)、OPTIMIZE TABLE を利用しなければいけません。

削除された行はリンクされたリスト内で保存され、後続の INSERT 操作は古い行の位置を再利用します。使用されていないスペースの再要求をし、データ ファイルをデフラグするには OPTIMIZE TABLE を利用する事ができます。

このステートメントはテーブルに SELECTINSERT 権限を要求します。

ほとんどの設定で、OPTIMIZE TABLE を利用する必要は全くありません。可変長行の更新を頻繁にするとしても、特定のテーブルに対してだけ、この作業を週に一度、または月に一度以上する必要はありません。

OPTIMIZE TABLEMyISAMInnoDB テーブルに対して のみ 機能します。これは、NDB ディスク データ テーブルを含むその他のストレージ エンジンを利用して作成されたテーブルには機能 しません

MyISAM テーブルに対しては、OPTIMIZE TABLE は次のように機能します。

  1. もしテーブルが行を削除したり分割したりすると、テーブルを修復します。

  2. もしインデックス ページがソートされていなければ、それらをソートします。

  3. もしテーブルの統計が最新でなければ、(そしてインデックスをソートする事で修復が完了されなければ)それらを更新します。

InnoDB テーブルに対しては、 インデックス統計とクラスタされたインデックス内の使用されていないフリー スペースを更新する為にテーブルを復元する ALTER TABLEOPTIMIZE TABLE がマップされます。

--skip-new--safe-mode オプションを利用して mysqld をスタートさせる事で、OPTIMIZE TABLE が別のストレージ エンジン上で機能させる事ができます。この場合、OPTIMIZE TABLE は単に ALTER TABLE にマップされます。

OPTIMIZE TABLE は次のカラムを利用して結果セットを返します。

カラム
Tableテーブル名
Opいつも optimize
Msg_typestatuserrorinfo、または warning の1つ
Msg_textメッセージ

MySQL は OPTIMIZE TABLE が起動している最中にテーブルを調べるという事に注意してください。

OPTIMIZE TABLE ステートメントは、任意の NO_WRITE_TO_BINLOG キーワード(またはそのエイリアス LOCAL)が利用されない限り、バイナリ ログに書きこまれます。これは、複製マスタとして機能している MySQL サーバ上で利用される OPTIMIZE TABLE ステートメントが、複製スレーブにデフォルトで複製される為に行われます。

OPTIMIZE TABLE は、POINT カラム上の空間インデックスのような、R-tree インデックスをソートしません。(バグ #23578)

12.5.2.6. REPAIR TABLE 構文

REPAIR [LOCAL | NO_WRITE_TO_BINLOG] TABLE
    tbl_name [, tbl_name] ... [QUICK] [EXTENDED] [USE_FRM]

REPAIR TABLE は破損された可能性があるテーブルを修復します。これはデフォルトで、myisamchk --recover tbl_name と同じ効果を持っています。REPAIR TABLEMyISAMARCHIVE テーブルに対して機能します。MySQL 5.1.9 から、REPAIRCSV テーブルにも有効になりました。 項13.4. 「MyISAM ストレージエンジン」項13.10. 「ARCHIVE ストレージエンジン」、そして 項13.11. 「CSV ストレージエンジン」 を参照してください。

このステートメントはテーブルに SELECTINSERT 権限を要求します。

通常は、このステートメントは一度も実行する必要はありません。しかし、もし大変な失敗をしてしまった時は REPAIR TABLE を利用すると全てのデータを MyISAM テーブルから取り戻す事ができます。もしテーブルが頻繁に破損する場合は、REPAIR TABLE を利用する必要性を減らす為にその原因を見つける努力が必要です。項B.1.4.2. 「What to Do If MySQL Keeps Crashing」項13.4.4. 「MyISAM テーブルの問題点」 を参照して下さい。

警告:もし REPAIR TABLE 操作の最中にサーバが停止してしまったら、再起動した直後に、他の操作をする前にすぐにもう一度 REPAIR TABLE ステートメントを実行しなければいけません。(バックアップを作成してスタートさせるのが良いでしょう。)最悪の場合、データ ファイルの情報を何も持たない新しい綺麗なインデックス ファイルを得て、その次に行う操作によってデータ ファイルが上書きされてしまう事もあるでしょう。実際に起こる可能性は低い事ですが、起こり得るシナリオです。

REPAIR TABLE は次のカラムを利用して結果セットを返します。

カラム
Tableテーブル名
Opいつも repair
Msg_typestatuserrorinfo、または warning の1つ
Msg_textメッセージ

REPAIR TABLE ステートメントは各修復済テーブルにたくさんの情報行を作成する可能性があります。最後の行は statusMsg_testMsg_type 値を持ち、Msg_text は通常 OK になります。もし OK ではなかったら、myisamchk --safe-recover を利用してテーブルを修復してみる必要があります。(REPAIR TABLEmyisamchk の全てのオプションをまだインプリメントしていません。)myisamchk --safe-recover を利用すると、--max-record-length のような REPAIR TABLE がサポートしていないオプションを利用する事ができます。

もし QUICK が与えられたら、REPAIR TABLE はインデックス ツリーのみを修復しようと試みます。このタイプの修正は myisamchk --recover --quick によって行われた物と似ています。

もし EXTENDED を利用すると、MySQL は1つのインデックスをソートしながら一度に作成する代わりに、1つの行ごとに作成します。このタイプの修正は myisamchk --recover --quick によって行われた物と似ています。

REPAIR TABLE に有効な USE_FRM モードもあります。もし .MYI インデックス ファイルがなくなっていたり、そのヘッダが破損していたらこれを利用してください。このモードでは、MySQL は .frm ファイルからの情報を利用して .MYI ファイルを再作成します。この種類の修復は myisamchk ではできません。注意:このモードは、通常の REPAIR モードを利用できない時 のみ 利用してください。.MYI ヘッダは REPAIR ... USE_FRM 内で失われた重要なテーブル メタデータ(具体的には、現在の AUTO_INCREMENT 値と Delete link)を含んでいます。この情報は .MYI ファイル内にも格納されているので、テーブルが圧縮された時には USE_FRM を利用しないでください。

REPAIR TABLE ステートメントは、任意の NO_WRITE_TO_BINLOG キーワード(またはそのエイリアス LOCAL)が利用されない限り、バイナリ ログに書きこまれます。これは、複製マスタとして機能している MySQL サーバ上で利用される REPAIR TABLE ステートメントが、複製スレーブにデフォルトで複製される為に行われます。

12.5.2.7. RESTORE TABLE 構文

RESTORE TABLE tbl_name [, tbl_name] ... FROM '/path/to/backup/directory'

RESTORE TABLEBACKUP TABLE で作成されたバックアップからテーブルを復旧します。ディレクトリは、完全なパス名として指定されなければいけません。

既存テーブルは上書きされません。もしそのようなテーブルを修復させようとするとエラーが発生します。BACKUP TABLE と同じで、RESTORE TABLE は現在 MyISAM テーブルにしか機能しません。修復されたテーブルはマスタからスレーブに複製されません。

各テーブルのバックアップは、その .frm フォーマット ファイルと .MYD データ ファイルで構成されています。修復操作はそれらのファイルを修復し、そして .MYI インデックス ファイルを再構築する為にそれらを利用します。修復操作は、インデックスを再構築する必要がある為、バックアップ作業よりも時間がかかります。テーブルが長いインデックスを持っていれば、その分時間も長くかかります。

RESTORE TABLE は次のカラムを利用して結果セットを返します。

カラム
Tableテーブル名
Opいつも restore
Msg_typestatuserrorinfo、または warning の1つ
Msg_textメッセージ

12.5.3. SET 構文

SET variable_assignment [, variable_assignment] ...

variable_assignment:
      user_var_name = expr
    | [GLOBAL | SESSION] system_var_name = expr
    | [@@global. | @@session. | @@]system_var_name = expr

SET ステートメントは、サーバやクライアントの操作に影響を与える、様々なタイプの変数に値を割り当てます。MySQL の古いバージョンは SET OPTION を採用していましたが、OPTION を持たない SET がより好まれるようになった為、この構文は廃止される事になりました。

このセクションでは、システム変数やユーザ変数に値を割り当てる SET の利用について説明します。変数に関するこれらのタイプの一般情報については 項4.2.3. 「システム変数」項8.4. 「ユーザによって定義された変数」 を参照してください。システム変数も、項4.2.4. 「システム変数の使用」 で説明されているように、サーバ起動時に設定する事ができます。

SET 構文異型のいくつかが、別のコンテキストで利用されています。

次の説明は、変数を設定する為に利用する事ができる、異なる SET 構文を表しています。例では = 代入演算子を利用していますが、:= 演算子も許容されています。

ユーザ変数は @var_name として書かれ、次のように設定されます。

SET @var_name = expr;

多くのシステム変数は動的であり、SET ステートメントを利用してサーバが起動している間に変更する事ができます。(リストついては、項4.2.4.2. 「動的システム変数」 をご覧ください。)

SET を利用してシステム変数を変更するには、任意で修飾子が先行する var_name として参照してください。

  • 変数がグローバルである事を明示的に指示する為には、その名前に GLOBAL@@global. を先行させてください。SUPER 権限はグローバル変数を設定する為に要求されます。

  • 変数がセッションである事を明示的に指示する為には、その名前に SESSION@@global. を先行させてください。セッション変数を設定するのに特別な権限は必要とされませんが、クライアントは自分自身のセッション変数以外は変更できませんので、別のクライアントの物は変更できません。

  • LOCAL@@local.SESSION@@session. の同義語です。

  • もし修飾子が何もなければ、SET はセッション変数を変更します。

A SET ステートメントは、カンマで区切られた複数変数割り当てを含む事ができます。もし複数のシステム変数を設定したら、ステートメント内の一番最近の GLOBALSESSION 修飾子が、指定された修飾子を持たない次の変数に利用されます。

例:

SET sort_buffer_size=10000;
SET @@local.sort_buffer_size=10000;
SET GLOBAL sort_buffer_size=1000000, SESSION sort_buffer_size=1000000;
SET @@sort_buffer_size=1000000;
SET @@global.sort_buffer_size=1000000, @@local.sort_buffer_size=1000000;

SET を利用してシステム変数に値を割り当てた時、(起動オプションでは可能なように)値の中でサフィックス文字を利用する事はできません。しかし、その値は式の形を取る事ができます。

SET sort_buffer_size = 10 * 1024 * 1024;

システム変数の @@var_name 構文は、別のデータベースとの互換性の為にサポートされています。

もしセッション システム変数を変更すると、セッションが終了するまで、または変数を異なる値に変更するまではその値は効果を持ち続けます。別のクライアントは変更を見る事ができません。

もしグローバル システム変数を変更すると、その値はサーバが再起動するまでの間記憶され、次の接続に利用されます。(グローバル システム変数を永久的な物にするには、それをオプション ファイルに設定する必要があります。)そのグローバル変数にアクセスする全てのクライアントが変更を見る事ができます。しかしその変更は、変更が行われた後に接続するクライアントの、対応するセッション変数に対してだけ影響を与えます。グローバル変数の変更は、現在接続中のクライアントのセッション変数には影響を与えません。(SET GLOBAL ステートメントを発行するクライアントにも)

不正使用を防ぐ為に、もし SET GLOBALSET SESSION とだけ利用できる変数と共に利用したり、グローバル変数を設定する時に GLOBAL (または @@global.)を指定しなかったりすると、MySQL はエラーを作成します。

SESSION 変数を GLOBAL 値に、または GLOBAL 値をコンパイル インされた MySQL デフォルト値に設定するには、DEFAULT キーワードを利用してください。例えば、次の2つのステートメントは max_join_size のセッション値をグローバル値に設定する上で同一です。

SET max_join_size=DEFAULT;
SET @@session.max_join_size=@@global.max_join_size;

全てのシステム変数を DEFAULT に設定できる訳では有りません。そのような場合、DEFAULT の利用はエラーを引き起こします。

@@ 修飾子の1つを利用する事で、式の中の特定のグローバル、またはシステム変数の値を参照する事ができます。例えば、このようにして SELECT ステートメント内の値を検索する事ができます。

SELECT @@global.sql_mode, @@session.sql_mode, @@sql_mode;

@@var_name (@@global.@@session. を指定しない場合)のような式でシステム変数を参照する時、MySQL はセッション値が存在すればそれを返し、そうでなければグローバル値を返します。(これは、毎回セッション値を参照する SET @@var_name = value とは異なります。)

システム変数名と値を表示するには、SHOW VARIABLES ステートメントを利用してください。(詳しくは 項12.5.4.30. 「SHOW VARIABLES 構文」 を参照してください。)

次のリストは、非スタンダード構文を持つオプションについて説明しています。システム変数のリスト中に無い物は、項4.2.3. 「システム変数」 で説明されています。ここで説明されているオプションが SHOW VARIABLES で表示されていないとしても、SELECT を利用してそれらの値を得る事ができます。(CHARACTER SETSET NAMES は例外です。)例:

mysql> SELECT @@AUTOCOMMIT;
+--------------+
| @@AUTOCOMMIT |
+--------------+
|            1 |
+--------------+

これらのオプションは、大文字でも小文字でもかまいません。

  • AUTOCOMMIT = {0 | 1}

    オート コミット モードを設定してください。もし1に設定すると、テーブルの全ての変更がすぐに効果を発揮します。もし0に設定すると、トランザクションを受け入れる為には COMMIT、キャンセルするには ROLLBACK を利用しなければいけません。デフォルトで、AUTOCOMMIT で始まるクライアント接続は1を設定します。もし AUTOCOMMIT モードを0から1に変更すると、MySQL は開いているトランザクションの自動 COMMIT を実行します。トランザクションを始める別の方法は、START TRANSACTIONBEGIN ステートメントを利用する方法です。詳しくは 項12.4.1. 「START TRANSACTIONCOMMIT、そして ROLLBACK 構文」 を参照してください。

  • BIG_TABLES = {0 | 1}

    もし1に設定すると、全てのテンポラリ テーブルは、メモリの中ではなくディスク上に格納されます。これはスピードが少し遅いですが、エラー The table tbl_name is full は、大きいテンポラリ テーブルを必要とする SELECT オペレーションにこれは起こりません。新しい接続のデフォルト値は0です。(メモリ内のテンポラリ テーブルを利用してください。)通常、メモリ内のテーブルは要求に従って自動的にディスク ベース テーブルに変換されるので、この変数を設定する必要は全くありません。(注意:この変数は以前は SQL_BIG_TABLES という名前でした。)

  • CHARACTER SET {charset_name | DEFAULT}

    これは与えられたマッピングを利用して全ての文字列をクライアントとの間でマップします。MySQL ソース分布の中で sql/convert.cc を編集する事で新しいマッピングを追加する事ができます。SET CHARACTER SET は3つのセッション システム変数を設定します。character_set_clientcharacter_set_results は与えたれた文字セットに設定され、 character_set_connectioncharacter_set_database の値に設定されます。詳しくは 項9.4. 「接続のキャラクタセットおよび照合順序」 を参照してください。

    デフォルトのマッピングは、値 DEFAULT を利用する事で復旧できます。デフォルトはサーバの設定によって決まります。

    SET CHARACTER SET の構文は、別のほとんどのオプションを設定している物とは異なる事を覚えておいて下さい。

  • FOREIGN_KEY_CHECKS = {0 | 1}

    もし1に設定すると(デフォルト)、InnoDB テーブルの外部キー制約が確認されます。もし0に設定すると、それらは無視されます。外部キー確認を無効にする事は、それらの親/子供関係に要求される順番とは異なる順番で InnoDB を再ロードするのに役立ちます。詳しくは 項13.5.6.4. 「FOREIGN KEY 制約」 を参照してください。

    FOREIGN_KEY_CHECKS を0に設定する事もまた、データ定義ステートメントに影響を与えます。DROP SCHEMA は、スキーマ外のテーブルに参照される外部キーを持つテーブルを含んでいてもスキーマをドロップし、そして、DROP TABLE は別のテーブルに参照される外部キーを持つテーブルをドロップします。

    注意

    Setting FOREIGN_KEY_CHECKS を1に設定する事は、既存テーブル データのスキャンをトリガしません。従って、FOREIGN_KEY_CHECKS=0 の最中にテーブルに追加された行の一貫性の照合はされません。

  • IDENTITY = value

    この変数は LAST_INSERT_ID 変数の同義語です。これは別のデータベース システムとの互換性の為に存在します。この値は SELECT @@IDENTITY を利用して読む事ができ、SET IDENTITY を利用して設定する事ができます。

  • INSERT_ID = value

    AUTO_INCREMENT 値を挿入する時、次の INSERTALTER TABLE ステートメントで使用される値を設定してください。これは主にバイナリ ログと共に利用されます。

  • LAST_INSERT_ID = value

    LAST_INSERT_ID() から返される値を設定してください。これは、テーブルを更新するステートメント内で LAST_INSERT_ID() を利用する時にバイナリ ログ内に格納されます。この変数を設定する事で、mysql_insert_id() C API 関数に返される値は更新されません。

  • NAMES {'charset_name' [COLLATE 'collation_name'} | DEFAULT}

    SET NAMES は3つのセッション システム変数 character_set_clientcharacter_set_connection、そして character_set_results を与えられた文字セットに設定します。character_set_connectioncharset_name に設定すると、collation_connectioncharset_name のデフォルト照合に設定します。任意の COLLATE 条項は照合を明示的に指定するのに利用されるでしょう。詳しくは 項9.4. 「接続のキャラクタセットおよび照合順序」 を参照してください。

    デフォルトのマッピングは、値 DEFAULT を利用する事で復旧できます。デフォルトはサーバの設定によって決まります。

    SET NAMES の構文は、別のほとんどのオプションを設定している物とは異なる事を覚えておいて下さい。

  • ONE_SHOT

    このオプションは変数ではなく修飾子です。これは、文字セット、照合、そしてタイム ゾーンを設定する変数の効果に影響を与える為に利用する事ができます。ONE_SHOT は主に複製を目的として利用されます。文字セット、照合、そしてタイム ゾーン変数の値をロールフォーワードで元の形を反映させる為に、mysqlbinlog はそれらをテンポラリに修正できるよう SET ONE_SHOT を利用します。ONE_SHOT は内部的な利用の為だけの物で、MySQL 5.0 以降のバージョンでは廃止予定です。

    ONE_SHOT を許容された変数のセット以外の物と利用する事はできません。もし利用を試みると、次のようなエラーが発生します。

    mysql> SET ONE_SHOT max_allowed_packet = 1;
    ERROR 1382 (HY000): The 'SET ONE_SHOT' syntax is reserved for purposes
    internal to the MySQL server
    

    もし ONE_SHOT が許容された変数と共に利用されたら、それは要求されたとおりに変数を変更しますが、それは次の非 SET ステートメントに対してのみ行われます。その後、サーバは全ての文字セット、照合、そしてタイム ゾーンに関連したシステム変数を、以前の値に再設定します。例:

    mysql> SET ONE_SHOT character_set_connection = latin5;
    
    mysql> SET ONE_SHOT collation_connection = latin5_turkish_ci;
    
    mysql> SHOW VARIABLES LIKE '%_connection';
    +--------------------------+-------------------+
    | Variable_name            | Value             |
    +--------------------------+-------------------+
    | character_set_connection | latin5            |
    | collation_connection     | latin5_turkish_ci |
    +--------------------------+-------------------+
    
    mysql> SHOW VARIABLES LIKE '%_connection';
    +--------------------------+-------------------+
    | Variable_name            | Value             |
    +--------------------------+-------------------+
    | character_set_connection | latin1            |
    | collation_connection     | latin1_swedish_ci |
    +--------------------------+-------------------+
    
  • SQL_AUTO_IS_NULL = {0 | 1}

    もし1に設定すると(デフォルト)、次の構造を利用する事で AUTO_INCREMENT カラムを含む最後にテーブルに挿入された行を見つける事ができます。

    WHERE auto_increment_column IS NULL
    

    この動作は、Access のようないくつかの ODBC プログラムによって利用されます。

  • SQL_BIG_SELECTS = {0 | 1}

    もし0に設定すると、MySQL は、実行するのにとても時間がかかる SELECT ステートメントを異常終了します。(これはオプチマイザが、分析された行の数が max_join_size の値を超えると判断したステートメントの事です。)これは、得策では無い WHERE ステートメントが発行された時に便利な物です。新しい接続のデフォルト値は、全ての SELECT ステートメントを許容する1です。

    もし max_join_size システム変数を DEFAULT 以外の値に設定すると、SQL_BIG_SELECTS は0に設定されます。

  • SQL_BUFFER_RESULT = {0 | 1}

    もし1に設定すると、SQL_BUFFER_RESULT は結果が SELECT ステートメントからテンポラリ テーブルに置かれるように強制します。これは、MySQL がテーブル ロックを早く解除するのを助け、クライアントに結果を送るのに時間がかかる場合に有益な物になります。 デフォルト値は0です。

  • SQL_LOG_BIN = {0 | 1}

    もし0に設定すると、クライアントの為のバイナリ ログはログされません。クライアントはこのオプションを設定する為に SUPER 権限を持つ必要があります。デフォルト値は1です。

  • SQL_LOG_OFF = {0 | 1}

    もし1に設定すると、このクライアントの為の通常のクエリ ログはログされません。クライアントはこのオプションを設定する為に SUPER 権限を持つ必要があります。デフォルト値は0です。

  • SQL_LOG_UPDATE = {0 | 1}

    この変数は廃止予定であり、SQL_LOG_BIN にマップされています。

  • SQL_NOTES = {0 | 1}

    もし1に設定すると(デフォルト)、Note レベルの警告が記録されます。もし0に設定すると Note 警告は抑制されます。mysqldump はダンプ ファイルの再ロードが、その操作のインテグリティに影響しないイベントに対して警告を発行しないよう、この変数を0に設定する為にアウトプットを含みます。

  • SQL_QUOTE_SHOW_CREATE = {0 | 1}

    もし1に設定すると(デフォルト)、サーバは SHOW CREATE TABLESHOW CREATE DATABASE ステートメントに識別子を引用します。もし0に設定すると、引用は無効になります。このオプションは、引用を必要とする識別子に対して複製が機能するように、デフォルトで使用可能となっています。項12.5.4.9. 「SHOW CREATE TABLE 構文」項12.5.4.6. 「SHOW CREATE DATABASE 構文」 を参照して下さい。

  • SQL_SAFE_UPDATES = {0 | 1}

    もし1に設定すると、MySQL は WHERE 条項か LIMIT 条項内でキーを利用しない UPDATEDELETE ステートメントを異常終了します。これは、キーが正しく利用されずその為に多数の行を変更、または削除する UPDATEDELETE ステートメントをキャッチする事を可能にします。デフォルト値は0です。

  • SQL_SELECT_LIMIT = {value | DEFAULT}

    SELECT ステートメントから返される最大行数。新しい接続のデフォルト値は 「無制限」 です。もしその制限を変更すると、デフォルト値は DEFAULTSQL_SELECT_LIMIT 値を利用して復旧できます。

    もし SELECTLIMIT 条項を持っていたら、LIMITSQL_SELECT_LIMIT の値を上回ります。

    SQL_SELECT_LIMIT は、ストアド ルーチン内で実行された SELECT ステートメントに適応しません。それは、クライアントに戻される結果セットを作成しない SELECT ステートメントには適応しません。これらはサブクエリの中に SELECT ステートメント、CREATE TABLE ... SELECT、そして INSERT INTO ... SELECT を含んでいます。

  • SQL_WARNINGS = {0 | 1}

    この変数は、もし警告が発生したら、単列 INSERT ステートメントが情報を作成するかどうかをコントロールします。デフォルトは0です。情報文字列を作成するには、値を0に設定して下さい。

  • TIMESTAMP = {timestamp_value | DEFAULT}

    このクライアントに時刻を設定してください。これは、もし行の格納にバイナリ ログを利用するなら、元のタイムスタンプを得る為に利用されます。 timestamp_value は MySQL タイムスタンプではなく、ユニックス エポック タイムスタンプでなければいけません。

    SET TIMESTAMPNOW() に返された値に影響しますが、SYSDATE() に返された物には影響しません。これは、バイナリ ログ内のタイムスタンプ設定は SYSDATE() の起動に影響を持たないという意味です。サーバは、SYSDATE()NOW() のエイリアスになるよう働きかける為に --sysdate-is-now オプションでスタートでき、その場合、SET TIMESTAMP は両方の関数に影響を与えます。

  • UNIQUE_CHECKS = {0 | 1}

    もし1に設定すると(デフォルト)、InnoDB テーブル内の第二インデックスの一意性チェックが行われます。もし0に設定すると、ストレージ エンジンはインプット データ内に複製キーが存在しないと仮定する事を許可されます。もし、ご自分のデータに一意性違反が無い事が確かであれば、これを0に設定して InnoDB に大きいテーブルをインポートする際のスピードを早くする事ができます。

    この変数を0に設定する事は、ストレージ エンジンが複製キーを無視する事を 要求 する訳ではないと覚えておいて下さい。エンジンは複製キーの確認をし、もしそれらを発見したらエラーを発行する事が許可されています。

12.5.4. SHOW 構文

SHOW は、データベース、テーブル、カラム、またサーバのステータス情報などのような様々な情報を提供する多くの形を持っています。このセクションでは次のような物を紹介します。

SHOW AUTHORS
SHOW CHARACTER SET [LIKE 'pattern']
SHOW COLLATION [LIKE 'pattern']
SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [LIKE 'pattern']
SHOW CONTRIBUTORS
SHOW CREATE DATABASE db_name
SHOW CREATE EVENT event_name
SHOW CREATE FUNCTION funcname
SHOW CREATE PROCEDURE procname
SHOW CREATE TABLE tbl_name
SHOW CREATE VIEW view_name
SHOW DATABASES [LIKE 'pattern']
SHOW ENGINE engine_name {LOGS | STATUS | MUTEX}
SHOW [STORAGE] ENGINES
SHOW ERRORS [LIMIT [offset,] row_count]
SHOW [FULL] EVENTS
SHOW FUNCTION CODE sp_name
SHOW FUNCTION STATUS [LIKE 'pattern']
SHOW GRANTS FOR user
SHOW INDEX FROM tbl_name [FROM db_name]
SHOW INNODB STATUS
SHOW PROCEDURE CODE sp_name
SHOW PROCEDURE STATUS [LIKE 'pattern']
SHOW PLUGINS
SHOW PRIVILEGES
SHOW [FULL] PROCESSLIST
SHOW SCHEDULER STATUS
SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern']
SHOW TABLE STATUS [FROM db_name] [LIKE 'pattern']
SHOW [OPEN] TABLES [FROM db_name] [LIKE 'pattern']
SHOW TRIGGERS
SHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern']
SHOW WARNINGS [LIMIT [offset,] row_count]

SHOW ステートメントも、複製マスタとスレーブ マスタに関する情報を提供する形を持っており、それらは 項12.6. 「複製ステートメント」 で紹介されています。

SHOW BINARY LOGS
SHOW BINLOG EVENTS
SHOW MASTER STATUS
SHOW SLAVE HOSTS
SHOW SLAVE STATUS

もし与えられた SHOW ステートメントの構文が LIKE 'pattern' 部を含んでいたら、'pattern' は SQL ‘%’ と ‘_’ ワイルドカード文字を含む事ができる文字列になります。そのパターンは、一致する値へのステートメント アウトプットを制限するのに有効です。

いくつかの SHOW ステートメントは、どの行を表示するかを指定する事に対して柔軟性を提供する WHERE 条項も許容します。詳しくは 項21.27. 「SHOW ステートメントへの拡張」 を参照してください。

12.5.4.1. SHOW AUTHORS 構文

SHOW AUTHORS

SHOW AUTHORS ステートメントは、MySQL 上で働く人々の情報を表示します。それぞれの作者に対して、NameLocation、そして Comment 値を表示します。

このステートメントは、MySQL 5.1.3 で追加されました。

12.5.4.2. SHOW CHARACTER SET 構文

SHOW CHARACTER SET [LIKE 'pattern']

SHOW CHARACTER SET ステートメントは全ての有効な文字セットを表示します。これは、どの文字セット名が一致するかを指示する任意の LIKE 条項を取ります。例:

mysql> SHOW CHARACTER SET LIKE 'latin%';
+---------+-----------------------------+-------------------+--------+
| Charset | Description                 | Default collation | Maxlen |
+---------+-----------------------------+-------------------+--------+
| latin1  | cp1252 West European        | latin1_swedish_ci |      1 |
| latin2  | ISO 8859-2 Central European | latin2_general_ci |      1 |
| latin5  | ISO 8859-9 Turkish          | latin5_turkish_ci |      1 |
| latin7  | ISO 8859-13 Baltic          | latin7_general_ci |      1 |
+---------+-----------------------------+-------------------+--------+

Maxlen カラムは、一文字を格納するのに必要な最大バイト数を表示します。

12.5.4.3. SHOW COLLATION 構文

SHOW COLLATION [LIKE 'pattern']

SHOW COLLATION からのアウトプットは全ての有効な文字セットを含んでいます。これは、どの pattern が、どの照合名と一致するかを指示する任意の LIKE 条項を取ります。例:

mysql> SHOW COLLATION LIKE 'latin1%';
+-------------------+---------+----+---------+----------+---------+
| Collation         | Charset | Id | Default | Compiled | Sortlen |
+-------------------+---------+----+---------+----------+---------+
| latin1_german1_ci | latin1  |  5 |         |          |       0 |
| latin1_swedish_ci | latin1  |  8 | Yes     | Yes      |       0 |
| latin1_danish_ci  | latin1  | 15 |         |          |       0 |
| latin1_german2_ci | latin1  | 31 |         | Yes      |       2 |
| latin1_bin        | latin1  | 47 |         | Yes      |       0 |
| latin1_general_ci | latin1  | 48 |         |          |       0 |
| latin1_general_cs | latin1  | 49 |         |          |       0 |
| latin1_spanish_ci | latin1  | 94 |         |          |       0 |
+-------------------+---------+----+---------+----------+---------+

Default カラムは、照合がその文字セットにとってデフォルトであるかどうかを指示します。Compiled はその文字セットがサーバ内にコンパイルされるかどうかを指示します。Sortlen は、文字セットの中の文字列式をソートする為に必要とされるメモリの量と関係しています。

12.5.4.4. SHOW COLUMNS 構文

SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [LIKE 'pattern']

SHOW COLUMNS は与えられたテーブル内のカラムに関する情報を表示します。これはビューに対しても機能します。

FULL キーワードは、各カラムに対するプレ カラム コメントと同じように、アウトプットが今持っている権限を含むように働きかけます。

db_name.tbl_nametbl_name FROM db_name 構文の代替として利用する事ができます。言い換えると、これらの2つのステートメントは同等という事です。

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

SHOW FIELDS

SHOW COLUMNS の同義語です。テーブルのカラムを mysqlshow db_name tbl_name コマンドを利用してリストにする事もできます。

DESCRIBE ステートメントは SHOW COLUMNS に似た情報を提供します。詳しくは 項12.3.1. 「DESCRIBE 構文」 を参照してください。

12.5.4.5. SHOW CONTRIBUTORS 構文

SHOW CONTRIBUTORS

SHOW CONTRIBUTORS ステートメントは、MySQL のソ−スに貢献した人や、MySQL AB サポートを引き起こす情報を表示します。それぞれの貢献者に対して、 NameLocation、そして Comment 値を表示します。

このステートメントは、MySQL 5.1.12 で追加されました。

12.5.4.6. SHOW CREATE DATABASE 構文

SHOW CREATE {DATABASE | SCHEMA} db_name

与えられたデータベースを作成する CREATE DATABASE ステートメントを表示します。SHOW CREATE SCHEMASHOW CREATE DATABASE の同義語です。

mysql> SHOW CREATE DATABASE test\G
*************************** 1. row ***************************
       Database: test
Create Database: CREATE DATABASE `test`
                 /*!40100 DEFAULT CHARACTER SET latin1 */

mysql> SHOW CREATE SCHEMA test\G
*************************** 1. row ***************************
       Database: test
Create Database: CREATE DATABASE `test`
                 /*!40100 DEFAULT CHARACTER SET latin1 */

SHOW CREATE DATABASESQL_QUOTE_SHOW_CREATE オプションの値に従ってテーブルとカラム名を引用します。詳しくは 項12.5.3. 「SET 構文」 を参照してください。

12.5.4.7. SHOW CREATE EVENT

SHOW CREATE EVENT event_name

このステートメントは、与えられたイベントを再作成する為に必要な CREATE EVENT ステートメントを表示します。例えば、(同じイベント e_daily が定義され、その後 項12.5.4.15. 「SHOW EVENTS に変更された物を利用):

mysql> SHOW CREATE EVENT test.e_daily\G

*************************** 1. row ***************************
       Event: e_daily
Create Event: CREATE EVENT e_daily
                ON SCHEDULE EVERY 1 DAY
                STARTS CURRENT_TIMESTAMP + INTERVAL 6 HOUR
                ENABLE
                COMMENT 'Saves total number of sessions and
                         clears the table once per day.'
                DO
                  BEGIN
                    INSERT INTO site_activity.totals (when, total)
                      SELECT CURRENT_TIMESTAMP, COUNT(*) 
                      FROM site_activity.sessions;
                    DELETE FROM site_activity.sessions;
                  END

アウトプットは、それが作成されたステータスよりも、イベントの現在のステータス(ENABLE)を反映するという事を覚えておいて下さい。

このステートメントは、MySQL 5.1.6 でインプリメントされました。

12.5.4.8. SHOW CREATE PROCEDURESHOW CREATE FUNCTION 構文

SHOW CREATE {PROCEDURE | FUNCTION} sp_name

これらのステートメントは MySQL 拡張子です。それらは、SHOW CREATE TABLE と似て、名づけられたルーチンを再作成する為に利用できる精密な文字列を返します。そのステートメントは、あなたがそのルーチンの持ち主になるか、mysql.proc テーブルに SELECT アクセスを持つ事を要求します。

mysql> SHOW CREATE FUNCTION test.hello\G
*************************** 1. row ***************************
       Function: hello
       sql_mode:
Create Function: CREATE FUNCTION `test`.`hello`(s CHAR(20)) ≫
                 RETURNS CHAR(50)
                 RETURN CONCAT('Hello, ',s,'!')

12.5.4.9. SHOW CREATE TABLE 構文

SHOW CREATE TABLE tbl_name

与えられたテーブルを作成する CREATE TABLE ステートメントを表示します。このステートメントも、ビューと共に機能します。

mysql> SHOW CREATE TABLE t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE t (
  id INT(11) default NULL auto_increment,
  s char(60) default NULL,
  PRIMARY KEY (id)
) ENGINE=MyISAM

SHOW CREATE TABLESQL_QUOTE_SHOW_CREATE オプションの値に従ってテーブルとカラム名を引用します。詳しくは 項12.5.3. 「SET 構文」 を参照してください。

12.5.4.10. SHOW CREATE VIEW 構文

SHOW CREATE VIEW view_name

このステートメントは、与えられたビューを作成する CREATE VIEW ステートメントを表示します。

mysql> SHOW CREATE VIEW v;
+------+----------------------------------------------------+
| View | Create View                                        |
+------+----------------------------------------------------+
| v    | CREATE VIEW `test`.`v` AS select 1 AS `a`,2 AS `b` |
+------+----------------------------------------------------+

SHOW CREATE VIEW の利用は、問題になっているビューに SHOW VIEW 権限と SELECT 権限を必要とします。

VIEWS テーブルを含む INFORMATION_SCHEMA から、ビュー オブジェクトに関する情報を得る事ができます。詳しくは 項21.15. 「INFORMATION_SCHEMA VIEWS テーブル」 を参照してください。

12.5.4.11. SHOW DATABASES 構文

SHOW {DATABASES | SCHEMAS} [LIKE 'pattern']

SHOW DATABASES は MySQL サーバ ホスト上のデータベースをリストにします。SHOW SCHEMASSHOW DATABASES の同義語です。

グローバル SHOW DATABASES 権限を持っていない限り、自分が何かしらの権限を持つデータベースしか見る事ができません。mysqlshow コマンドを利用してこのリストを手に入れる事もできます。

もしサーバが --skip-show-database オプションを利用してスタートしたら、SHOW DATABASES 権限を持っていない限り、このステートメントを利用する事は絶対にできません。

SHOW SCHEMAS を利用する事もできます。

12.5.4.12. SHOW ENGINE 構文

SHOW ENGINE engine_name {LOGS | STATUS | MUTEX}

SHOW ENGINE はストレージ エンジンに関するログやステータス情報を表示します。現在次のステートメントがサポートされています。

SHOW ENGINE INNODB STATUS
SHOW ENGINE INNODB MUTEX
SHOW ENGINE NDB STATUS

SHOW ENGINE INNODB STATUSSHOW ENGINE INNODB MUTEX の古い(または廃止された)同義語は SHOW INNODB STATUSSHOW MUTEX STATUS です。

SHOW ENGINE INNODB STATUSInnoDB ストレージエンジンの状態に関する広範囲な情報を表示します。

InnoDB モニタは InnoDB 処理に関する追加情報を提供します。詳しくは 項13.5.11.1. 「SHOW ENGINE INNODB STATUSInnoDB モニタ」 を参照してください。

SHOW ENGINE INNODB MUTEXInnoDB ミューテックス統計を表示します。アウトプット フィールドは次に紹介されています。

  • Type

    常に InnoDB です。

  • Name

    それがインプリメントされたミューテックス名とソース ファイル。例:&pool->mutex:mem0pool.c

    ミューテックス名はその目的を指示します。例えば、log_sys ミューテックスは InnoDB ログ サブシステムに利用され、ログ活動がどれほど集中しているのかを指示します。buf_pool ミューテックスは InnoDB バッファ プールを保護します。

  • Status

    ミューテックス ステータスフィールドはいくつかの値を含んでいます。

    • count は、ミューテックスが何回要求されたかを指示します。

    • spin_waits はスピンロックが何回起動しなければいけなかったかを指示します。

    • spin_rounds はスピンロック ラウンドの数を指示します。(spin_roundsspin_waits で割ると、平均ラウンド カウントがわかります。)

    • os_waits は OS の待機数を指示します。これは、スピンロックが機能しなかった時に起こります。(ミューテックスはスピンロックの最中にロックされておらず、OSに従い、待つ必要がありました。)

    • os_yields はスレッドがミューテックスをロックしようと試みて、そのタイムスライスを放棄し、OSに従う回数を指示します。(別のスレッドが起動する事を許可すると、ミューテックスをロックする為にそれを自由にするという仮定の下。)

    • os_wait_times は、もし timed_mutexes システム変数が1であれば(ON)、OS 待機にかかった時間を(分で)指示します。 もし timed_mutexes が0であれば(OFF)タイミングが無効になるので、os_wait_times は0です。timed_mutexes はデフォルトでオフになっています。

このステートメントからの情報は、システムの問題を診断するのに利用する事ができます。例えば、spin_waitsspin_rounds の大きい値は拡張性の問題を指示するでしょう。

もしサーバが、有効な NDBCLUSTER ストレージ エンジンを持っていたら、SHOW ENGINE NDB STATUS は接続されたデータノード、クラスタ接続、そしてクラスタ ビンログ エポックなどのクラスタ ステータス情報を表示します。

SHOW ENGINE NDB STATUS からのアウトプット例はここに表されています。? MySQL 5.0 内のステートメントによって表示されていた物からかなり変更されている事に注意してください。

mysql> SHOW ENGINE NDB STATUS\G
*************************** 1. row ***************************
  Type: ndbcluster
  Name: connection
Status: cluster_node_id=6, connected_host=192.168.0.179,
connected_port=1186, number_of_storage_nodes=4,
number_of_ready_storage_nodes=4, connect_count=0  
*************************** 2. row ***************************
  Type: ndbcluster
  Name: binlog
Status: latest_epoch=0, latest_trans_epoch=2226134,
latest_received_binlog_epoch=0, latest_handled_binlog_epoch=0,
latest_applied_binlog_epoch=0  
2 rows in set (0.00 sec)

In MySQL 5.0 では、SHOW ENGINE INNODB MUTEXSHOW MUTEX STATUS として呼び出されます。後者のステートメントは似たような情報を表示しますが、それは少し異なるアウトプット フォーマットになります。

SHOW ENGINE BDB LOGS は以前は BDB ログ ファイルのステータス情報を表示しました。MySQL 5.1.12 にもあるように、BDB ストレージ エンジンはもうサポートされていませんし、このステートメントは警告を作成します。

12.5.4.13. SHOW ENGINES 構文

SHOW [STORAGE] ENGINES

SHOW ENGINES はサーバのストレージ エンジンについてのステータス情報を表示します。これは特に、ストレージ エンジンがサポートされているのか、またはデフォルト エンジンが何なのかを確認するのに便利です。SHOW TABLE TYPES は廃止予定の同義語です。

mysql> SHOW ENGINES\G
*************************** 1. row ***************************
      Engine: MEMORY
     Support: YES
     Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 2. row ***************************
      Engine: MyISAM
     Support: DEFAULT
     Comment: Default engine as of MySQL 3.23 with great performance
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 3. row ***************************
      Engine: InnoDB
     Support: YES
     Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
          XA: YES
  Savepoints: YES
*************************** 4. row ***************************
      Engine: EXAMPLE
     Support: YES
     Comment: Example storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 5. row ***************************
      Engine: ARCHIVE
     Support: YES
     Comment: Archive storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 6. row ***************************
      Engine: CSV
     Support: YES
     Comment: CSV storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 7. row ***************************
      Engine: BLACKHOLE
     Support: YES
     Comment: /dev/null storage engine (anything you write ≫
              to it disappears)
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 8. row ***************************
      Engine: FEDERATED
     Support: YES
     Comment: Federated MySQL storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 9. row ***************************
      Engine: MRG_MYISAM
     Support: YES
     Comment: Collection of identical MyISAM tables
Transactions: NO
          XA: NO
  Savepoints: NO

SHOW ENGINES からのアウトプットは、使用される MySQL バージョンや別の要因によって変わります。Support カラム内に表されている値は、ここに表されているように、別の機能に対するサーバのサポート レベルを指示します。

意味
YES機能はサポートされており、アクティブです。
NO機能はサポートされていません。
DISABLED機能はサポートされていますが、無効になっています。

NO の値は、サーバはその機能に対するサポート無しでコンパイルされた為、ランタイムに起動する事はできないという事を意味します。

DISABLED の値は、サーバがその機能を無効にするオプションを利用してスタートされたか、それを有効にする為に必要な全てのオプションが与えられなかった為に起こります。後者の場合、エラー ログ ファイルは、なぜオプションが無効になったのかを指示する理由を含んでいるはずです。詳しくは 項4.11.2. 「エラー ログ」 を参照してください。

もし、サーバがストレージ エンジンの DISABLED をサポートする為にコンパイルされたのに、--skip-engine オプションを利用してスタートされたら、それも発見するかもしれません。例えば、--skip-innodbInnoDB エンジンを無効にします。NDB Cluster ストレージ エンジンにとっては、DISABLED は、サーバは MySQL クラスタへのサポートを利用してコンパイルされたが、スタートするのに --ndb-cluster オプションは利用されなかった、という事を意味します。

全ての MySQL サーバは、MyISAM がデフォルトのストレージ エンジンなので、MyISAM テーブルをサポートします。

TransactionsXA、そして Savepoints カラムが MySQL 5.1.2 で追加されました。それらはそれぞれストレージ エンジンが、トランザクション、XA トランザクション、そしてセーブポイントをサポートするかどうかを指示します。

12.5.4.14. SHOW ERRORS 構文

SHOW ERRORS [LIMIT [offset,] row_count]
SHOW COUNT(*) ERRORS

このステートメントは、エラー、警告、そして注意を表示する代わりに、エラーのみを表示するという事以外、SHOW WARNINGS と似ています。

LIMIT 条項は SELECT ステートメントに対するのと同じ構文を持っています。詳しくは 項12.2.7. 「SELECT 構文」 を参照してください。

SHOW COUNT(*) ERRORS ステートメントはエラーの数を表示します。error_count 変数からもこの数字を検索する事ができます。

SHOW COUNT(*) ERRORS;
SELECT @@error_count;

更なる情報については、項12.5.4.31. 「SHOW WARNINGS 構文」 を参照してください。

12.5.4.15. SHOW EVENTS

SHOW EVENTS [FROM schema_name] [LIKE pattern]

SHOW EVENTS は、その一番シンプルな形で、現在のスキーマ内の全てのイベントをリストにします。

mysql> SELECT CURRENT_USER(), SCHEMA();
+----------------+----------+
| CURRENT_USER() | SCHEMA() |
+----------------+----------+
| jon@ghidora    | myschema |
+----------------+----------+
1 row in set (0.00 sec)

mysql> SHOW EVENTS\G
*************************** 1. row ***************************
            Db: myschema
          Name: e_daily
       Definer: jon@ghidora
          Type: RECURRING
    Execute at: NULL
Interval value: 10
Interval field: INTERVAL_SECOND
        Starts: 2006-02-09 10:41:23
          Ends: 0000-00-00 00:00:00
        Status: ENABLED
1 row in set (0.01 sec)

SHOW EVENTS のアウトプット内のカラム ? INFORMATION_SCHEMA.EVENTS テーブル内のカラムに似ているけれど同一ではない ? がここに表されています。

  • Db:イベントが定義されるスキーマ(データベース)

  • Name:イベント名。

  • Definer:イベントを作成したユーザアカウント。(username@hostname)

  • Type:ONE TIME (一時的な)か RECURRING の2つのうちの1つの値。

  • Execute At:一時的なイベントが実行される時の日付と時刻。DATETIME 値として表示されます。

    自動更新イベントにとっては、このカラムの値はいつでも NULL です。

  • Interval Value:自動更新イベントの為の、イベント実行の間のインターバルの回数。

    一時的イベントにとっては、このカラムの値はいつでも NULL です。

  • Interval Field:自動更新イベントが、次の実行までの間のインターバルに利用される時間単位。

    一時的イベントにとっては、このカラムの値はいつでも NULL です。

  • Starts:自動更新イベント開始の日付と時間。これは DATETIME 値として表示され、これはそのイベントに開始の日付と時間が定義されない時は空白です。(MySQL 5.1.8 以前は、このような場合 '0000-00-00 00:00:00' がデフォルトでした。)

    一時的イベントにとっては、このカラムの値はいつでも NULL です。

  • Ends:自動更新イベント終了の日付と時間。これは、そのイベント終了の日付と時刻が定義されていなければ、DATETIME 値として表示され、デフォルトは '0000-00-00 00:00:00' になります。

    一時的イベントにとっては、このカラムの値はいつでも NULL です。

  • Status:イベント ステータスENABLEDDISABLED のうちの1つです。

アクション ステートメントは SHOW EVENTS のアウトプット内に表示されていない事に注意してください。

注意:StartsEnds ('0000-00-00 00:00:00' 以外)を表示する値は、現在はユニバーサル タイムを利用しています。しかし、ユニバーサル タイムのこのコンテキスト内での利用は変更される予定ですので、アプリケーション内でこれに依存するべきでは有りません。 (バグ #16420)項21.20. 「INFORMATION_SCHEMA EVENTS テーブル」 もご参照ください。

異なるスキーマのイベントを見るには、FROM 条項を利用できます。例えば、もし test スキーマが前出の例の中で選択されていたら、次のステートメントを利用して myschema 上で定義されたイベントを見る事ができました。

SHOW EVENTS FROM myschema;

LIKE にパターンを1つプラスした物を利用して、イベント名上でこのステートメントに返されたリストをフィルタする事ができます。

このステートメントは、MySQL 5.1.6 で追加されました。

項21.20. 「INFORMATION_SCHEMA EVENTS テーブル」 もご参照下さい。

注意:MySQL 5.1.11 とそれ以前のバージョンでは、SHOW EVENTS は現在のユーザが定義者であるイベントだけを表示し、SHOW FULL EVENTS ステートメントは、与えられたスキーマ上で全てのユーザによって定義されたイベントを見る為に利用されていました。SHOW FULL EVENTS は MySQL 5.1.12 で削除されました。

12.5.4.16. SHOW GRANTS 構文

SHOW GRANTS [FOR user]

このステートメントは、MySQL ユーザ アカウントに供与された権限を複製する為に発行されなければいけない GRANT ステートメントをリストにします。アカウントは、例えば 'jeffrey'@'localhost' のように GRANT ステートメントと同じフォーマットを利用して名づけられます。もしアカウント名のユーザ名部分だけを指定すると、ホスト名の '%' 部分が利用されます。アカウント名の指定についての追加情報に関しては、項12.5.1.3. 「GRANT 構文」 を参照してください。

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

サーバに接続する為に利用している、アカウントに供与された権限をリストにする為に、次のステートメントを利用する事ができます。

SHOW GRANTS;
SHOW GRANTS FOR CURRENT_USER;
SHOW GRANTS FOR CURRENT_USER();

MySQL 5.1.12 にも有るように、もし SHOW GRANTS FOR CURRENT_USER (またはそれと同等な構文)が DEFINER コンテキスト内で利用されたら、SQL SECURITY DEFINER を利用して定義されたストアド プロシージャ内などで)、表示された供与物は、呼び出し元の物ではなく、定義者の物です。

SHOW GRANTS は名づけられたアカウントに明示的に供与された権限のみを表示します。そのアカウントに有効なその他の権限もあるかもしれませんが、それらは表示されません。例えば、もし匿名アカウントが存在したら、名づけられたアカウントはその権限を利用する事ができるかもしれませんが、SHOW GRANTS はそれらを表示しません。

12.5.4.17. SHOW INDEX 構文

SHOW INDEX FROM tbl_name [FROM db_name]

SHOW INDEX はテーブル インデックス情報を返します。そのフォーマットは、ODBC 内の SQLStatistics コールのそれと似ています。

SHOW INDEX は次のフィールドを返します。

  • Table

    テーブル名。

  • Non_unique

    もしインデックスが複製を含む事ができなければ0、もしできるなら1。

  • Key_name

    インデックス名

  • Seq_in_index

    1から始まる、インデックス内のカラム シーケンス番号

  • Column_name

    カラム名

  • Collation

    カラムがインデックス内でどのようにソートされるか。MySQL では、これは値 ‘A’ (昇順)か NULL (格納されない)を持つ事ができます。

  • Cardinality

    インデックス内の固有値数の見積もりこれは、ANALYZE TABLEmyisamchk -a を起動させる事で更新されます。Cardinality は、整数として格納された統計に基づいてカウントされるので、小さいテーブルに対してもその値は必ずしも精密ではありません。濃度が高ければ、その分 MySQL が接合を行う時にインデックスを利用する可能性は高くなります。

  • Sub_part

    もしカラムが部分的にだけインデックスされていた時のインデックスされる文字数、もしカラム全体がインデックスされていた時は NULL です。

  • Packed

    キーがどのようにパックされるのかを指示します。もしそうでなければ NULL です。

  • Null

    もしカラムが NULL を含んでいたら、YES を含みます。もしそうでなければ、カラムは NO を含みます。

  • Index_type

    使用されるインデックス方法(BTREEFULLTEXTHASHRTREE)

  • Comment

    様々な意見

db_name.tbl_nametbl_name FROM db_name 構文の代替として利用する事ができます。これらの2つのステートメントは同等です。

SHOW INDEX FROM mytable FROM mydb;
SHOW INDEX FROM mydb.mytable;

SHOW KEYS

SHOW INDEX の同義語です。テーブルのインデックスを mysqlshow db_name tbl_name コマンドを利用してリストにする事もできます。

12.5.4.18. SHOW INNODB STATUS 構文

SHOW INNODB STATUS

MySQL 5.1 では、これは廃止予定の SHOW ENGINE INNODB STATUS の同義語です。詳しくは 項12.5.4.12. 「SHOW ENGINE 構文」 を参照してください。

12.5.4.19. SHOW OPEN TABLES 構文

SHOW OPEN TABLES [FROM db_name] [LIKE 'pattern']

SHOW OPEN TABLES は、現在テーブル キャッシュ内で開かれている非 TEMPORARY テーブルをリストします。詳しくは 項6.4.8. 「MySQL でのテーブルのオープンとクローズの方法」 を参照してください。

SHOW OPEN TABLES は次のフィールドを返します。

  • Database

    テーブルを含むデータベース

  • Table

    テーブル名。

  • In_use

    クエリによってテーブルが現在使用されている回数。もしカウントがゼロなら、そのテーブルは開いていますが現在は利用されていません。

  • Name_locked

    テーブル名がロックされているかどうか名前ロックは、ドロップやテーブルのリネームのような操作に利用されます。

12.5.4.20. SHOW PLUGINS 構文

SHOW PLUGINS

SHOW PLUGINS は既知のプラグインの情報を表示します。

mysql> SHOW PLUGINS;
+------------+--------+----------------+---------+
| Name       | Status | Type           | Library |
+------------+--------+----------------+---------+
| MEMORY     | ACTIVE | STORAGE ENGINE | NULL    |
| MyISAM     | ACTIVE | STORAGE ENGINE | NULL    |
| InnoDB     | ACTIVE | STORAGE ENGINE | NULL    |
| ARCHIVE    | ACTIVE | STORAGE ENGINE | NULL    |
| CSV        | ACTIVE | STORAGE ENGINE | NULL    |
| BLACKHOLE  | ACTIVE | STORAGE ENGINE | NULL    |
| FEDERATED  | ACTIVE | STORAGE ENGINE | NULL    |
| MRG_MYISAM | ACTIVE | STORAGE ENGINE | NULL    |
+------------+--------+----------------+---------+

SHOW PLUGIN は MySQL 5.1.5 で追加され、5.1.9 で SHOW PLUGINS という名前に変わりました。(5.1.9 では SHOW PLUGIN は廃止予定で、警告を発します。)

12.5.4.21. SHOW PRIVILEGES 構文

SHOW PRIVILEGES

SHOW PRIVILEGES は MySQL サーバがサポートするシステム権限のリストを表示します。権限リストの詳細内容は、使用サーバのバージョンによって決まります。

mysql> SHOW PRIVILEGES\G
*************************** 1. row ***************************
Privilege: Alter
Context: Tables
Comment: To alter the table
*************************** 2. row ***************************
Privilege: Alter routine
Context: Functions,Procedures
Comment: To alter or drop stored functions/procedures
*************************** 3. row ***************************
Privilege: Create
Context: Databases,Tables,Indexes
Comment: To create new databases and tables
*************************** 4. row ***************************
Privilege: Create routine
Context: Functions,Procedures
Comment: To use CREATE FUNCTION/PROCEDURE
*************************** 5. row ***************************
Privilege: Create temporary tables
Context: Databases
Comment: To use CREATE TEMPORARY TABLE
...

12.5.4.22. SHOW PROCEDURE CODESHOW FUNCTION CODE 構文

SHOW {PROCEDURE | FUNCTION} CODE sp_name

これらのステートメントは、デバッグ サポートを利用して構築されたサーバに対してだけ有効な MySQL 拡張子です。それらは名づけられたルーチンの内部インプリメンテーション表現を表示します。そのステートメントは、あなたがそのルーチンの持ち主になるか、mysql.proc テーブルに SELECT アクセスを持つ事を要求します。

もし名づけられたルーチンが有効なら、各ステートメントは結果セットを作成します。結果セット内の各行は、ルーチン内の1つの 「instruction」 に対応します。最初のカラムは、0で始まる序数 Pos です。2つ目のカラムは、SQL ステートメントや(通常元のソースから変更された物)ストアド ルーチン ヘッダに対してだけ意味を持つコマンドを含む Instruction です。

mysql> DELIMITER //
mysql> CREATE PROCEDURE p1 ()
    -> BEGIN
    ->   DECLARE fanta INT DEFAULT 55;
    ->   DROP TABLE t2;
    ->   LOOP
    ->     INSERT INTO t3 VALUES (fanta);
    ->     END LOOP;
    ->   END//
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW PROCEDURE CODE p1//
+-----+----------------------------------------+
| Pos | Instruction                            |
+-----+----------------------------------------+
|   0 | set fanta@0 55                         |
|   1 | stmt 9 "DROP TABLE t2"                 |
|   2 | stmt 5 "INSERT INTO t3 VALUES (fanta)" |
|   3 | jump 2                                 |
+-----+----------------------------------------+
4 rows in set (0.00 sec)

この例の中では、非実行可能 BEGINEND ステートメントは無くなっており、DECLARE variable_name ステートメントに対しては、実行可能な部分だけが現れています。(デフォルトが割り当てられている部分)ソースから取り出された各ステートメントに対しては、後にタイプが続くコード文字 stmt があります。(9は DROP、5は INSERT を意味する、という感じの物です。)最終行は、GOTO instruction #2 という意味を持つ jump 2 指示を含んでいます。

これらのステートメントは、MySQL 5.1.3 で追加されました。

12.5.4.23. SHOW PROCEDURE STATUSSHOW FUNCTION STATUS 構文

SHOW {PROCEDURE | FUNCTION} STATUS [LIKE 'pattern']

これらのステートメントは MySQL 拡張子です。これらは、データベース、名前タイプ、作成者、そして作成日と変更日などのような、ルーチンの性質を返します。もしパターンが指定されなければ、どのステートメントを利用しているかによって、全てのストアド プロシージャや全てのストアド ファンクションの情報がリストされます。

mysql> SHOW FUNCTION STATUS LIKE 'hello'\G
*************************** 1. row ***************************
           Db: test
         Name: hello
         Type: FUNCTION
      Definer: testuser@localhost
     Modified: 2004-08-03 15:29:37
      Created: 2004-08-03 15:29:37
Security_type: DEFINER
      Comment:

INFORMATION_SCHEMA 内の ROUTINES テーブルからストアド ルーチンに関する情報を得る事もできます。詳しくは 項21.14. 「INFORMATION_SCHEMA ROUTINES テーブル」 を参照してください。

12.5.4.24. SHOW PROCESSLIST 構文

SHOW [FULL] PROCESSLIST

SHOW PROCESSLIST はどのスレッドが起動しているかを表示します。mysqladmin processlist コマンドを利用してこの情報を手に入れる事もできます。

もし PROCESS 権限を持っていれば、全てのスレッドを見る事ができます。そうでなければ、自分自身のスレッドのみ見る事ができます。(使用中のMySQL アカウントと関連しているスレッド)詳しくは 項12.5.5.3. 「KILL 構文」 を参照してください。もし FULL キーワードを利用しなければ、各ステートメントの最初の100文字だけが Info フィールドに表示されます。

MySQL Enterprise MySQL ネットワーク モニタリングとアドバイス サービス の読者は、プロセスが多すぎる時には、即時通知と専門家のアドバイスを受け取ります。追加情報については http://www-jp.mysql.com/products/enterprise/advisors.html を参照してください。

このステートメントは、「too many connections」 エラー メッセージを受け取り、何が起こっているのを確認したい時に大変役に立ちます。MySQL は、管理者がいつでもシステムに接続して確認できる事を保証する為、SUPER 権限を持つアカウントに利用される事ができる接続を1つ余分に確保します。(この権限を全てのユーザには与えていないと仮定しています。)

SHOW PROCESSLIST のアウトプットは、次のようになるでしょう。

mysql> SHOW FULL PROCESSLIST\G
*************************** 1. row ***************************
Id: 1
User: system user
Host:
db: NULL
Command: Connect
Time: 1030455
State: Waiting for master to send event
Info: NULL
*************************** 2. row ***************************
Id: 2
User: system user
Host:
db: NULL
Command: Connect
Time: 1004
State: Has read all relay log; waiting for the slave ≫
       I/O thread to update it
Info: NULL
*************************** 3. row ***************************
Id: 3112
User: replikator
Host: artemis:2204
db: NULL
Command: Binlog Dump
Time: 2144
State: Has sent all binlog to slave; waiting for binlog to be updated
Info: NULL
*************************** 4. row ***************************
Id: 3113
User: replikator
Host: iconnect2:45781
db: NULL
Command: Binlog Dump
Time: 2086
State: Has sent all binlog to slave; waiting for binlog to be updated
Info: NULL
*************************** 5. row ***************************
Id: 3123
User: stefan
Host: localhost
db: apollon
Command: Query
Time: 0
State: NULL
Info: SHOW FULL PROCESSLIST
5 rows in set (0.00 sec)

アウトプット カラムは次の意味を持っています。

  • Id

    接続識別子。

  • User

    ステートメントを発行した MySQL ユーザ。もしこれが system user であれば、タスクを内部的に取り扱う為に、サーバによって生み出された非クライアント スレッドを参照します。これは、複製スレーブか遅れた行のハンドラに利用される I/O または SQL スレッドになり得ます。 event_scheduler はスケジュールされたイベントをモニタするスレッドを参照する事ができます。system userevent_scheduler には、Host カラム内で指定されたホストはありません。

  • Host

    ステートメントを発行するクライアントのホスト名(ホストが無い system user 以外)。SHOW PROCESSLIST は、どのクライアントが何をしているかの究明を簡単にする為に、TCP/IP 接続のホスト名を host_name:client_port フォーマットで報告します。

  • db

    もし選択されれば、これがデフォルト データベースです。そうでなければ NULL です。

  • Command

    クライアント/サーバ プロトコルの COM_xxx コマンドに対応するカラムの値。詳しくは 項4.2.5. 「ステータス変数」 を参照してください。

    Command 値は、次のうちのどれかでしょう。Binlog Dump, Change userClose stmtConnectConnect OutCreate DBDaemonDebugDelayed insertDrop DBErrorExecuteFetchField ListInit DBKillLong DataPingPrepareProcesslistQueryQuitRefreshRegister SlaveReset stmtSet optionShutdownSleepStatisticsTable DumpTime

  • Time

    ステートメントやコマンドの開始から現在までの、秒表示での時間。

  • State

    次のうちのどれかになり得る、アクション、イベント、またはステート:After createAnalyzingChanging masterChecking master versionChecking tableConnecting to masterCopying to group tableCopying to tmp tableCreating delayed handlerCreating indexCreating sort indexCreating table from master dumpCreating tmp tableExecution of init_commandFULLTEXT initializationFinished reading one binlog; switching to next binlogFlushing tablesKilledKilling slaveLockedMaking temp file Opening master dump tableOpening tableOpening tablesProcessing requestPurging old relay logsQueueing master event to the relay logReading event from the relay logReading from netReading master dump table dataRebuilding the index on master dump tableReconnecting after a failed binlog dump requestReconnecting after a failed master event readRegistering slave on masterRemoving duplicatesReopen tablesRepair by sortingRepair doneRepair with keycacheRequesting binlog dumpRolling backSaving stateSearching rows for updateSending binlog event to slaveSending dataSorting for groupSorting for orderSorting indexSorting resultSystem lockTable lockThread initializedUpdatingUser lockWaiting for INSERTWaiting for master to send eventWaiting for master updateWaiting for slave mutex on exitWaiting for tableWaiting for tablesWaiting for the next event in relay logWaiting on condWaiting to finalize terminationWaiting to reconnect after a failed binlog dump requestWaiting to reconnect after a failed master event readWriting to netallocating local tablecleaning upclosing tablesconverting HEAP to MyISAMcopy to tmp tablecreating tabledeleting from main tabledeleting from reference tablesdiscard_or_import_tablespaceendfreeing itemsgot handler lockgot old tableinfoinitinsertlogging slow queryloginpreparingpurging old relay logsquery endremoving tmp tablerenamerename result tablereschedulesetupstarting slavestatisticsstoring row into queueunauthenticated userupdateupdatingupdating main tableupdating reference tablesupgrading lockwaiting for delay_listwaiting for handler insertwaiting for handler lockwaiting for handler openWaiting for event from ndbcluster

    最も一般的な State 値はこのセクションの残りの部分で説明されています。それ以外のほとんどの State 値は、サーバ内のバグを見つける為にだけ役に立ちます。複製サーバのプロセス ステートについての追加情報については、項5.5.1. 「レプリケーション実装の詳細」 も参照してください。

    SHOW PROCESSLIST ステートメントに対しては State の値は NULL です。

  • Info

    スレッドが実行中のステートメント、または、もしそれがステートメントを何も実行していなければ NULL になります。

SHOW PROCESSLIST からのアウトプット内で主に見られるいくつかの State

  • Checking table

    スレッドがテーブル チェック操作を行っています。

  • Closing tables

    スレッドが変更されたテーブル データをディスクにフラッシュしている、そして使用されたテーブルを閉じているという意味です。この操作スピードは早いでしょう。もし速くなければ、ディスクがフルではないという事と、ディスクがそれほど頻繁に使用されていないという事を証明しなければいけません。

  • Connect Out

    複製スレーブはそのマスタに接続しています。

  • Copying to group table

    もしステートメントが異なる ORDER BYGROUP BY 基準を持っていたら、行はグループによってソートされ、テンポラリ テーブルにコピーされます。

  • Copying to tmp table

    サーバはメモリ内のテンポラリ テーブルにコピーしています。

  • Copying to tmp table on disk

    サーバはディスク上のテンポラリ テーブルにコピーしています。テンポラリ結果セットは tmp_table_size よりも大きく、スレッドはメモリを保存する為にテンポラリ テーブルをイン メモリからディスク ベース フォーマットに変更しています。

  • Creating tmp table

    スレッドはクエリに結果の一部を保持する為にテンポラリ テーブルを作成しています。

  • deleting from main table

    サーバは複合テーブル削除の最初の部分を実行しています。最初のテーブルからの削除だけを行い、別の(参照)テーブルからの削除に利用されるフィールドとオフセットを保存しています。

  • deleting from reference tables

    サーバは複合テーブル削除の2番目の部分を行っており、別のテーブルから一致したテーブルを削除しています。

  • Flushing tables

    スレッドは FLUSH TABLES を実行しており、全てのスレッドがそのテーブルを閉じるのを待っています。

  • FULLTEXT initialization

    サーバは自然言語フル テキスト サーチを行う準備をしています。

  • 停止する

    誰かがスレッドに KILL ステートメントを送り、そして次にキル フラッグを見つけた時異常終了するはずです。そのフラッグは MySQL 内の主要な各ループ内で確認されますが、場合によってはスレッドが停止するまでに少し時間がかかる場合があります。もしスレッドが別のスレッドにロックされていると、停止作業は別のスレッドがそのロックを解除するとすぐに効果を発揮します。

  • Locked

    クエリは別のクエリによってロックされています。

  • Sending data

    スレッドは SELECT ステートメントの為に行を作成し、また、クライアントにデータを送っています。

  • Sorting for group

    スレッドは GROUP BY を満足させる為にソートを行っています。

  • Sorting for order

    スレッドは ORDER BY を満足させる為にソートを行っています。

  • Opening tables

    スレッドはテーブルをオープンしようと試みています。この操作は、何かにオープンを邪魔されない限り、スピードが速いはずです。例えば、ALTER TABLELOCK TABLE ステートメントは、そのステートメントが終了するまでテーブルのオープンを邪魔する事ができます。

  • Reading from net

    サーバはネットワークからパケットを読み込んでいます。

  • Removing duplicates

    クエリは、MySQL が早い段階で独特な操作を最適化する事ができなくなるような方法で SELECT DISTINCT を利用していました。この為、MySQL は結果をクライアントに送る前に全ての複製行を削除する為の特別な段階を必要とします。

  • Reopen table

    スレッドはテーブルの為にロックを得ましたが、その後基礎となるテーブル構造が変更された事に気が付きました。それはロックを解除し、テーブルを閉じ、そして再度オープンしようとしています。

  • Repair by sorting

    修復コードはインデックスを作成する為にソートを利用しています。

  • Repair with keycache

    修復コードはキー キャッシュを通してキー作成を1つ1つ利用しています。これは Repair by sorting と比べるとかなり遅い作業です。

  • Searching rows for update

    スレッドは、全ての一致する行を更新する前にそれらを見つける為の第一段階を行っています。もし UPDATE が、関連する行を見つける為に利用されたインデックスを変更していれば、これが行われなければいけません。

  • Sleeping

    スレッドは新しいステートメントをスレッドにに送る為のクライアントを待っています。

  • statistics

    サーバはクエリ実行計画を開発する統計を計算しています。

  • System lock

    スレッドは、テーブルの為の外部システム ロックを得るのを待っています。もし同じテーブルにアクセスする複数の mysqld サーバを利用していなければ、--skip-external-locking オプションを利用してシステム ロックを無効にする事ができます。

  • unauthenticated user

    クライアント接続への関連はしたが、そのクライアント ユーザの認証はまだ行われていないスレッドの状態。

  • Upgrading lock

    INSERT DELAYED ハンドラは行を挿入する為に、テーブルにロックを得ようとしています。

  • Updating

    スレッドは更新する行を探していて、それらを更新しています。

  • updating main table

    サーバは複合テーブル更新の最初の部分を実行しています。最初のテーブルの更新だけを行い、別の(参照)テーブルの更新に利用されるフィールドとオフセットを保存しています。

  • updating reference tables

    サーバは複合テーブル更新の2番目の部分を行っており、別のテーブルから一致したテーブルを更新しています。

  • User Lock

    スレッドは GET_LOCK() 上で待っています。

  • Waiting for event from ndbcluster

    サーバは MySQL クラスタ内の SQL ノードとして機能しており、クラスタ管理ノードに接続されています。

  • Waiting for tables

    スレッドは、テーブルの基礎構造が変更され、その新しい構造を得る為にテーブルを再度オープンしなければいけないという通知を受け取りました。しかし、テーブルを再度オープンするには、他の全てのスレッドが問題になっているテーブルを閉じるまで待たなければいけません。

    もし別のスレッドが FLUSH TABLES か、次にある問題のテーブル上のステートメントの中のひとつを利用すると、この通知が出されます。FLUSH TABLES tbl_nameALTER TABLERENAME TABLEREPAIR TABLEANALYZE TABLE、または OPTIMIZE TABLE

  • waiting for handler insert

    INSERT DELAYED ハンドラは全ての未解決の挿入を処理し、新しい物を待っています。

  • Writing to net

    サーバはネットワークにパケットを書き込んでいます。

ほとんどのステートが大変速い操作に対応します。もしスレッドがこれらのステートのどれかに何秒間も留まれば、調査が必要な問題があるかもしれません。

12.5.4.25. SHOW SCHEDULER STATUS 構文

SHOW SCHEDULER STATUS

このステートメントは、イベント スケジューラの状態に関連したでバグ情報を提供します。これは、MySQL 5.1.11 の -debug 構造内でだけサポートされ、5.1.12 とそれ以降のリリースでは削除されました。

アウトプット例がここに表示されています。

+--------------------------------+---------------------+
| Name                           | Value               |
+--------------------------------+---------------------+
| scheduler state                | INITIALIZED         |
| thread_id                      | NULL                |
| scheduler last locked at       | init_scheduler::313 |
| scheduler last unlocked at     | init_scheduler::318 |
| scheduler waiting on condition | 0                   |
| scheduler workers count        | 0                   |
| scheduler executed events      | 0                   |
| scheduler data locked          | 0                   |
| queue element count            | 1                   |
| queue data locked              | 0                   |
| queue data attempting lock     | 0                   |
| queue last locked at           | create_event::218   |
| queue last unlocked at         | create_event::222   |
| queue last attempted lock at   | ::0                 |
| queue waiting on condition     | 0                   |
| next activation at             |    0-00-00 00:00:00 |
+--------------------------------+---------------------+

MySQL 5.1.12 以降の物では、この情報は mysqladmin debug を利用して得る事ができます。(詳しくは 項7.9. 「mysqladmin ? MySQL サーバの管理を行うクライアント」 をご確認ください。)イベント スケジューラ ステート情報を得る事に関する情報については、項19.4. 「Event Scheduler Status」 を参照してください。

12.5.4.26. SHOW STATUS 構文

SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern']

SHOW STATUS はサーバ ステータス情報を提供します。この情報は、mysqladmin extended-status コマンドを利用して得る事もできます。

部分的なアウトプットがここに表示されています。名前と値のリストは、お使いのサーバとは異なる場合があります。各変数の意味は 項4.2.5. 「ステータス変数」 で説明しています。

mysql> SHOW STATUS;
+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| Aborted_clients          | 0          |
| Aborted_connects         | 0          |
| Bytes_received           | 155372598  |
| Bytes_sent               | 1176560426 |
| Connections              | 30023      |
| Created_tmp_disk_tables  | 0          |
| Created_tmp_tables       | 8340       |
| Created_tmp_files        | 60         |
...
| Open_tables              | 1          |
| Open_files               | 2          |
| Open_streams             | 0          |
| Opened_tables            | 44600      |
| Questions                | 2026873    |
...
| Table_locks_immediate    | 1920382    |
| Table_locks_waited       | 0          |
| Threads_cached           | 0          |
| Threads_created          | 30022      |
| Threads_connected        | 1          |
| Threads_running          | 1          |
| Uptime                   | 80380      |
+--------------------------+------------+

LIKE 条項を利用すると、パターンと一致する名前を持つ変数の行のみを表示します。

mysql> SHOW STATUS LIKE 'Key%';
+--------------------+----------+
| Variable_name      | Value    |
+--------------------+----------+
| Key_blocks_used    | 14955    |
| Key_read_requests  | 96854827 |
| Key_reads          | 162040   |
| Key_write_requests | 7589728  |
| Key_writes         | 3813196  |
+--------------------+----------+

GLOBAL 修飾子を利用すると、SHOW STATUS は MySQL への全ての接続のステータス値を表示します。SESSION を利用すると、現在の接続のステータス値を表示します。 もし修飾子が無ければ、デフォルトは SESSION です。LOCALSESSION の同義語です。

いくつかのステータス変数は、グローバル値しか持っていません。それらに対しては、GLOBALSESSION の両方に同じ値を得ます。

12.5.4.27. SHOW TABLE STATUS 構文

SHOW TABLE STATUS [FROM db_name] [LIKE 'pattern']

SHOW TABLE STATUSSHOW TABLES のように機能しますが、各テーブルに関する多くの情報を提供します。mysqlshow --status db_name コマンドを利用してこのリストを得る事もできます。

このステートメントもまたビューの情報を表示します。

SHOW TABLE STATUS は次のフィールドを返します。

  • Name

    テーブル名。

  • Engine

    テーブルのストレージ エンジン。詳しくは 章?13. ストレージエンジンとテーブルタイプ を参照してください。

  • Version

    テーブルの .frm file. のバージョン番号。

  • Row_format

    行のストレージ フォーマット(FixedDynamicCompressedRedundantCompact)InnoDB テーブルのフォーマットは RedundantCompact としてレポートされます。

  • Rows

    行数MyISAM のようないくつかのストレージ エンジンは、正確なカウントを格納します。InnoDB のような別のストレージ エンジンにとっては、この値はおおよその物であり、実際の値とは40から50%くらい異なります。そのような場合は、正確なカウントを得る為に SELECT COUNT(*) を利用してください。

    Rows 値は INFORMATION_SCHEMA データベース内のテーブルには NULL です。

  • Avg_row_length

    平均行長

  • Data_length

    データ ファイルの長さ

  • Max_data_length

    データ ファイルの最大長データ ポインタ サイズが利用されたと仮定して、これはテーブル内に格納できるデータの総バイト数です。

  • Index_length

    インデックス ファイルの長さ

  • Data_free

    割り当てられたけれど使用されていないバイト数

  • Auto_increment

    次の AUTO_INCREMENT 値。

  • Create_time

    テーブルが作成された時。

  • Update_time

    データ ファイルが最後に更新された時。いくつかのストレージ エンジンに対しては、この値は NULL です。例えば、InnoDB はそのテーブルスペース内に複合テーブルを格納し、データ ファイル タイムスタンプは適応しません。

  • Check_time

    テーブルが最後に確認された時。値が毎回 NULL の場合、全てのストレージ エンジンはこの時更新しません。

  • Collation

    テーブルの文字セットと照合。

  • Checksum

    ライブチェックサム値(もしあれば)。

  • Create_options

    CREATE TABLE と共に利用される特別オプション。

  • Comment

    テーブルを作成する時に利用されるコメント(またはなぜ MySQL がテーブル情報にアクセスできなかったのかに関する情報)。

InnoDB テーブルは、テーブル コメントの中で、 それが属する所にテーブルスペースのフリー スペースを報告します。共有テーブルスペースの中にあるテーブルには、これが共有テーブルスペースの空きスペースです。もし複数のテーブルスペースを利用していて、そのテーブルが専用のテーブルスペースを所有していたら、そのフリー スペースはそのテーブルだけの物です。

MEMORY テーブルに対して、Data_lengthMax_data_length、そして Index_length 値は割り当てられたメモリの実際の量を概算します。割り当てアルゴリズムは、割り当て操作の数を減らす為に、大量のメモリを確保します。

NDB Cluster テーブルに対して、BLOB カラムは考慮されないという例外はありますが、このステートメントのアウトプットは Avg_row_lengthData_length カラムのおおよその値を表します。 さらに、レプリカの数が Comment カラム内に表示されます。(number_of_replicas として)

ビューに関しては、Name がビュー名を指示し、Commentview と言う事以外、SHOW TABLE STATUS に表示される全てのフィールドは NULL です。

12.5.4.28. SHOW TABLES 構文

SHOW [FULL] TABLES [FROM db_name] [LIKE 'pattern']

SHOW TABLES は、与えられたテーブル内で非 TEMPORARY テーブルをリストします。mysqlshow db_name コマンドを利用してこのリストを得る事もできます。

このステートメントはデータベース内のビューもリストします。FULL 修飾子は SHOW FULL TABLES が第2のアウトプット カラムを表示するようにサポートされています。第2カラムの値は、テーブルに対しては BASE TABLE で、ビューに対しては VIEW です。

注意:もしテーブルに権限を持っていなかったら、テーブルは SHOW TABLESmysqlshow db_name からのアウトプット内に現れません。

12.5.4.29. SHOW TRIGGERS 構文

SHOW TRIGGERS [FROM db_name] [LIKE expr]

SHOW TRIGGERS は最近 MySQL サーバ上で定義されたトリガをリストします。このステートメントは SUPER 権限を必要とします。

項18.3. 「トリガの使用」 内で定義されている、トリガ ins_sum に対しては、このステートメントのアウトプットはここに表されているようになります。

mysql> SHOW TRIGGERS LIKE 'acc%'\G
*************************** 1. row ***************************
  Trigger: ins_sum
    Event: INSERT
    Table: account
Statement: SET @sum = @sum + NEW.amount
   Timing: BEFORE
  Created: NULL
 sql_mode:
  Definer: myname@localhost

注意:LIKE 条項を SHOW TRIGGERS と利用する時、一致する式(expr) は、トリガ名ではなく、トリガが宣言されたテーブル名と比較されます。

mysql> SHOW TRIGGERS LIKE 'ins%';
Empty set (0.01 sec)

このステートメントのアウトプット内のカラムに関する簡単な説明はここに表されています。

  • Trigger

    トリガ名。

  • Event

    トリガを有効化するイベント:'INSERT''UPDATE'、または 'DELETE' の1つ。

  • Table

    トリガが定義されるテーブル。

  • Statement

    トリガが有効化された時に実行されるステートメント。これは INFORMATION_SCHEMA.TRIGGERSACTION_STATEMENT 内に表されているテキストと同じです。

  • Timing

    'BEFORE''AFTER' の2つの値の1つ。

  • Created

    現在、このカラムの値はいつでも NULL です。

  • sql_mode

    トリガが実行する時に有効な SQL モード。

  • Definer

    トリガを作成したアカウント。

項21.16. 「INFORMATION_SCHEMA TRIGGERS テーブル」 もご参照ください。

12.5.4.30. SHOW VARIABLES 構文

SHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern']

SHOW VARIABLES は MySQL システム変数の値を表示します。mysqladmin variables コマンドを利用してこの情報を得る事もできます。

GLOBAL 修飾子を利用すると、SHOW VARIABLES は MySQL への新しい接続に利用される値を表示します。SESSION を利用すると、現在の接続に有効な値を表示します。 もし修飾子が無ければ、デフォルトは SESSION です。LOCALSESSION の同義語です。

もしデフォルトのシステム変数が不適切であれば、mysqld がスタートした時にコマンド オプションを利用してそれらを設定する事ができ、また SET ステートメントを利用してほとんどの物をランタイムに変更できます。項4.2.4. 「システム変数の使用」項12.5.3. 「SET 構文」 を参照して下さい。

部分的なアウトプットがここに表示されています。名前と値のリストは、お使いのサーバとは異なる場合があります。項4.2.3. 「システム変数」 で各変数の意味が説明されており、項6.5.2. 「サーバパラメータのチューニング」 にはそれらを調整する為の情報が紹介されています。

mysql> SHOW VARIABLES;
+---------------------------------+---------------------------+
| Variable_name                   | Value                     |
+---------------------------------+---------------------------+
| auto_increment_increment        | 1                         |
| auto_increment_offset           | 1                         |
| automatic_sp_privileges         | ON                        |
| back_log                        | 50                        |
| basedir                         | /home/jon/bin/mysql-5.1/  |
| binlog_cache_size               | 32768                     |
| bulk_insert_buffer_size         | 8388608                   |
| character_set_client            | latin1                    |
| character_set_connection        | latin1                    |
...
| max_user_connections            | 0                         |
| max_write_lock_count            | 4294967295                |
| multi_range_count               | 256                       |
| myisam_data_pointer_size        | 6                         |
| myisam_max_sort_file_size       | 2147483647                |
| myisam_recover_options          | OFF                       |
| myisam_repair_threads           | 1                         |
| myisam_sort_buffer_size         | 8388608                   |
| ndb_autoincrement_prefetch_sz   | 32                        |
| ndb_cache_check_time            | 0                         |
| ndb_force_send                  | ON                        |
...
| time_zone                       | SYSTEM                    |
| timed_mutexes                   | OFF                       |
| tmp_table_size                  | 33554432                  |
| tmpdir                          |                           |
| transaction_alloc_block_size    | 8192                      |
| transaction_prealloc_size       | 4096                      |
| tx_isolation                    | REPEATABLE-READ           |
| updatable_views_with_limit      | YES                       |
| version                         | 5.1.6-alpha-log           |
| version_comment                 | Source distribution       |
| version_compile_machine         | i686                      |
| version_compile_os              | suse-linux                |
| wait_timeout                    | 28800                     |
+---------------------------------+---------------------------+

LIKE 条項を利用すると、パターンと一致する名前を持つ変数の行のみを表示します。

特定の変数に行を得る為には、次に表示されているように LIKE 条項を利用してください。

SHOW VARIABLES LIKE 'max_join_size';
SHOW SESSION VARIABLES LIKE 'max_join_size';

名前がパターンと一致する変数のリストを得るには、LIKE 条項内の ‘%’ ワイルドカード文字を利用してください。

SHOW VARIABLES LIKE '%size%';
SHOW GLOBAL VARIABLES LIKE '%size%';

ワイルドカード文字は、一致するパターン内のどの場所でも利用する事ができます。厳密に言うと、‘_’ は全ての単一文字と一致するワイルドカードなので、完全に一致させる為に ‘\_’ の時は拡張する必要があります。実際には、これはほとんど必要ありません。

12.5.4.31. SHOW WARNINGS 構文

SHOW WARNINGS [LIMIT [offset,] row_count]
SHOW COUNT(*) WARNINGS

SHOW WARNINGS は、メッセージを作成した最後のステートメントから生じたエラー、警告、そしてノート メッセージを表示、または、もしテーブルを利用した最後のステートメントが何のメッセージも作成しなければ、何も表示しません。関連ステートメントである SHOW ERRORS はエラーだけを表示します。詳しくは 項12.5.4.14. 「SHOW ERRORS 構文」 を参照してください。

テーブルを利用するそれぞれの新ステートメントに対して、メッセージのリストはリセットされます。

SHOW COUNT(*) WARNINGS ステートメントはエラー、警告、そしてノートの総数を表示します。warning_count 変数からもこの数字を検索する事ができます。

SHOW COUNT(*) WARNINGS;
SELECT @@warning_count;

もし max_error_count システム変数が、全てのメッセージの格納ができないほど低く設定されると、warning_count の値は SHOW WARNINGS によって表示されるメッセージ数よりも大きくなります。このセクションの後の方で表示される例で、これがどのように起きるのか紹介しています。

LIMIT 条項は SELECT ステートメントに対するのと同じ構文を持っています。詳しくは 項12.2.7. 「SELECT 構文」 を参照してください。

MySQL サーバは、最後のステートメントから生じたエラー、警告、そしてノートの総数を送り返します。もし C API を利用していれば、この値は mysql_warning_count() をコールする事で得る事ができます。詳しくは 項23.2.3.72. 「mysql_warning_count() を参照してください。

警告は、LOAD DATA INFILE や、また DML INSERTUPDATECREATE TABLE、そして ALTER TABLE のような DML ステートメントなどのようなステートメントに対して作成されます。

次の DROP TABLE ステートメントはノートをもたらします:

mysql> DROP TABLE IF EXISTS no_such_table;
mysql> SHOW WARNINGS;
+-------+------+-------------------------------+
| Level | Code | Message                       |
+-------+------+-------------------------------+
| Note  | 1051 | Unknown table 'no_such_table' |
+-------+------+-------------------------------+

ここに、CREATE TABLE に対する構文警告と、INSERT に対する変換警告を表すシンプルな例があります。

mysql> CREATE TABLE t1 (a TINYINT NOT NULL, b CHAR(4)) TYPE=MyISAM;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Warning
   Code: 1287
Message: 'TYPE=storage_engine' is deprecated, use
         'ENGINE=storage_engine' instead
1 row in set (0.00 sec)

mysql> INSERT INTO t1 VALUES(10,'mysql'),(NULL,'test'),
    -> (300,'Open Source');
Query OK, 3 rows affected, 4 warnings (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 4

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Warning
   Code: 1265
Message: Data truncated for column 'b' at row 1
*************************** 2. row ***************************
  Level: Warning
   Code: 1263
Message: Data truncated, NULL supplied to NOT NULL column 'a' at row 2
*************************** 3. row ***************************
  Level: Warning
   Code: 1264
Message: Data truncated, out of range for column 'a' at row 3
*************************** 4. row ***************************
  Level: Warning
   Code: 1265
Message: Data truncated for column 'b' at row 3
4 rows in set (0.00 sec)

エラー警告、そしてノート メッセージの最高格納数は max_error_count システム変数によってコントロールされています。デフォルトにより、その値は64です。格納するメッセージ数を変更したければ、max_error_count の値を変更してください。次の例では ALTER TABLE ステートメントは3つの警告メッセージを発生しますが、max_error_count が1に設定されている為、そのうちの1つしか格納されません。

mysql> SHOW VARIABLES LIKE 'max_error_count';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_error_count | 64    |
+-----------------+-------+
1 row in set (0.00 sec)

mysql> SET max_error_count=1;
Query OK, 0 rows affected (0.00 sec)

mysql> ALTER TABLE t1 MODIFY b CHAR;
Query OK, 3 rows affected, 3 warnings (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 3

mysql> SELECT @@warning_count;
+-----------------+
| @@warning_count |
+-----------------+
|               3 |
+-----------------+
1 row in set (0.01 sec)

mysql> SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1263 | Data truncated for column 'b' at row 1 |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)

警告を無効にするには、max_error_count を0に設定してください。この場合、warning_count はいくつの警告が起きたか指示しますが、どのメッセージも格納はされません。

SQL_NOTES セッション変数を0に設定して、Note レベルの警告が記録されないようにできます。

12.5.5. その他の管理ステートメント

12.5.5.1. CACHE INDEX 構文

CACHE INDEX
  tbl_index_list [, tbl_index_list] ...
  IN key_cache_name

tbl_index_list:
  tbl_name [[INDEX|KEY] (index_name[, index_name] ...)]

CACHE INDEX ステートメントはテーブル インデックスを特定のキー キャッシュに割り当てます。これは MyISAM テーブルにしか利用されません。

次のステートメントは、インデックスをテーブル t1t2、そして t3 から hot_cache という名前のキー キャッシュに割り当てます。

mysql> CACHE INDEX t1, t2, t3 IN hot_cache;
+---------+--------------------+----------+----------+
| Table   | Op                 | Msg_type | Msg_text |
+---------+--------------------+----------+----------+
| test.t1 | assign_to_keycache | status   | OK       |
| test.t2 | assign_to_keycache | status   | OK       |
| test.t3 | assign_to_keycache | status   | OK       |
+---------+--------------------+----------+----------+

CACHE INDEX の構文によって、テーブルからの特定のインデックスだけがキャッシュに割り当てられなければいけない、と指定する事ができます。現在のインプリメンテーションは、全てのテーブルのインデックスをキャッシュに割り当てるので、テーブル名以外を指定する利用は無いのです。

CACHE INDEX ステートメント内で参照されるキー キャッシュは、パラメータ設定ステートメントを設定するか、サーバ パラメータ設定の中で作成できます。例:

mysql> SET GLOBAL keycache1.key_buffer_size=128*1024;

キー キャッシュ パラメータには、構造化システム変数のメンバとしてアクセスできます。詳しくは 項4.2.4.1. 「構造化システム変数」 を参照してください。

キー キャッシュは、インデックスをそれに割り当てる前に存在していなければいけません。

mysql> CACHE INDEX t1 IN non_existent_cache;
ERROR 1284 (HY000): Unknown key cache 'non_existent_cache'

デフォルトで、テーブル インデックスは、サーバ起動時に作成された主要(デフォルト)キー キャッシュに割り当てられます。キー キャッシュが破壊される時、そこに割り当てられた全てのインデックスはデフォルト キーキャッシュに再び割り当てられます。

インデックスの割り当ては、サーバに対してグローバルに影響します。もし1つのクライアントが既存のキャッシュにインデックスを割り当てると、どのクライアントがクエリを発行したかに関わらず、このキャッシュはそのインデックスを含む全てのクエリに対して利用されます。

12.5.5.2. FLUSH 構文

FLUSH [LOCAL | NO_WRITE_TO_BINLOG]
    flush_option [, flush_option] ...

FLUSH ステートメントは、MySQL に利用された様々な内部キャッシュをクリア、または再ロードします。FLUSH を実行する為には、RELOAD 権限を持つ必要があります。

RESET ステートメントは FLUSH と似ています。詳しくは 項12.5.5.5. 「RESET 構文」 を参照してください。

flush_option は、次のうちのどれかになり得ます。

  • HOSTS

    ホスト キャッシュ テーブルを空にします。もし、いくつかのホストが IP 番号を変えたり、エラー メッセージ Host 'host_name' is blocked を受け取ったりしたら、ホスト テーブルをフラッシュする必要があります。MySQL サーバに接続中に、連続して max_connect_errors 以上のエラーがホストに発生すると、MySQL は何か異常があると仮定して、それ以上の接続の要求をブロックします。ホスト テーブルをフラッシュすると、ホストは再度接続を試みる事ができます。詳しくは 項B.1.2.5. 「Host 'host_name' is blocked を参照してください。このエラー メッセージを避ける為に、--max_connect_errors=999999999 を利用して mysqld をスタートする事ができます。

  • DES_KEY_FILE

    サーバ起動時に --des-key-file オプションを利用して指定されたファイルからの DES キーを再ロードします。

  • LOGS

    全てのログ ファイルを閉じ、再オープンします。もしバイナリ ログが有効であれば、バイナリ ログ ファイルのシーケンス番号は前のファイルと比較して1つ増加されます。これは Unix では、SIGHUP シグナルを mysqld サーバに送信する事と同じです。(mysqldSIGHUPSIGQUIT を無視する Mac OS X 10.3 バージョン以外)

    もしサーバが --log-error オプションでスタートされたら、それは FLUSH LOGS によって -old のサフィックスを利用して現在のエラー ログ ファイルをリネームし、新しく空のログ ファイルを作成します。もし --log-error オプションがなければリネームは行われません。

  • MASTER (DEPRECATED)全てのバイナリ ログを削除し、バイナリ ログ インデックス ファイルをリセットし、新しいバイナリ ログを作成します。FLUSH MASTERRESET MASTER と置き換えられ廃止予定であり、現在は後方互換だけがサポートされています。詳しくは 項12.6.1.2. 「RESET MASTER 構文」 を参照してください。

  • PRIVILEGES

    mysql データベース内で供与テーブルから権限を再ロードします。

  • QUERY CACHE

    メモリ使用を向上させる為にクエリ キャッシュをデフラグします。FLUSH QUERY CACHERESET QUERY CACHE とは違い、キャッシュからクエリを削除しません。

  • SLAVE (DEPRECATED)リレー ログ ファイルやマスタのバイナリ ログ内の複製位置を含む、全ての複製スレーブ パラメータをリセットします。FLUSH SLAVERESET SLAVE と置き換えられ廃止予定であり、現在は後方互換だけがサポートされています。詳しくは 項12.6.2.5. 「RESET SLAVE 構文」 を参照してください。

  • STATUS

    このオプションは、グローバル値に現在のスレッドのセッション ステータス変数値を追加し、セッション値をゼロにリセットします。それはキー キャッシュ(デフォルトと名づけられた物)のカウンタをゼロにリセットし、現在オープンしている接続の数に Max_used_conections を設定します。これは、クエリをデバグしている時のみ利用するべき物です。詳しくは 項1.7. 「質問またはバグの報告」 を参照してください。

  • {TABLE | TABLES} [tbl_name [, tbl_name] ...]

    どのテーブル名づけられていない時に、全てのオープンなテーブルを閉じ、利用中の全てのテーブルを強制的に閉じます。これはクエリ キャッシュもフラッシュします。複数のテーブル名があると、与えられたテーブルだけをフラッシュします。FLUSH TABLESRESET QUERY CACHE のように、クエリ キャッシュから全てのクエリ結果の削除もします。

  • TABLES WITH READ LOCK

    UNLOCK TABLES を実行して明示的にロックを解除するまで、リード ロックを利用して全てのデータベースの全てのオープン テーブルを閉じ、全てのテーブルをロックします。これは、もし Veritas のような、時間内にスナップショットを撮る事ができるファイル システムを持っているなら、バックアップを取るのに大変便利な方法になります。

    FLUSH TABLES WITH READ LOCK は、グローバル リード ロックは取得しますがテーブル ロックはしないので、テーブル ロックと暗黙的なコミットに関しては LOCK TABLESUNLOCK TABLES と同じような動作の制約は受けません。

    • UNLOCK TABLES は、もしテーブルが現在 LOCK TABLES でロックされていたらトランザクションを行います。これは、FLUSH TABLES WITH READ LOCK ステートメントがテーブル レベル ロックを取得しない為、これに続く UNLOCK TABLES に対しては行われません。

    • トランザクションを開始すると、LOCK TABLES を利用して行ったテーブル ロックを、まるで UNLOCK TABLES を実行したかのように解除してしまいます。トランザクションを開始しても、FLUSH TABLES WITH READ LOCK を利用して行われたグローバル リード ロックの解除はしません。

  • USER_RESOURCES

    全ての時間あたりのユーザ リソースをゼロにリセットします。これは、時間ごとの接続、クエリ、更新リミットに達したクライアントがすぐに活動を再開できるようにします。FLUSH USER_RESOURCES は最大同時接続のリミットに適応しません。詳しくは 項12.5.1.3. 「GRANT 構文」 を参照してください。

FLUSH ステートメントは、任意の NO_WRITE_TO_BINLOG キーワード(またはそのエイリアス LOCAL) が利用されない限り、バイナリ ログに書きこまれます。これは、複製マスタとして機能している MySQL サーバ上で利用される FLUSH ステートメントが、複製スレーブにデフォルトで複製される為に行われます。

注意:FLUSH LOGSFLUSH MASTERFLUSH SLAVE、そして FLUSH TABLES WITH READ LOCK は、スレーブに複製されると問題を引き起こす為、ログインされません。

flush-hostsflush-logsflush-privilegesflush-status、または flush-tables コマンドを利用する mysqladmin ユーティリティで、いくつかのステートメントにアクセスする事ができます。

注意:MySQL 5.1 内では、ストアド ファンクションやトリガ内で FLUSH ステートメントを発行する事は不可能です。しかし、ストアド プロシージャ内の FLUSH がストアド ファンクションやトリガにコールされない限り、それらを利用してもよいでしょう。詳しくは 項D.1. 「ストアド ルーチンとトリガの規制」 を参照してください。

RESET ステートメントが複製の中でどのように利用されるかという情報については 項12.5.5.5. 「RESET 構文」 も参照してください。

12.5.5.3. KILL 構文

KILL [CONNECTION | QUERY] thread_id

mysqld への各接続は別々のスレッド内で起動します。どのスレッドが SHOW PROCESSLIST ステートメントを利用し、スレッドを停止させるのかを、KILL thread_id ステートメントを利用して確認する事ができます。

KILL は任意の CONNECTIONQUERY 修飾子を許容します。

  • KILL CONNECTION は修飾子を持たない KILL と同じです。それは thread_id と関連している接続を終了します。

  • KILL QUERY は現在接続が実行中であるステートメントを終了させますが、その接続自体には手をつけずそのまま残しておきます。

もし PROCESS 権限を持っていれば、全てのスレッドを見る事ができます。もし SUPER 権限を持っていれば、全てのスレッドとステートメントを停止する事ができます。そうでなければ、自分自身のスレッドとステートメントのみ確認、停止させる事ができます。

mysqladmin processlistmysqladmin kill コマンドを利用して、スレッドを検査、停止する事もできます。

注意:埋め込みサーバは、ホスト アプリケーションのスレッド内ではほとんど起動しないので、KILL と埋め込み MySQL サーバ ライブラリを一緒に利用する事はできません。それは、それ自身の接続スレッドは作成しません。

KILL を利用する時、スレッド固有のキル フラッグがスレッドに設定されます。ほとんどの場合、キル フラッグは特定のインターバルでしか確認されないので、スレッドが停止するまでに少し時間がかかります。

  • SELECT,ORDER BY そして GROUP BY ループ内では、フラッグは行のブロックを読み込んだ後に確認されます。もしキル フラッグが設定されると、ステートメントは異常終了します。

  • ALTER TABLE の最中に、行の各ブロックが元テーブルから読み込まれる前にキル フラッグが確認されます。もしキル フラッグが設定されると、ステートメントは異常終了し、テンポラリ テーブルは削除されます。

  • UPDATEDELETE 操作の最中に、各ブロックの読み込みや、行の各更新や削除の後でキル フラッグが確認されます。もしキル フラッグが設定されると、ステートメントは異常終了します。もしトランザクションを利用していなければ、変更はロールバックされない事に注意してください。

  • GET_LOCK()NULL を異常終了し、返します。

  • INSERT DELAYED スレッドはメモリ内に持っている全ての行をすばやくフラッシュ(挿入)します。

  • もしスレッドがテーブル ロック ハンドラ内にあれば、(状態: Locked) テーブルロックは迅速に異常終了します。

  • もしスレッドが書き込みコール内でフリー ディスク スペースを待っていたら、その書き込みは 「disk full」 エラー メッセージを利用して異常終了されます。

  • 警告: MyISAM テーブル上で REPAIR TABLEOPTIMIZE TABLE 操作を終了させると、テーブルが破損され、利用不可能になります。それを最適化、または修復するまで(割り込み無しで)、そのようなテーブルへの書き込みや読み込みは失敗します。

12.5.5.4. LOAD INDEX INTO CACHE 構文

LOAD INDEX INTO CACHE
  tbl_index_list [, tbl_index_list] ...

tbl_index_list:
  tbl_name
    [[INDEX|KEY] (index_name[, index_name] ...)]
    [IGNORE LEAVES]

LOAD INDEX INTO CACHE ステートメントは、明示的な CACHE INDEX ステートメントによって割り当てられたキー キャッシュに、またはそうでなければデフォルトのキー キャッシュに、テーブル インデックスをあらかじめロードしておきます。LOAD INDEX INTO CACHEMyISAM テーブルにだけ利用されます。

IGNORE LEAVES 修飾子は、インデックスの非リーフ ノードの為のブロックだけがあらかじめロードされるよう働きかけます。

次のステートメントは、(index blocks) テーブル t1t2 のインデックスのノード(インデックスブロック)をあらかじめロードしておきます。

mysql> LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES;
+---------+--------------+----------+----------+
| Table   | Op           | Msg_type | Msg_text |
+---------+--------------+----------+----------+
| test.t1 | preload_keys | status   | OK       |
| test.t2 | preload_keys | status   | OK       |
+---------+--------------+----------+----------+

このステートメントは t1 から全てのインデックス ブロックをあらかじめロードしておきます。それは、t2 から非リーフ ノードのブロックだけをあらかじめロードします。

LOAD INDEX INTO CACHE の構文によって、テーブルからの特定のインデックスだけがあらかじめロードされなければいけない、と指定する事ができます。現在のインプリメンテーションは、全てのテーブルのインデックスをキャッシュ内に割り当てるので、テーブル名以外を指定する利用は無いのです。

LOAD INDEX INTO CACHE は、テーブル内の全てのインデックスが同じブロック サイズでなければ失敗します。myisamchk -dv を利用し、Blocksize カラムを確認する事で、テーブルのインデックス ブロック サイズを決定する事ができます。

12.5.5.5. RESET 構文

RESET reset_option [, reset_option] ...

RESET ステートメントは様々なサーバ操作の状態をクリアする為に利用されます。RESET を実行する為には RELOAD 権限を持つ必要があります。

RESETFLUSH ステートメントの、より強力バージョンとして機能します。詳しくは 項12.5.5.2. 「FLUSH 構文」 を参照してください。

reset_option は、次のうちのどれかになり得ます。

  • MASTER

    インデックス ファイル内にリストされている全てのバイナリ ログを削除し、バイナリ ログ インデックス ファイルをゼロにリセットし、新しいバイナリ ログを作成します。(MySQL 3.23.26 以前のバージョンでは FLUSH MASTER として知られています。)詳しくは 項12.6.1. 「マスタ サーバをコントロールする SQL ステートメント」 を参照してください。

  • QUERY CACHE

    クエリ キャッシュから全てのクエリ結果を削除します。

  • SLAVE

    スレーブがマスタ バイナリ ログ内の複製位置を忘れるよう働きかけます。また、既存リレー ログ ファイルを削除する事で、リレー ログをリセットし、新しい物を開始します。(MySQL 3.23.26 以前のバージョンでは FLUSH SLAVE として知られています。)詳しくは 項12.6.2. 「スレーブ サーバをコントロールする SQL ステートメント」 を参照してください。

12.6. 複製ステートメント

このセクションでは、複製に関連した SQL ステートメントについて説明します。1つのグループは、マスタ サーバをコントロールする為に利用されます。別の物はスレーブ サーバをコントロールする為に利用されます。

12.6.1. マスタ サーバをコントロールする SQL ステートメント

複製は SQL インターフェースを通してコントロールできます。このセクションでは、マスタ複製サーバの管理についてのステートメントの説明をします。項12.6.2. 「スレーブ サーバをコントロールする SQL ステートメント」では、スレーブ サーバの管理について説明しています。

12.6.1.1. PURGE MASTER LOGS 構文

PURGE {MASTER | BINARY} LOGS TO 'log_name'
PURGE {MASTER | BINARY} LOGS BEFORE 'date'

ログ インデックス内で指定されたログや日付の前にリストされている全てのバイナリ ログを削除します。与えられたログが最初になるように、ログ インデックス ファイル内に記録されたリストからもログが削除されます。

例:

PURGE MASTER LOGS TO 'mysql-bin.010';
PURGE MASTER LOGS BEFORE '2003-04-02 22:46:26';

BEFORE 異型の date 引数は 'YYYY-MM-DD hh:mm:ss' フォーマットになり得ます。MASTERBINARY は同義語です。

このステートメントは、スレーブが複製中に起動しても安全です。それらを停止させる必要はありません。現在削除しようとしているログの1つを読み込んでいる、アクティブ スレーブを持っていれば、このステートメントは何もせず、エラーで失敗します。しかし、もしスレーブが休止状態で、まだ読み込まれていないログの1つを消去してしまったら、そのスレーブはその後複製が不可能になります。

ログを安全に消去するには、次の手順に従ってください。

  1. 各スレーブ サーバ上で、どのログがそれを読み込んでいるのか確認する為に SHOW SLAVE STATUS を利用してください。

  2. SHOW BINARY LOGS を利用してマスタ サーバ上でバイナリ ログのリストを手に入れてください。

  3. 全てのスレーブの中で一番最初のログを確認してください。.これがターゲット ログです。もし全てのスレーブが最新であれば、これがリスト上の最後のログになります。

  4. 削除しようとしている全てのログのバックアップを作成してください。(このステップは任意ですが、常に推奨されている物です。)

  5. ターゲット ログを含まず、そこまでの全てのログを消去してください。

指定した日数後に(項4.2.3. 「システム変数」 を参照)バイナリ ログを自動的に無効にする expire_logs_days システム変数も設定できます。もし複製を利用しているなら、ご利用のスレーブがマスタよりも遅れるであろう最大日数よりも低く変数を設定しなければいけません。

12.6.1.2. RESET MASTER 構文

RESET MASTER

インデックス ファイル内にリストされている全てのバイナリ ログを削除し、バイナリ ログ インデックス ファイルをゼロにリセットし、新しいバイナリ ログを作成します。

12.6.1.3. SET SQL_LOG_BIN 構文

SET SQL_LOG_BIN = {0|1}

もしクライアントが SUPER 権限を持っていたら、現在の接続(SQL_LOG_BIN がセッション変数です)のバイナリ ログを無効、または有効にします。もしクライアントがその権限を持っていなければ、ステートメントはエラーによって拒否されます。

12.6.1.4. SHOW BINLOG EVENTS 構文

SHOW BINLOG EVENTS
   [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]

バイナリ ログ内のイベントを表します。もし 'log_name' を指定しなければ、最初のバイナリ ログが表示されます。

LIMIT 条項は SELECT ステートメントに対するのと同じ構文を持っています。詳しくは 項12.2.7. 「SELECT 構文」 を参照してください。

注意:LIMIT を利用せずに SHOW BINLOG EVENTS を発行すると、サーバがクライアントに完全なバイナリ ログのコンテンツ(データを変更するサーバによって実行された全てのステートメントを含む)を返すので、時間、リソースの両方を大量に消費するプロセスを開始する事になってしまいます。SHOW BINLOG EVENTS の代替として、後ほど行う調査と分析の為のバイナリ ログをテキスト ファイルに保存する為に mysqlbinlog ユーティリティを利用してください。詳しくは 項7.10. 「mysqlbinlog ? バイナリログファイルを処理するためのユーティリティ」 を参照してください。

12.6.1.5. SHOW BINARY LOGS 構文

SHOW BINARY LOGS
SHOW MASTER LOGS

サーバ上にバイナリ ログをリストします。このステートメントは、どのログを消去できるかを決める方法を表す 項12.6.1.1. 「PURGE MASTER LOGS 構文」 内で説明されている手順の一部として利用されています。

mysql> SHOW BINARY LOGS;
+---------------+-----------+
| Log_name      | File_size |
+---------------+-----------+
| binlog.000015 |    724935 |
| binlog.000016 |    733481 |
+---------------+-----------+

SHOW MASTER LOGSSHOW BINARY LOGS と同等です。

12.6.1.6. SHOW MASTER STATUS 構文

SHOW MASTER STATUS

マスタのバイナリ ログ ファイルについてのステータス情報を提供します。例:

mysql > SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| mysql-bin.003 | 73       | test         | manual,mysql     |
+---------------+----------+--------------+------------------+

12.6.1.7. SHOW SLAVE HOSTS 構文

SHOW SLAVE HOSTS

現在マスタと共に登録されている複製スレーブのリストを表示します。このリスト内では、--report-host=slave_name オプションを利用してスタートされたスレーブのみ見る事ができます。

このリストはどのサーバ上にも表示されます。(マスタサーバだけではありません。)アウトプットはこのようになります。

mysql> SHOW SLAVE HOSTS;
+------------+-----------+------+-----------+
| Server_id  | Host      | Port | Master_id |
+------------+-----------+------+-----------+
|  192168010 | iconnect2 | 3306 | 192168011 |
| 1921680101 | athena    | 3306 | 192168011 |
+------------+-----------+------+-----------+

  • Server_id:サーバのオプション ファイル内、または --server-id=value を利用したコマンド ライン上で設定された、ユニーク サーバ ID です。

  • Host:サーバのオプション ファイル内、または --report-host=value を利用したコマンド ライン上で設定された、スレーブ サーバのホスト名です。

    OS 内で設定されたマシン名とは異なる可能性があるという事に注意してください。

  • Port:スレーブ サーバが聴いているポート

  • Master_id:スレーブ サーバがそこから複製している、マスタ サーバのユニーク サーバ ID。

いくつかの MySQL バージョンは別の変数 Rpl_recovery_rank を報告します。この変数が利用された事はなく、最終的に削除されました。

12.6.2. スレーブ サーバをコントロールする SQL ステートメント

複製は SQL インターフェースを通してコントロールできます。.このセクションでは、スレーブ複製サーバの管理についてのステートメントの説明をします。項12.6.1. 「マスタ サーバをコントロールする SQL ステートメント」では、マスタ サーバの管理について説明しています。

12.6.2.1. CHANGE MASTER TO 構文

CHANGE MASTER TO master_def [, master_def] ...

master_def:
    MASTER_HOST = 'host_name'
  | MASTER_USER = 'user_name'
  | MASTER_PASSWORD = 'password'
  | MASTER_PORT = port_num
  | MASTER_CONNECT_RETRY = count
  | MASTER_LOG_FILE = 'master_log_name'
  | MASTER_LOG_POS = master_log_pos
  | RELAY_LOG_FILE = 'relay_log_name'
  | RELAY_LOG_POS = relay_log_pos
  | MASTER_SSL = {0|1}
  | MASTER_SSL_CA = 'ca_file_name'
  | MASTER_SSL_CAPATH = 'ca_directory_name'
  | MASTER_SSL_CERT = 'cert_file_name'
  | MASTER_SSL_KEY = 'key_file_name'
  | MASTER_SSL_CIPHER = 'cipher_list'

CHANGE MASTER TO は、スレーブ サーバがマスタ サーバに接続、また更新する時に利用するパラメータを変更します。それは master.inforelay-log.info ファイルのコンテンツの更新もします。

MASTER_USERMASTER_PASSWORDMASTER_SSLMASTER_SSL_CAMASTER_SSL_CAPATHMASTER_SSL_CERTMASTER_SSL_KEY、そして MASTER_SSL_CIPHER はどのようにマスタに接続すかという事について情報を提供します。

SSL オプション(MASTER_SSLMASTER_SSL_CAMASTER_SSL_CAPATHMASTER_SSL_CERTMASTER_SSL_KEY、そして MASTER_SSL_CIPHER) は、SSLサポート無しでコンパイルされたスレーブ上でも変更できます。それらは master.info ファイルに保存されますが、有効な SSL サポートを持つサーバを利用しなければ無視されます。

もし与えられたパラメータを指定しなければ、次の説明の中で指示されている場合以外は古い値を持ち続けます。例えば、MySQL マスタに接続する為のパスワードが変更されたら、スレーブに新しいパスワードについて指示する為にこれらのステートメントを発行するだけでよいのです。

STOP SLAVE; -- if replication was running
CHANGE MASTER TO MASTER_PASSWORD='new3cret';
START SLAVE; -- if you want to restart replication

変更しないパラメータを指定する必要はありません。(ホスト、ポート、ユーザ、など)

MASTER_HOSTMASTER_PORT はマスタホストと、その TCP/IP ポートのホスト名(または IP アドレス) です。 もし MASTER_HOSTlocalhost と同等であれば、その時は MySQL の別の部分と同じで、ポート番号は無視されるという事に注意してください。(例えば、もし Unix ソケットファイルが利用できる場合)

もし MASTER_HOSTMASTER_PORT を指定すると、スレーブはマスタ サーバが以前とは違うと仮定します。(たとえ現在の値と等しいホストやポート値を指定したとしても)この場合、マスタ バイナリ ログ名と位置の古い値は適応しないとみなされる為、もしステートメント内の MASTER_LOG_FILEMASTER_LOG_POS を指定しなければ、MASTER_LOG_FILE=''MASTER_LOG_POS=4 が静かにそれに加えられます。

MASTER_LOG_FILEMASTER_LOG_POS は、次にスレットがスタートするマスタから、スレーブ I/O スレッドが読み込みを始めなければいけない座標です。もしそれらのどちもを指定しなければ、RELAY_LOG_FILERELAY_LOG_POS を指定する事ができません。もし MASTER_LOG_FILEMASTER_LOG_POS も指定されなければ、CHANGE MASTER が発行される前に、スレーブは slave SQL thread の最後の座標を利用します。これは、ただ単に使用するパスワードを変更したいだけの時に、スレーブ I/O スレッドと比べてスレーブ SQL スレッドが遅かったとしても、複製内に切れ目がない事を保証します。

CHANGE MASTER は、RELAY_LOG_FILERELAY_LOG_POS を指定しない限り、全てのリレー ログ ファイルを削除し、新しい物をスタートします。その場合、リレー ログは保管されます。relay_log_purge グローバル変数は静かに0に設定されます。

CHANGE MASTER は、マスタのスナップショットを持っていて、それに対応するログとオフセットを記録した時に、スレーブを設定するのに役立ちます。スナップショットをスレーブにロードした後、スレーブ上で CHANGE MASTER TO MASTER_LOG_FILE='log_name_on_master', MASTER_LOG_POS=log_offset_on_master を起動する事ができます。

次の例は、マスタとマスタのバイナリ ログ座標を変更します。これは、マスタを複製する為にスレーブを設定したい時に利用します。

CHANGE MASTER TO
  MASTER_HOST='master2.mycompany.com',
  MASTER_USER='replication',
  MASTER_PASSWORD='bigs3cret',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='master2-bin.001',
  MASTER_LOG_POS=4,
  MASTER_CONNECT_RETRY=10;

次の例は、あまり利用されない操作を表しています。これは、何かの理由でもう一度実行したいリレー ログをスレーブが持っている時に利用します。これを行う為には、マスタにはアクセス不可能でなければいけません。CHANGE MASTER TO を利用し、SQL スレッドをスタートさせるだけでよいです。(START SLAVE SQL_THREAD)

CHANGE MASTER TO
  RELAY_LOG_FILE='slave-relay-bin.006',
  RELAY_LOG_POS=4025;

スタンド アロンを利用した非複製セットアップ内、クラッシュ後の修復の為の非スレーブ サーバ内で、2番目の操作を利用する事もできます。サーバがクラッシュして、バックアップを格納したと仮定してください。サーバのバイナリログ(リレーログではなく通常のバイナリログ)、名づけられた(例えば)myhost-bin.* を再生したいでしょう。まず、次の手順と全く同じように作業しなかった為にサーバが誤ってバイナリ ログを消去してしまう、という場合に備えて、これらのバイナリ ログのバックアップ コピーを安全なところに作成してください。更なる安全の為に SET GLOBAL relay_log_purge=0 を利用してください。--log-bin オプションは利用せず、その代わりに、--replicate-same-server-id--relay-log=myhost-bin (サーバにこれらの通常のバイナリ ログがリレー ログだと信じさせる為)そして --skip-slave-start オプションを利用してサーバをスタートさせてください。サーバがスタートしたら、これらのステートメントを発行してください。

CHANGE MASTER TO
  RELAY_LOG_FILE='myhost-bin.153',
  RELAY_LOG_POS=410,
  MASTER_HOST='some_dummy_string';
START SLAVE SQL_THREAD;

サーバがそれ自身のバイナリ ログを読み込み、実行するので、クラッシュの修復を達成します。修復が終了したら、STOP SLAVE を起動し、サーバをシャットダウンし、master.inforelay-log.info ファイルを削除し、そして元のオプションを利用してサーバを再スタートさせてください。

MASTER_HOST オプション(たとえダミー値を利用していても) を指定するには、それがスレーブだとマスタに信じさせる事が必要です。

12.6.2.2. LOAD DATA FROM MASTER 構文

LOAD DATA FROM MASTER

この機能は終了しました。今後は使わないことを勧めます。MySQLの将来のバージョンでは取り除かれることもあります。

LOAD DATA FROM MASTERLOAD TABLE FROM MASTER の現在のインプリメンテーションがとても制限されているので、これらのステートメントは MySQL のバージョン 4.1 以降では廃止予定です。今後のバージョンでは、さらに進歩した技術(「online backup」 と呼ばれる物) を紹介する予定です。その技術は、さらに多くのストレージ エンジンと機能する更なる利点を持ちます。

MySQL 5.1 以前のバージョンで LOAD DATA FROM MASTERLOAD TABLE FROM MASTER を利用する為に推奨する代替方法は、mysqldumpmysqlhotcopy を利用する事です。後者は Perl と2つの Perl モジュール(DBIDBD:mysql)を必要とし、MyISAMARCHIVE テーブルにだけ機能します。mysqldump を利用すると、マスタ上に SQL ダンプを作成でき、それらをスレーブ上の mysql クライアントにパイプ(またはコピー)できます。これは全てのストレージ エンジンに機能するという利点を持ちますが、SELECT を利用して機能する為スピードが大変遅いです。

このステートメントは、マスタのスナップショットを撮り、それをスレーブにコピーします。それは、スレーブが正しい位置から複製を始めるように MASTER_LOG_FILEMASTER_LOG_POS の値を更新します。--replicate-*-do-*--replicate-*-ignore-* オプションを利用して指定されたテーブルとデータベースの除外ルールは支持されています。マスタからテーブルをロードする時にスレーブを混乱させる --replicate-rewrite-db="db1->db3"--replicate-rewrite-db="db2->db3" のような非固有マッピングを設定する為に、ユーザはこのオプションを利用できるので、--replicate-rewrite-db は考慮に入れられて いません

このステートメントは次の条件に従い利用できます:

  • これは MyISAM テーブルにしか機能しません。非 MyISAM テーブルをロードしようとすると、次のエラーが起こります。

    ERROR 1189 (08S01): Net error reading from master
    
  • それはスナップショットを撮っている間にグローバル リード ロックを取得し、それはロード作業中のマスタ上での更新を妨げます。

もし大きいテーブルをロードしていたら、マスタとスレーブの両方で net_read_timeoutnet_write_timeout の値を増やす必要があるでしょう。詳しくは 項4.2.3. 「システム変数」 を参照してください。

LOAD DATA FROM MASTERmysql データベースから何もコピー しない 事に注意してください。これは、マスタとスレーブ上で異なるユーザと権限を持つ事を簡単にします。

LOAD DATA FROM MASTER を利用する為には、 マスタに接続する為に利用される複製アカウントはマスタ上に RELOADSUPER 権限を持ち、ロードしたい全てのマスタ テーブルに SELECT 権限を持つ必要があります。ユーザが SELECT 権限を持たない全てのマスタ テーブルは LOAD DATA FROM MASTER に無視されます。これは、マスタがユーザからそれらを隠す為に起こります。LOAD DATA FROM MASTER は、ロードするデータベースを知る為に SHOW DATABASES をコールしますが、SHOW DATABASES はユーザが何かしらの権限を持つデータベースだけを返します。詳しくは 項12.5.4.11. 「SHOW DATABASES 構文」 を参照してください。スレーブ サイドでは、LOAD DATA FROM MASTER を発行するユーザはデータベースをドロップし作成する権限と、コピーされるテーブルを持つ必要があります。

12.6.2.3. LOAD TABLE tbl_name FROM MASTER 構文

LOAD TABLE tbl_name FROM MASTER

この機能は終了しました。今後は使わないことを勧めます。MySQLの将来のバージョンでは取り除かれることもあります。

LOAD DATA FROM MASTERLOAD TABLE FROM MASTER の現在のインプリメンテーションがとても制限されているので、これらのステートメントは MySQL のバージョン 4.1 以降では廃止予定です。今後のバージョンでは、さらに進歩した技術(「online backup」 と呼ばれる物) を紹介する予定です。その技術は、さらに多くのストレージ エンジンと機能する更なる利点を持ちます。

MySQL 5.1 以前のバージョンで LOAD DATA FROM MASTERLOAD TABLE FROM MASTER を利用する為に推奨する代替方法は、mysqldumpmysqlhotcopy を利用する事です。後者は Perl と2つの Perl モジュール(DBIDBD:mysql)を必要とし、MyISAMARCHIVE テーブルにだけ機能します。mysqldump を利用すると、マスタ上に SQL ダンプを作成でき、それらをスレーブ上の mysql クライアントにパイプ(またはコピー)できます。これは全てのストレージ エンジンに機能するという利点を持ちますが、SELECT を利用して機能する為スピードが大変遅いです。

マスタからスレーブにテーブルのコピーをトランスファします。このステートメントは主に LOAD DATA FROM MASTER 操作をデバッグしながらインプリメントされます。LOAD TABLE を利用するには、マスタ サーバに接続するのに利用されるアカウントはマスタ上に RELOADSUPER 権限を持ち、マスタ テーブルをロードする為に SELECT 権限を持つ必要があります。スレーブ サイドでは、LOAD TABLE FROM MASTER を発行するユーザはテーブルをドロップし作成する権限を持つ必要があります。

LOAD DATA FROM MASTER の条件もこれに適応します。例えば、LOAD TABLE FROM MASTERMyISAM テーブルに対してのみ機能します。

LOAD DATA FROM MASTER のタイム アウト ノートもこれに適応します。

12.6.2.4. MASTER_POS_WAIT() 構文

SELECT MASTER_POS_WAIT('master_log_file', master_log_pos)

このオプションはステートメントではなく関数です。これはスレーブがマスタのバイナリ ログ内の指定された位置までのイベントを読み込み、実行した事を保証する為に利用されます。完全な説明は 項11.10.4. 「その他の関数」 を参照してください。

12.6.2.5. RESET SLAVE 構文

RESET SLAVE

RESET SLAVE がスレーブがマスタのバイナリ ログ内の複製位置を忘れるよう働きかけます。このステートメントは再スタートの時に利用する為の物です。これは master.inforelay-log.info ファイル、全てのリレー ログを削除し、そして新しいリレー ログをスタートします。

注意:スレーブ SQL スレッドによって完全に実行されていなくても全てのリレー ログが削除されます。(もし STOP SLAVE ステートメントを発行していたり、スレーブが高負荷であると、複製スレーブ上にこの状態が存在しやすくなります。)

master.info ファイル内に格納された接続情報は、対応するスタートアップ オプション内で指定された値を利用して速やかにリセットされます。この情報は、マスタ ホスト、マスタ ポート、マスタ ユーザ、そしてマスタ パスワードのような値を含みます。もしスレーブ SQL スレッドが停止した時テンポラリ テーブルの複製の最中で、そして RESET SLAVE が発行されると、これらの複製テンポラリ テーブルはスレーブ上で削除されます。

12.6.2.6. SET GLOBAL SQL_SLAVE_SKIP_COUNTER 構文

SET GLOBAL SQL_SLAVE_SKIP_COUNTER = N

このステートメントは、マスタから次の N イベントをスキップします。これはステートメントによって引き起こされた複製から回復するのに役に立ちます。

このステートメントは、スレーブ スレッドが起動していない時のみ有効です。そうでなければ、エラーを発生させます。

12.6.2.7. SHOW SLAVE STATUS 構文

SHOW SLAVE STATUS

このステートメントは、スレーブ スレッドに不可欠なパラメータ上にステータス情報を提供します。mysql クライアントを利用してこのステートメントを発行すると、より読みやすい水平方向のレイアウトを得る為に、セミコロンではなく \G ステートメント ターミネータを利用する事ができます。

mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
       Slave_IO_State: Waiting for master to send event
          Master_Host: localhost
          Master_User: root
          Master_Port: 3306
        Connect_Retry: 3
      Master_Log_File: gbichot-bin.005
  Read_Master_Log_Pos: 79
       Relay_Log_File: gbichot-relay-bin.005
        Relay_Log_Pos: 548
Relay_Master_Log_File: gbichot-bin.005
     Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
      Replicate_Do_DB:
  Replicate_Ignore_DB:
           Last_Errno: 0
           Last_Error:
         Skip_Counter: 0
  Exec_Master_Log_Pos: 79
      Relay_Log_Space: 552
      Until_Condition: None
       Until_Log_File:
        Until_Log_Pos: 0
   Master_SSL_Allowed: No
   Master_SSL_CA_File:
   Master_SSL_CA_Path:
      Master_SSL_Cert:
    Master_SSL_Cipher:
       Master_SSL_Key:
Seconds_Behind_Master: 8

SHOW SLAVE STATUS は次のフィールドを返します。

  • Slave_IO_State

    スレーブ I/O スレッドの為の SHOW PROCESSLIST のアウトプットの State フィールドのコピー。これで、スレッドが何をしているかを知る事ができます。マスタに接続しようとしている、マスタからイベントを待っている、マスタに再接続している、など。項5.5.1. 「レプリケーション実装の詳細」 にステートの例がリストされています。古いバージョンの MySQL では、マスタへの接続が成功していなくてもスレッドが起動し続ける事ができるので、このフィールドを確認する必要があります。もし起動していれば問題は有りませんが、もしそうでなければ、Last_Error フィールド内にエラーを見つけることができます。(下記で説明)

  • Master_Host

    現在のマスタ ホスト。

  • Master_User

    マスタに接続する為に利用される現在のユーザ。

  • Master_Port

    現在のマスタ ポート。

  • Connect_Retry

    --master-connect-retry オプションの現在の値。

  • Master_Log_File

    I/O スレッドが現在読み込んでいるマスタ バイナリ ログ ファイルの名前。

  • Read_Master_Log_Pos

    現在のマスタ バイナリ ログ内で、I/O スレッドが読み込んだところまでの位置。

  • Relay_Log_File

    現在読み込み、実行をしている SQL スレッドからのリレー ログ ファイルの名前。

  • Relay_Log_Pos

    SQL スレッドが現在のリレー ログ内で読み込み、実行したところまでの位置。

  • Relay_Master_Log_File

    SQL スレッドによって実行された一番最近のイベントを含むマスタ バイナリ ログ ファイルの名前。

  • Slave_IO_Running

    I/O スレッドがスタートされて、マスタに正常に接続したかどうか。MySQL の古いバージョンでは( 4.1.14 と 5.0.12 以前)、スレーブがまだマスタに接続されていなくても Slave_IO_RunningYES です。

  • Slave_SQL_Running

    SQL スレッドがスタートしたかどうか

  • Replicate_Do_DBReplicate_Ignore_DB

    もしあるなら、--replicate-do-db--replicate-ignore-db オプションを利用して指定されたデータベースのリスト。

  • Replicate_Do_TableReplicate_Ignore_TableReplicate_Wild_Do_TableReplicate_Wild_Ignore_Table

    もしあるなら、--replicate-do-table--replicate-ignore-table--replicate-wild-do-table、そして --replicate-wild-ignore_table オプションを利用して指定されたテーブルのリスト。

  • Last_ErrnoLast_Error

    一番最近実行されたクエリに返されるエラー数とエラー メッセージ。エラー数が0で、空の文字列のメッセージであれば、「no error.」 です。もし Last_Error 値が空でなければ、それもスレーブのエラー ログ内に現れます。例:

    Last_Errno: 1051
    Last_Error: error 'Unknown table 'z'' on query 'drop table z'
    

    このメッセージは、テーブル z がマスタ上に存在しそこでドロップされたが、それはスレーブ上には存在しなかった為、スレーブ上で DROP TABLE が失敗した、という事を含んでいます。(これは例えば、複製をセットアップする時にテーブルをスレーブにコピーするのを忘れた時に起きます。)

  • Skip_Counter

    SQL_SLAVE_SKIP_COUNTER に一番最近利用された値。

  • Exec_Master_Log_Pos

    マスタのバイナリ ログから SQL スレッドによって実行された最後のイベントの位置(Relay_Master_Log_File)。(マスタのバイナリ ログ内の Relay_Master_Log_FileExec_Master_Log_Pos)はリレーログ内の(Relay_Log_FileRelay_Log_Pos)に対応しています。

  • Relay_Log_Space

    全ての既存リレー ログを合計したサイズ。

  • Until_ConditionUntil_Log_FileUntil_Log_Pos

    START SLAVE ステートメントの UNTIL 条項内で指定された値。

    Until_Condition は3つの値を持ちます。

    • UNTIL 条項が指定されなければ None

    • もしスレーブがマスタのバイナリ ログ内の指定位置まで読み込んでいたら Master

    • もしスレーブがそのリレー ログ内の指定位置まで読み込んでいたら Relay

    Until_Log_FileUntil_Log_Pos は、SQL スレッドが実行を停止するポイントを定義するログ ファイル名と位置の値を指示します。

  • Master_SSL_AllowedMaster_SSL_CA_FileMaster_SSL_CA_PathMaster_SSL_CertMaster_SSL_CipherMaster_SSL_Key

    これらのフィールドは、もし SSL パラメータがあれば、マスタに接続するスレーブによって利用されるそれらを表します。

    Master_SSL_Allowed はこれらの値を持ちます。

    • もしマスタへの SSL 接続が許可されると Yes

    • もしマスタへの SSL 接続が許可されないと No

    • もし SSL 接続が許可されても、スレーブ サーバが有効な SSL サポートを持っていなければ Ignored

    別の SSL 関連フィールドの値は、--master-ca--master-capath--master-cert--master-cipher、そして --master-key オプションの値に対応します。

  • Seconds_Behind_Master

    このフィールドは、スレーブがどの程度 「late」 であるかの目安です。

    • スレーブ SQL スレッドがアクティブに起動している時(更新を実行している時)、このフィールドはスレッドによって実行されたマスタ上の一番最近のイベントのタイム スタンプから経過した秒数を表します。

    • SQL スレッドがスレーブ I/O スレッドに追いつき、そこからの更なるイベントを待ってアイドル状態になると、このフィールドはゼロになります。

    基本的に、このフィールドはスレーブ SQL スレッドとスレーブ I/O スレッド間の時差を秒数で計算します。

    もしマスタとスレーブ間のネットワーク接続が速ければ、スレーブ I/O スレッドはマスタにとても近いので、このフィールドはマスタと比べてスレーブ SQL スレッドがどれくらい遅いかを表す近似値と言えます。これは、もしネットワークが遅いと参考になる近似値とは 言えません。スレーブ SQL スレッドは頻繁に読み込みが遅いスレーブ I/O スレッドに追いつかれる為、I/O スレッドがマスタよりも遅くても Seconds_Behind_Master は 0 の値を頻繁に示します。言い換えると、このカラムは速いネットワークに対してだけ有効である という事です。

    この時間差の算出は、マスタとスレーブが同一の時計を持たなくても機能します。(時計の違いはスレーブ I/O スレッドがスタートする時に計算され、その時点から一定であると仮定されます。)Seconds_Behind_Master は、もしスレーブ SQL スレッドが起動していなかったり、スレーブ I/O スレッドが起動していない、またはマスタに接続されていない時は、NULL です(「unknown」 を意味する)。例えばもしスレーブ I/O スレッドが、再接続前に --master-connect-retry オプションによって与えられた秒数眠っていたとすると、スレーブはマスタが何をしているか知る事ができないので NULL が表示され、その為どの程度遅れているか正確に知る事ができません。

    このフィールドには1つ制限があります。タイムスタンプは複製中に維持されますので、これは、もしマスタ M1 自体が M0 のスレーブだったら、M0 のビンログからのイベントを複製する上で発生したM1のビンログからのイベントは、M0 のイベントのタイムスタンプを持つ、という事を意味します。これは MySQL が TIMESTAMP を正常に複製する事を可能にします。しかし、Seconds_Behind_Master の欠点は、もし M1 もクライアントから直接更新されると、最後の M1 のイベントは M0 からであったり、直接の更新からの一番最近のタイムスタンプであったりする為、その値はランダムに外れる、という事です。

12.6.2.8. START SLAVE 構文

START SLAVE [thread_type [, thread_type] ... ]
START SLAVE [SQL_THREAD] UNTIL
    MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos
START SLAVE [SQL_THREAD] UNTIL
    RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos

thread_type: IO_THREAD | SQL_THREAD

thread_type オプションを持たない START SLAVE は両方のスレーブ スレッドをスタートします。I/O スレッドはマスタ サーバからクエリを読み、それらをリレー ログ内に格納します。SQL スレッドはリレー ログを読みこみ、クエリを実行します。START SLAVESUPER 権限を必要とします。

もし START SLAVE がスレーブ スレッドのスタートに成功すると、エラー無しで返ります。しかし、そのよう場場合でも、スレーブ スレッドがスタートし、その後停止する、という事になり得ます。(例えば、マスタに接続できなかったり、マスタのバイナリログを読めなかったり、それ以外の問題の為)START SLAVE からはこれについての警告はありません。スレーブ スレッドによって発生したエラー メッセージに対するスレーブのエラー ログの確認、また SHOW SLAVE STATUS を利用してそれらが満足に機能している事を確認する必要があります。

どのスレッドをスタートするかを指定する為に、ステートメントに IO_THREADSQL_THREAD オプションを追加する事ができます。

UNTIL 条項は、SQL スレッドがマスタ バイナリ ログ、またはスレーブ リレー ログ内の指定ポイントに達するまで、スレーブがスタート、起動する事を指定する為に追加されるかもしれません。SQL スレッドがそのポイントに達すると、それは停止します。もし SQL_THREAD オプションがステートメント内で指定されると、それは SQL スレッドのみをスタートします。そうでなければ、それはスレーブ スレッドを両方スタートします。もし SQL スレッドが起動していると、UNTIL 条項は無視され、警告が発行されます。

UNTIL 条項には、ログ ファイル名と位置の両方を指定する必要があります。マスタとリレー ログ オプションを混同しないでください。

全ての UNTIL 条件は、後に続く STOP SLAVE ステートメント、UNTIL 条項を含まない START SLAVE ステートメント、またはサーバの再スタートによってリセットされます。

UNTIL 条項は、デバッグの複製や、スレーブがステートメントを複製するのを防ぎたいポイントの直前まで複製が続くように働きかけるのに役に立ちます。例えば、マスタ上でもし分別のない DROP TABLE ステートメントが実行されたら、スレーブがそのポイントまでは実行し、それ以上は進まないように指示する為 UNTIL を利用する事ができます。イベントが何であるかを調べる為には、マスタ ログかスレーブ リレー ログと共に、mysqlbinlog 利用するか、または SHOW BINLOG EVENTS ステートメントを利用してしてください。

もしスレーブ プロセス複製クエリをセクションの中で持つ為に UNTIL を利用していたら、スレーブ サーバがスタートする時に SQL スレッドが起動するのを防ぐ為に、スレーブを --skip-slave-start オプションでスタートするする事が推奨されています。予期せぬサーバの再スタートによって忘れられる事を防ぐ為、コマンド ライン上ではなく、オプション ファイル内でこのオプションを利用するのが一番良いでしょう。

SHOW SLAVE STATUS ステートメントは UNTIL 条件の現在の値を表示するアウトプット フィールドを含んでいます。

MySQL の古いバージョン内では(4.0.5以前)、このステートメントは SLAVE START と呼ばれていました。この利用方法は MySQL 5.1 内でいまだに後方互換の為に許容されていますが、廃止予定になっています。

12.6.2.9. STOP SLAVE 構文

STOP SLAVE [thread_type [, thread_type] ... ]

thread_type: IO_THREAD | SQL_THREAD

スレーブ スレッドを停止します。STOP SLAVESUPER 権限を必要とします。

START SLAVE のように、このステートメントは、スレッドに名前を付けたり、スレッドを停止したりする為に IO_THREADSQL_THREAD オプションと共に利用されます。

MySQL の古いバージョン内では(4.0.5以前)、このステートメントは SLAVE STOP と呼ばれていました。この利用方法は MySQL 5.1 内でいまだに後方互換の為に許容されていますが、廃止予定になっています。

12.7. プリペアド ステートメントの為の SQL 構文

MySQL 5.1 はサーバ サイドのプリペアド ステートメントへのサポートを提供します。妥当なクライアント プログラムインターフェースを利用するという条件で、このサポートは MySQL 4.1 内でインプリメントされた有効なクライアント/サーバ バイナリ プロトコルを駆使します。インターフェース候補は、MySQL C API クライアント ライブラリ(C プログラムの為の物)、MySQL コネクタ/J(プログラムの為の物)、そして MySQL コネクタ/NET です。例えば、C API はそのプリペアド ステートメント API を構成する関数呼び出しのセットを提供します。詳しくは 項23.2.4. 「準備されたC APIステートメント。」 を参照してください。別の言語インターフェースは、バイナリ プロトコルを C クライアント ライブラリ内でリンクさせて利用するプリペアド ステートメントのサポートを提供する事ができます。その1つの例が、PHP 5.0 以降で有効な、mysqli extension です。

プリペアド ステートメントの代替 SQL インターフェースが有効です。このインターフェースはプリペアド ステートメント API にバイナリ プロトコルを利用する事ほど有効では有りませんが、これは SQL レベルで直接有効なのでプログラミングを必要としません。

  • 有効なプログラミング インターフェースが無い時にこれを利用する事ができます。

  • mysql クライアント プログラムのように、実行されるサーバに SQL ステートメントを送る事を許容する全てのプログラムからこれを利用する事ができます。

  • もしクライアントが古いバージョンのクライアント ライブラリを利用していてもこれを利用する事ができます。たった1つ要求される事は、プリペアド ステートメントの SQL 構文をサポートするのに充分新しいサーバに接続できなければいけないという事です。

プリペアド ステートメントの SQL 構文は、次のような場合に利用する為の物です。

  • プリペアド ステートメントが、それをコード化する前に自分のアプリケーション内でどのように機能するかをテストしたい。

  • アプリケーションが、プリペアド ステートメントを実行するに当たり問題が発生し、何が原因なのかを調査したい。

  • バグ リポートをファイルする為に、プリペアド ステートメントについて起きている問題を説明するテスト ケースを作成したい。

  • プリペアド ステートメントを利用したいが、それらをサポートするプログラム API へのアクセスが無い。

プリペアド ステートメントの SQL 構文が3つの SQL ステートメントに基づいている。

  • PREPARE stmt_name FROM preparable_stmt

    PREPARE ステートメントはステートメントを準備し、後でそのステートメントを参照する物によって、名前 stmt_name を割り当てます。ステートメント名は大文字と小文字を区別しません。 preparable_stmt は文字列直定数、またはステートメントのテキストを含むユーザ変数です。テキストは複数ステートメントではなく、単一 SQL ステートメントを表さなければいけません。ステートメント内で ‘?’ 文字は、後でクエリを実行する時にデータ値がクエリのどこに結合されるかを指示するパラメータ メーカとして利用されます。‘?’ 文字は、それらを文字列値に結合したいとしても、引用符で囲んではいけません。パラメータ メーカは、SQL キーワードや識別子等ではなく、データ値が現れるところでのみ利用する事ができます。

    もし与えられた名前を持つプリペアド ステートメントが既に存在したら、新しいステートメントが準備される前にそれは暗黙的に割り当て解除されます。これは、もし新しいステートメントがエラーを含み準備できないとしたらエラーは返され、与えられた名前のステートメントは存在しない、という意味です。

    プリペアド ステートメントの範囲は、それが作成される範囲内のクライアント セッションです。他のクライアントはそれを見る事ができません。

  • EXECUTE stmt_name [USING @var_name [, @var_name] ...]

    ステートメントを準備した後、プリペアド ステートメント名を参照する EXECUTE ステートメントを利用してそれを実行します。もしプリペアド ステートメントがパラメータ メーカを含んでいたら、パラメータに結合される値を含むユーザ変数をリストする USING 条項を提供する必要があります。パラメータ値はユーザ変数のみで提供でき、USING 条項はステートメント内のパラメータ メーカ数と全く同数の変数に名前をつける必要があります。

    各実行の前に、与えられたプリペアド ステートメントを複数回実行し、それに異なる変数を与え、また変数を異なる値に設定する事ができます。

  • {DEALLOCATE | DROP} PREPARE stmt_name

    プリペアド ステートメントの割り当てを解除するには、DEALLOCATE PREPARE ステートメントを利用してください。割り当て解除した後にプリペアド ステートメントを実行しようとするとエラーが発生します。

    もし以前のプリペアド ステートメントの割り当て解除をしないでクライアント セッションを終了しようとすると、サーバがそれを自動的に割り当て解除します。

次の SQL ステートメントはプリペアド ステートメント内で利用できます。CREATE TABLEDELETEDOINSERTREPLACESELECTSETUPDATE、そしてほとんどの SHOW ステートメント。

MySQL 5.1.10 以降、次の追加ステートメントがサポートされています。

ANALYZE TABLE
OPTIMIZE TABLE
REPAIR TABLE

MySQL 5.1.12 以降、次の追加ステートメントがサポートされています。

CACHE INDEX
CHANGE MASTER
CHECKSUM {TABLE | TABLES}
{CREATE | RENAME | DROP} DATABASE
{CREATE | RENAME | DROP} USER
FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES
  | LOGS | STATUS | MASTER | SLAVE | DES_KEY_FILE | USER_RESOURCES}
GRANT
REVOKE
KILL
LOAD INDEX INTO CACHE
RESET {MASTER | SLAVE | QUERY CACHE}
SHOW BINLOG EVENTS
SHOW CREATE {PROCEDURE | FUNCTION | EVENT | TABLE | VIEW}
SHOW {AUTHORS | CONTRIBUTORS | WARNINGS | ERRORS}
SHOW {MASTER | BINARY} LOGS
SHOW {MASTER | SLAVE} STATUS
SLAVE {START | STOP}
INSTALL PLUGIN
UNINSTALL PLUGIN

その他のステートメントはまだサポートされていません。

次の例は、2辺の長さが分かっている3角形の斜辺を算出するステートメントを準備する為の、2つの同等な方法を表しています。

最初の例は、ステートメントのテキストを提供する為に、文字列直定数を利用してプリペアド ステートメントを作成する方法を表しています。

mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql> SET @a = 3;
mysql> SET @b = 4;
mysql> EXECUTE stmt1 USING @a, @b;
+------------+
| hypotenuse |
+------------+
|          5 |
+------------+
mysql> DEALLOCATE PREPARE stmt1;

2つ目の例も似ていますが、ステートメントのテキストをユーザ変数として提供しています。

mysql> SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql> PREPARE stmt2 FROM @s;
mysql> SET @a = 6;
mysql> SET @b = 8;
mysql> EXECUTE stmt2 USING @a, @b;
+------------+
| hypotenuse |
+------------+
|         10 |
+------------+
mysql> DEALLOCATE PREPARE stmt2;

プレースホルダは、プリペアド ステートメントを利用する時に LIMIT 条項の引数に対して利用できます。詳しくは 項12.2.7. 「SELECT 構文」 を参照してください。

プリペアド ステートメントの SQL 構文は、ネスト化された種類の中では利用できません。これは、PREPARE にパスしたステートメント自体は PREPAREEXECUTE、または DEALLOCATE PREPARE ステートメントになり得ないという事です。

プリペアド ステートメントの SQL 構文は、プリペアド ステートメント API コールを利用する事とは違います。例えば、PREPAREEXECUTE、または DEALLOCATE PREPARE ステートメントを準備する為に mysql_stmt_prepare() C API 関数を利用する事はできません。

プリペアド ステートメントの SQL 構文はストアド プロシージャ内で利用できますが、ストアド ファンクションやトリガ内では利用できません。

プリペアド ステートメントの SQL 構文は、マルチ ステートメント(‘;’ 文字で分割される、単一文字列内の複数ステートメントの事)をサポートしません。

アダルトレンタルサーバー