LoginSignup
1
0

More than 1 year has passed since last update.

MySQLで「Column cannot be null.」 timestampとdatetimeに振り回された話

Last updated at Posted at 2020-08-21

データベースサーバの移行に際して起こったトラブル.

MySQLにて,データ挿入時に自動でタイムスタンプを付与したい…

> CREATE TABLE `my_table` (
> `insert_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP PRIMARY KEY,
> `my_column1` VARCHAR(4) NOT NULL,
> `my_column2` VARCHAR(4) NOT NULL,
> `my_column3` VARCHAR(4) NOT NULL);

こんなテーブルを作った.
insert_timeはNULLを許容しないが,もしNULLを入れても自動で現在時刻に差し替えてくれるはず…!

データを挿入してみる.

> INSERT INTO my_table VALUES (null, "aaaa", "iiii", "uuuu");

しかし…

Column 'insert_time' cannot be null.

移行前のサーバではこれで動いてたはずなのに…

解決策

その1:insert_timeを指定しないようにする

> INSERT INTO my_table (my_column1, my_column2, my_column3) VALUES ("aaaa", "iiii", "uuuu");

めんどい…

その2:nullではなくdefaultを指定する

> INSERT INTO my_table VALUES (default, "aaaa", "iiii", "uuuu");

なるほど,nullで指定してしまってたからいけなかったのか.
nulldefaultに置き換わるわけではなかったのね!

デフォルト値を使いたいなら

  • 何も指定しない
  • defaultを指定する

のいずれかが必要だということだ.

しかし,移行前のサーバではなぜエラーを吐かなかったのか?

## 勘違いの原因
移行前のサーバを調べ直したところ,insert_timeの型がdatetimeじゃなくてtimestampだったのだ!

timestamp型なら,

> INSERT INTO my_table VALUES (null, "aaaa", "iiii", "uuuu");

も問題なく通る.

Q. じゃあtimestamp型を使うべきか?

A. datetimeを使うべき

timestampの方がdatetimeよりも使い勝手が悪いみたい.
一番分かりやすいのは,datetimeは「9999年」まで指定できるのに対して,
timestampは「2038年」までしか指定できないということ.

2038年なんてそんなに遠い未来じゃないから,どうしてもtimestampを使わざるをえないような人以外は,datetime使えばいいよね.

他にもいろいろ違うっぽい.
(参考:MySQLのDATETIME型とTIMESTAMP型の違いを検証してみた

結論

原因も知れたしスッキリした!

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0