web-dev-qa-db-ja.com

2つ以上のタイムスタンプフィールドがcreateステートメントに存在する場合にのみ、mysqlが「フィールドの無効なデフォルト値」をスローするのはなぜですか?

Mysql 5.7.28では、次のようなテーブルを作成します。

create table t1 (
id int not null,
d1 timestamp) 
engine=innodb;

これは正常に機能しますであり、d1 なので non-nulldefault value current_timetampon update current_timestamp

しかし、以下のように2つのタイムスタンプフィールドを持つ同じテーブルを作成しようとすると、

create table t1 (
id int not null,
d1 timestamp,
d2 timestamp) 
engine=innodb;

エラーが発生します:

SQLエラー(1067): 'd2'のデフォルト値が無効です

エラーが発生する理由2番目のタイムスタンプを追加した場合のみフィールド?
これはmysqlのバグですか、それとも予期される動作ですか?

3
Marinos An

この動作は explicit_defaults_for_timestamp システム変数で説明されていますデフォルトでは無効 for 5.65.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.0NO_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がコメントで述べたように、デフォルト値に依存しないでください。常にフィールドの完全な仕様を記述します。

3
leopal