Mysql 5.7.28では、次のようなテーブルを作成します。
create table t1 (
id int not null,
d1 timestamp)
engine=innodb;
これは正常に機能しますであり、d1
なので non-null
とdefault value current_timetamp
、on update current_timestamp
。
しかし、以下のように2つのタイムスタンプフィールドを持つ同じテーブルを作成しようとすると、
create table t1 (
id int not null,
d1 timestamp,
d2 timestamp)
engine=innodb;
エラーが発生します:
SQLエラー(1067): 'd2'のデフォルト値が無効です
エラーが発生する理由2番目のタイムスタンプを追加した場合のみフィールド?
これはmysqlのバグですか、それとも予期される動作ですか?
この動作は explicit_defaults_for_timestamp システム変数で説明されていますデフォルトでは無効 for 5.6
、5.7
(および5.1
では事実上無効) 8.0
の-enabledです。
上記のリンクからの引用:
(5.7)explicit_defaults_for_timestamp is disabledの場合、サーバーは非標準の動作を有効にし、TIMESTAMP列を次のように処理します。
- NULL属性を使用して明示的に宣言されていないTIMESTAMP列は、NOT NULL属性を使用して自動的に宣言されます。そのような列にNULLの値を割り当てることは許可され、現在のタイムスタンプに列を設定します。
- NULL属性または明示的なDEFAULTまたはON UPDATEで明示的に宣言されていない場合、テーブルの最初のTIMESTAMP列
属性、DEFAULTで自動的に宣言されます
CURRENT_TIMESTAMPおよびON UPDATE CURRENT_TIMESTAMP属性。- 最初の列に続くTIMESTAMP列は、NULL属性または明示的なDEFAULT属性で明示的に宣言されていない場合、DEFAULT '0000-00-00 00:00:00'(「ゼロ」として自動的に宣言されます。タイムスタンプ)。そのような列に明示的な値を指定しない挿入された行の場合、列には '0000-00-00 00:00:00'が割り当てられ、警告は発生しません。
strict SQLモードまたはNO_ZERO_DATE SQLモードが有効かどうかによって、デフォルト値の '0000-00-00 00:00:00'は無効になる場合があります。
5.7
の問題は、NO_ZERO_DATE
モードが有効になっていることです。これは許可しない0000-00-00 00:00:00
のデフォルト値です。ドキュメントで説明されているように、timestamp列の後に(明示的に宣言されていない場合)デフォルト値として追加されます。最初の1つ。
Mysql 8.0
はNO_ZERO_DATE
モードがまだ有効になっていますが、explicit_defaults_for_timestamp
envvarはデフォルトで有効になっています documentation に従って、デフォルト値としてnullが追加されます以下(テーブルの作成でエラーが発生しない):
(8.0)explicit_defaults_for_timestamp is enabledの場合、サーバーは非標準の動作を無効にし、TIMESTAMP列を次のように処理します。
[..]
- NOT NULL属性を使用して明示的に宣言されていないTIMESTAMP列は、NULL属性を使用して自動的に宣言され、NULL値を許可します。そのような列にNULLの値を割り当てると、現在のタイムスタンプではなくNULLに設定されます。
[..]
- テーブルの最初のTIMESTAMP列は、最初の列に続くTIMESTAMP列とは異なる方法で処理されません。
この動作は MySQLの課題追跡 でも説明されていますが、「バグではない」とマークされています。
@Akinaがコメントで述べたように、デフォルト値に依存しないでください。常にフィールドの完全な仕様を記述します。