先日、諸事情あってMySQLのテーブルをコピーしておきたいことがありました。
SELECT以外の操作は滅多にやらないので、少し調べて出てきたのがこちらの方法です。
1つ目のクエリで元のテーブルと同じ構造のテーブルを作り、
2つ目のクエリでデータを移しています。
CREATE TABLE new_table_name LIKE table_name;
INSERT INTO new_table_name SELECT * FROM table_name;
今回必要だった要件は、これで満たせたのですが、一個のクエリでコピーする方法があったはず、
というおぼろげな記憶があったのでもう少し探して見つけたのがこちら。
CREATE TABLE new_table_name SELECT * FROM table_name;
これなら1行で中のテーブルをコピーできます。
なんで一行で済む2番目の方法よりも、クエリを二つ使う1番目の方法の方がよく使われているのか気になったので、後日実験してみました。
結果わかったのは、データはどちらの方法でも同じようにコピーされるのですが、
2番目の方法では、テーブルの設定の一部がコピーされないことです。
試したのがこちら。
まず、元のテーブル。
mysql> desc sample1;
+------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| created_at | datetime | NO | | CURRENT_TIMESTAMP | |
| updated_at | datetime | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+------------+--------------+------+-----+-------------------+-----------------------------+
1番目の方法でコピーしたテーブル。こちらは元のテーブルと同じです。
mysql> desc sample2;
+------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| created_at | datetime | NO | | CURRENT_TIMESTAMP | |
| updated_at | datetime | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+------------+--------------+------+-----+-------------------+-----------------------------+
2番目の方法でコピーしたテーブル。
auto_incrementやDefaultの値の一部、主キー属性などがコピーされていません。
mysql> desc sample2;
+------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | | 0 | |
| name | varchar(255) | YES | | NULL | |
| created_at | datetime | NO | | CURRENT_TIMESTAMP | |
| updated_at | datetime | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+------------+--------------+------+-----+-------------------+-----------------------------+
値はどちらの方法でもコピーされるのですが、
見落としがちな部分に差異があるので注意が必要ですね。