質問: PostgresSQLを使用していますが、データベースのテーブル設計に関して、日付に関する型の適切な使い分けを知りたいです。 大は小をかねるではないですが、調べれば調べるほど日付に関する型は全部Timestamp型でも問題ないような気がしています。どういった場合にTime型やDate型を使用するのでしょうか? ※PostgresSQLのバージョンは8.4.17です。 ※2038年問題は考慮しません。
回答: まずは、きちんとしたリファレンスから見てみましょう。 8.5. 日付/時刻データ型 簡単にまとめると、(タイムゾーンやら浮動小数点表現やらのことは無視しておきます) ``` timestamp 日付と時刻両方 date 日付 time 時刻 ``` と言うことになります。 さて、ここで日付のみを表したい項目にtimestamp型を使用した場合、どうなるでしょう。当然比較などの場合、時刻部分を勘定に入れずに日付が同じであれば「一致」と判断したいわけです。 2つの対応方法をすぐに思いつくでしょう。 * 時分秒以下を表す部分は必ず0を入れることにする * 比較の際は必ず時分秒以下を切り捨ててから比較する このような一種の「ルール」による回避は、一人の人間が各テーブルのカラム定義の隅々まで完全に把握していることができるような小規模システムでは十分機能するでしょうが、システムの規模が大きくなって、参加する開発者の数が増大するのに連れ、そう言ったルールを徹底するのはどんどん難しくなっていきます。(`now`なんて便利な慣用句は「日付だけのつもり」のカラムに適用したからと言って、自動的に時分秒以下の部分に0を入れてくれたりしません。) 時刻のみを表すカラムにtimestampを適用した場合も概ね同様の問題が発生します。 また、こう言ったルールの不徹底によるバグは、「エラー等は出ずに動いちゃうけど、実行してみると、結果が思ったのとちょっと違う」と言う形で現れがちで、なかなか発見されにくく修正も困難になることが多いです。事実上DateTime型しか存在しないDBMS上で動くシステムでは、この手のバグ修正に悩まされたことが何度もあります...。 DBにデータを入れるにあたっては、他にも色々な「ルール」があるものなので、これだけで全てが解決するわけではありませんが、少なくとも程度の問題として、**日付だけを表すカラムにはdate型、時刻だけを表すカラムにはtime型を使用する**ことにしておけば、「ルール」に反したコードのせいで予期せぬことが起こる可能性を大きく減らしてくれる、と言って良いでしょう。