CREATE TABLE 構文

1. サイレント カラム仕様変更
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. ストレージエンジンとテーブルタイプ でテーブルを表す為にそれぞれのストレージ エンジンがどのファイルを作成するのか説明されています。もしテーブル名が特別な文字を含んでいる場合、そのテーブル ファイルの名前は項 「ファイル名への識別子のマッピング」に表されているようにそれらの文字が暗号化された形を含んだ物になります。

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

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

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) ストレージエンジン」 を参照してください。
MERGE 1つのテーブルとして利用される MyISAM テーブルの集まり。また、MRG_MyISAM としても知られています。詳しくは 項13.6. 「MERGE ストレージエンジン」 を参照してください。
MyISAM MySQL に利用されるデフォルト ストレージ エンジンであるバイナリ ポータブル ストレージ エンジン。詳しくは 項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 を利用すれば適応されます。

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

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

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

パーティションは修正し、マージし、テーブルに追加し、テーブルからドロップする事ができます。これらのタスクを成し遂げる為の基本的な MySQL ステートメントについての情報は、項 「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 の最中の並列挿入を許可しません。

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

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

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

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

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

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

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

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

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