MySQLタイムスタンプ列にNULLを挿入/更新する際の予期しない動作を観察しています。
以下のステートメントを考慮してください。
_create table temp(id int, hireDate timestamp default 0);
insert into temp (id) values(1);
insert into temp (id, hireDate) values(2, null);
select * from temp;
id hireDate
-----------------------------
1
2 2012-09-19 10:54:10.0
_
最初の挿入(hiredate
がSQLで指定されていない場合、hireDateはnull(0)
になります。
ただし、明示的なNULLがSQLで渡されると、現在の日付時刻が挿入されますが、これは予期しないことです。なぜこれが起こるのですか?
注:Hibernateは2番目のタイプの挿入を使用するため、問題になります。タイムスタンプ列にnullを挿入するにはどうすればよいですか?
http://dev.mysql.com/doc/refman/5.0/en/timestamp-initialization.html
さらに、NULL値を許可するようにNULL属性で定義されていない限り、任意のTIMESTAMP列をNULL値に割り当てることにより、現在の日時に初期化または更新できます。
テーブルの作成:
create table penguins(id int primary key auto_increment, the_time timestamp NULL);
いくつかの行を挿入:
insert into penguins(the_time) values (now());
insert into penguins(the_time) values (null);
insert into penguins(the_time) values (0);
insert into penguins(the_time) values ('1999-10-10 01:02:03');
どの印刷:
select * from penguins
1 2015-01-23 15:40:36
2
3 0000-00-00 00:00:00
4 1999-10-10 01:02:03
2行目のデータ型:timestamp
のthe_time
という列の値はNULLです。
HireDate列のデフォルト値を変更する必要があります。デフォルト値はnullでなければなりません
この
create table temp(id int, hireDate timestamp default 0);
これになります:
create table temp(id int, hireDate timestamp null);
アプリケーションの値をMySQLタイムスタンプタイプの列に格納しないでください。タイムスタンプタイプは、データベースサーバー側の動的タイムスタンプにのみ使用します(DEFAULTおよびON UPDATE列属性を参照)。列を「mysql_row_created_at」および「mysql_row_updated_at」と呼んで明示的にします。
MySQLは物理的にそのtimestamp-typeを数値のUNIX-Epoch-deltaとして格納するため、UTCの暗黙のタイムゾーンがあり、セッション(AKA接続)レベルでのタイムゾーンの変更の影響を受けないことに注意してください。
既知のタイムゾーンを持つ値を保存する場合は、「datetime」タイプから離れてください。 'datetime'型は、パックされた数値の文字列によく似ています。それとともに保存されるタイムゾーンの詳細はありません。
通常、「日付」タイプを使用しても問題ありません。ただし、一部のコンテキストでは、(アクティブなタイムゾーンの)真夜中の日時として解釈されるため、回避する必要があるすべての「日時」関連の混乱につながることに注意してください。
アプリケーション側の日時値については、 'int unsigned'、 'bigint'(signed)、 'double'(signed)、またはdecimal(N、P)を使用して、UNIX-Epoch-deltaを単純に格納します。秒でない場合は、列名の接尾辞に解像度を表示してください。
例:
`mysql_row_created_at` TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
`mysql_row_updated_at` TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`Epoch` int unsigned NOT NULL,
`Epoch_ms` bigint NOT NULL,
`Epoch_us` bigint NOT NULL,
`Epoch` double NOT NULL,
`Epoch6` decimal(16,6),
データベースをできるだけダムストレージとして扱います。したがって、変換はアプリケーション側でのみ実行し、データベース側では実行しないでください。
知っておきたいこと:
SELECT @@GLOBAL.TIME_ZONE
, @@SESSION.TIME_ZONE
, @@SESSION.TIMESTAMP
, UNIX_TIMESTAMP(NOW(6))
;
テーブルのhireDate
coloumnにNULLを挿入する場合は、nullを指定する必要があります
INSERT INTO temp (id, hireDate) VALUES(3, null);
Datatype
のhireDate
はtimestamp
であり、列の作成時にnullとして定義する必要があるため