MySQL:TIMESTAMPフィールドが使い物にならない理由

日時を表すフィールドとしてはTIMESTAMPとDATETIMEというフィールド型がある。どちらもJava上からは(MySQLドライバの扱いとしては)、java.sql.Timestampになるようだ。

しかし、この二つには大きな違いがあり、TIMESTAMP型は「使い物にならない」。その理由をまとめてみる。

2038年問題がある

良く言われることだが、このフィールドの値は2038年までしか対応していない。

勝手にデフォルトが設定される

どういうわけか、例えば「create table something (a timestamp)」などとすると、実際に作成されるフィールドは、「a timestamp not null default current_timestamp on update current_timestamp」になってしまう。これはもちろんMySQLシステムの設定によるようだが、デフォルトではこういった振る舞いになる。

これを避けるには、例えば「a timestamp null default null」などとするわけだが、通常の意味での「a timestamp」を作成することはできないようだ。

このあたりの事情は以下にある。

値がOSのロケールに依存してしまう

おおよそデータベースシステムのTIMESTAMP値というのは、ロケールを持たない値、つまりOSのロケールが変わろうとも、同じ値になるのだが、しかし、MySQLのTIMESTAMP値はOSのロケールに依存してしまうのである。

これは以下に説明がある。

つまり、うっかりロケールを変更しようものなら、全く別の値になってしまう。

DATETIMEを使う

これらの振る舞いは非常にわかりにくく制御しにくい。特に以下の余計な点は問題だ。

  • MySQLシステムの設定に振る舞いが依存する
  • OSのロケール設定に振る舞いが依存する。

これを避けるためにはDATETIMEを使うしかない。