結論
何がいいたいかといいますと0000-00-00 00:00:00があるとORMも死ぬし、DBマイグレーションツールも死ぬし、そもそもMySQLからポスグレにデータを持っていくこともFDWをすることも出来なくて死ぬのじゃ。
— そーだい@初代ALF (@soudai1025) 2018年4月25日
色々困るので使わない。
理由
以下に理由を述べる
SQL標準ではない
正論で殴った場合。
0000-00-00 00:00:00の仕様が難しい
0000-00-00 00:00:00
はMySQLの独自な仕様で NOT NULL制約のカラムではNULLと等価であり、NULLではない という仕様がある。
"NOT NULL として宣言された DATE および DATETIME カラムでは、次のようなステートメントを使用することで、特殊な日付 '0000-00-00' を検索できます"https://t.co/qLBYqy7FZm
— とみたまさひろ🍣🍺 (@tmtms) 2015年12月17日
いや、できなくていいんですけど…。
@sakaik IS NULL と IS NOT NULL の両方に含まれます!
— とみたまさひろ🍣🍺 (@tmtms) 2015年12月17日
この仕様を知らないと意図しない結果を取得することになる。
ORMなどが対応してない
アプリケーションを作る時、ORMだったりDatetimeオブジェクトを操作することはよくあることだ。
しかし 0000-00-00 00:00:00
に対応していないことが多く、不正な値として扱われる。
doctrine2で$hoge->setBirthday(new DateTime("'0000/00/00'))
— そーだい@初代ALF (@soudai1025) 2015年1月5日
したいけどPHPのDATE型が00/00をサポートしてない。
MySQLはおkなのでdoctrine2のdate型にStringをどうにか突っ込めないものか…
DB移行で困る
なんらかの理由でMySQL以外のRDBMSに移行しようとした時、 0000-00-00 00:00:00
をサポートしていないことで値の修正が必要になる。
具体的な例だとMySQLからPostgreSQLにデータを移そうとした時にerrorでコケる。
AWS DMSもFDW for MySQLもそこを意図してないので自分で値を修正してやる必要がある。
なかなか異種間DB移行はないかもしれないけど、いざ必要となった時にめちゃくちゃ困る。
まとめ
0000-00-00 00:00:00 は自然界にはないのじゃ
— そーだい@初代ALF (@soudai1025) 2018年4月25日
せめてNULLだったり 0001-01-01 00:00:00 1000-01-01 00:00:00 を使いましょう。
って7年前の俺に言いたい。
2020/07/03 追記
範囲は '1000-01-01 00:00:00' から '9999-12-31 23:59:59' です。
コメントで指摘いただいたので修正した。
追記(2018/05/14)
MySQLの0000-00-00 00:00:00は使ってはならない - そーだいなるらくがき帳b.hatena.ne.jpzero date問題はMySQLerにはあるあるネタだけど、SQLモードでzero dateを禁止できるんで、SQLモードにも触れて欲しかった。5.7からデフォルトでNO_ZERO_DATE, NO_ZERO_IN_DATEモードがONになっている。
2018/05/14 17:06
SQLモードを正しく設定していればこの問題にはぶち当たらないのでSQLモードはちゃんと kamipo TRADITIONAL
を使うべし。