データ移行の手順書を作成している時、移行データが入ったcsvファイルをデータベースにインポートしていました。その際にALTER TABLEを使用した為今回はALTER TABLEを使う際の注意点を紹介します。
使用データベース:MySQL
目次
作成したばかりのデータベースの設定がしたい
今回は移行前のデータベースから抽出したcsvファイルを移行先のデータベースに入るように直した上で移行しようとしていました。
しかし問題が1つあり、移行前のデータベースと新しいデータベースではカラムの数や順番が異なっています。そこで一旦、移行前のデータベースに則った仮のデータベースを作成し、そこにインポートする事にしました。
その後、仮のデータベースを新しいデータベースに則った形に作り変えた上でcsvファイルを出力し、新しいデータベースにインポートします。
その仮のデータベースの設定をする際にALTER TABLEを使い、データベースの設定を行うことにしました。
ALTER TABLEとは何か
テーブルの構造を変更する時に使われます。今回はカラムの内容の変更だけ行いますが、カラムやインデックスの追加、削除にも使うことができます。
設定したはずの内容がなくなっている
長いSQL文を書くのに自信がなかった為、1つのカラムに対しALTER TABLEを使った短いSQL文を複数回行うことで設定を行おうとしました。
しかし、SQL文の入力を終えて確認してみるとSQL文を入力する過程で既にカラムに設定されているはずの内容が、別のALTER TABLEを使ったSQL文をそのカラムに対して入力した後になくなっていたのです。
検証1 どういう時に起こるのか
ここでは、ALTER TABLEを使用したSQL文を内容を変えた上で同じカラムに対して2度行った場合を検証しています。
1.create database information default character set utf8mb4;
を実行し、データベースを作成する。
2.use information;
を実行し、先ほど製作したデータベースに接続する。
3.CREATE TABLE test(test_flg int);
を実行しテーブルを作成する。
4.test_flgがint型でデフォルト値がNULLであることを確認する。
mysql> show create table test\G;
*************************** 1. row ***************************
Table: test
Create Table: CREATE TABLE `test` (
`test_flg` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
5.ALTER TABLE test ALTER test_flg SET DEFAULT 3;
を実行しtest_flgのデフォルト値を3にする。
6.test_flgのデフォルト値が3になっていることを確認。
mysql> show create table test\G;
*************************** 1. row ***************************
Table: test
Create Table: CREATE TABLE `test` (
`test_flg` int(11) DEFAULT '3'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
7.ALTER TABLE test MODIFY test_flg int COMMENT ‘テスト’;
を実行。
8.test_flgにコメントが追加されていてデフォルト値が3ではないことを確認。
mysql> show create table test\G;
*************************** 1. row ***************************
Table: test
Create Table: CREATE TABLE `test` (
`test_flg` int(11) DEFAULT NULL COMMENT 'テスト'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
一度行ったデフォルト値の設定がなくなっています。
ただ、SQL文を実行する順番を変えればこの症状が出ない事があった為もう1つ検証してみることにしました。
検証2 実行する順番を入れ替えたらどうなるのか
先程の条件にカラムへのコメントの追加とデフォルト値の設定の順番を入れ換えて行っています。
1.create database information2 default character set utf8mb4;
を実行し、データベースを作成する。
2.use information2;
を実行し、先ほど製作したデータベースに接続する。
3.CREATE TABLE test2(test2_flg int);
を実行しテーブルを作成する。
4.test2_flgがint型でデフォルト値がNULLであることを確認する。
mysql> show create table test2\G;
*************************** 1. row ****************************
Table: test2
Create Table: CREATE TABLE `test2` (
`test2_flg` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
5.ALTER TABLE test2 MODIFY test2_flg int COMMENT ‘テスト2’;
を実行し、コメントを追加する。
6.test2_flgにコメントが追加されていることを確認する。
mysql> show create table test2\G;
*************************** 1. row ***************************
Table: test2
Create Table: CREATE TABLE `test2` (
`test2_flg` int(11) DEFAULT NULL COMMENT 'テスト2'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
7.ALTER TABLE test2 ALTER test2_flg SET DEFAULT 4;
を実行し、デフォルト値を4にする。
8.これまでの設定した内容が消えていないことを確認。
mysql> show create table test2\G;
*************************** 1. row ***************************
Table: test2
Create Table: CREATE TABLE `test2` (
`test2_flg` int(11) DEFAULT '4' COMMENT 'テスト2'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
こちらではこれまでの設定を引き継いだまま設定を変更することができました。
原因
ALTER TABLEを使う上でMODIFY、または今回は使っていませんがCHANGEを使う場合、元の定義に存在していても、新しい定義として指定されていない属性は引き継がれません。
よって、1つのカラムに対して設定する全ての属性を元々設定されていたものも含めて一度にまとめて設定する必要があることを知りませんでした。
まとめ
ALTER TABLEを使い、且つMODIFYもしくはCHANGEを使う際はそのカラムに設定したい内容は一度にまとめて設定する事。
それができない場合は先にMODIFY、CHANGEを使ったSQL文を行い、その後MODIFY、CHANGEを使わずに足りていない他の設定を行うこと。
参考サイト
昨年大学を卒業したばかりのエンジニアです。CakePHPを勉強中です。拙い部分も多いですがよろしくお願いします。