2016年11月13日日曜日

MySQLの timestamp型が、なかなか厄介。

オフィス狛 技術部です。

弊社ではしばらく使う事のなかったMySQLですが、
とあるプロジェクトで久しぶりに使い、そしてハマりました。

問題となったテーブル

まず、以下のようなCreate文を実行しました。
CREATE TABLE koma_test (
      koma_test_id bigint NOT NULL AUTO_INCREMENT,
      koam_code varchar(2) NOT NULL,
      test_count int,
      test_fee decimal(7,0),
      has_deleted boolean DEFAULT false NOT NULL,
      entry_datetime timestamp NOT NULL,
      entry_user varchar(100),
      update_datetime timestamp NOT NULL,
      update_user varchar(100),
      PRIMARY KEY (koma_test_id)
);

entry_datetime」「update_datetime」などは、システムで良くあるタイムスタンプ系のカラムです。
日時はプログラム側で設定する事を想定しています。

発生した現象

本来、プログラム側では登録時(Insert時)のみ「entry_datetime」が設定され、
それ以降、その値は変わらない想定でした。

ところが、テーブル更新時(Update時)に「entry_datetime」が勝手に更新されていたのです。
当然最初はプログラムを疑いましたが、プログラムに問題はありませんでした。

で、ちょっとハマった後、何気なく作成されたテーブルの定義を確認すると、
「entry_datetime」に「CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP」が付いているのです。
(「update_datetime」には付いていない)

もちろん、Create文には、そのような指定はしていません。
どうやら、timestamp型には、デフォルトで「CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP」が付いてしまうようです。
※他のサイトの情報だと、NULL 許可していても、NOT NULL にもなってしまうようです。

なんて余計なお世話だ・・・とも思いましたが、
まあ、「timestamp」という属性名だし、そういう事になりますよね・・・
タイムスタンプ系の使い道で無い場合、型は「datetime」にすれば良いだけですからね。

とは言うものの、今のままでは、本来の用途に使えないので、テーブルの定義を変更します。
ALTER TABLE koma_test CHANGE entry_datetime entry_datetime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

注意事項ですが、デフォルト値の「CURRENT_TIMESTAMP」も削除したいからといって、
ALTER TABLE koma_test CHANGE entry_datetime entry_datetime TIMESTAMP NOT NULL;
というSQLを流してしまうと、
またデフォルトの「CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP」が付いてしまいます。

MySQLを使い込んでいる方ですと、「そりゃ、そうでしょ」レベルの話なのかもしれませんが、
久しぶりに使うと、ハマってしまいますね。


0 件のコメント:

コメントを投稿