暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL中timestamp数据类型定义

941
MySQL中的timestamp数据类型,在使用上还是有很多讲究的,之前写的一些历史文章,
MySQL的TIMESTAMP数据类型
小白学习MySQL - TIMESTAMP类型字段非空和默认值属性的影响
技术社区推送的这篇文章《技术分享 | MySQL--测试--timestamp 字段默认值测试》,讲了一些timestamp数据类型定义的相关问题,可以补充到我们的知识库中。

背景

客户反馈表定义中含timestamp字段(SQL语句),定义如下:
    b timestamp NOT NULL
    在MySQL中执⾏后,变成如下:
      b timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
      想知道其原因,这⾥涉及到了两个技术点:

      1. MySQL如何给timestamp字段设置默认值。

      2. 00这种时间格式是否被允许。

      MySQL如何给timestamp字段设置默认值

      涉及参数:explicit_defaults_for_timestamp

      参数解析:

      默认情况,启⽤explicit_defaults_for_timestamp,

      如果启⽤参数,表示禁⽌⾮标准⾏为,此时按如下⽅式处理timestamp列:
      • 若要分配当前时间戳,只能设置列为CURRENT_TIMESTAMP或同义词NOW(),不能通过NULL。
      • 没有使⽤NOT NULL属性显式声明的timestamp列将⾃动使⽤NULL属性声明并允许使⽤NULL值。
      • 对于NOT NULL属性声明的timestamp列不允许使⽤NULL值。
      • 使⽤了NOT NULL属性但未使⽤DEFAULT属性的timestamp会被认为没有默认值。
      • DEFAULT CURRENT_TIMESTAMP或者UPDATE CURRENT_TIMESTAMP属性不会被⾃动声明,只能显式指定。
      • 表中第⼀个timestamp列的处理和其他timestamp列的处理⽅式并⽆不同。

      如果禁⽤参数,表示开启了⾮标准⾏为,此时按如下⽅式处理timestamp列:

      • 没有显式声明NULL属性的timestamp列将⾃动声明NOT NULL属性;并允许插⼊NULL值(8.0.22之前),但会将该列设置设置为当前时间戳。

      • 表中第⼀个timestamp列,如果没有显式声明NULL属性或者显式的DEFAULT属性或者ON UPDATE属性,则⾃动使⽤DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP属性声明该列。
      • 除第⼀个timestamp列以外的其他timestamp列,如果没有显式声明NULL属性或者显式的DEFAULT属性,则会⾃动声明为DEFAULT '0000-00-00 00:00:00'("zero"时间戳)。若sql_mode中包含了NO_ZERO_DATE,则默认值可能⽆效。

      zero时间戳是否被允许:
      • 通过sql_mode中的NO_ZERO_DATE值控制。

      • 如果sql_mode中含NO_ZERO_DATE,则不允许 '0000-00-00 00:00:00'("zero"时间戳) ,否则允许。


      MySQL5.7.24测试:

      测试场景:

      建表语句:

      create database if not exists db_test;
      use db_test;
      drop table if exists tb_a;
      create table tb_a(a timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      ,
      b timestamp NOT NULL
      ) engine=InnoDB;
      show create table tb_a \G

      场景1:

      set session explicit_defaults_for_timestamp=1;
      set session sql_mode='NO_ZERO_DATE';

      测试截图1:

      说明1:

      因为explicit_defaults_for_timestamp值为1,并不会为timestamp字段设置默认值。

      场景2:

      set session explicit_defaults_for_timestamp=1;
      set session sql_mode='';

      测试截图2:

      说明2:
      因为explicit_defaults_for_timestamp值为1,并不会为timestamp字段设置默认值。

      场景3:

      set session explicit_defaults_for_timestamp=0;
      set session sql_mode='NO_ZERO_DATE';

      测试截图3:

      说明3:

      因为explicit_defaults_for_timestamp值为0,且b字段不是第⼀个timestamp字段,没有显示声明NULL属性或DEFAULT属性,所以会赋予默认值 '0000-00-00 00:00:00',⼜因为sql_mode中含NO_ZERO_DATE,不允许zero时间戳,所以报错:

        ERROR 1067 (42000): Invalid default value for 'b'

        场景4:

        set session explicit_defaults_for_timestamp=0;
        set session sql_mode='';

        测试截图4:

        说明4:

        因为explicit_defaults_for_timestamp值为0,且b字段不是第⼀个timestamp字段,没有显示声明NULL属性或DEFAULT属性,所以会赋予默认值 '0000-00-00 00:00:00'。

        说明

        上面测试围绕客户场景设置,还有更多测试场景可供探索。
        不过还是建议:
        explicit_defaults_for_timestamp=1
        sql_mode含NO_ZERO_DATE

        如果您认为这篇文章有些帮助,还请不吝点下文章末尾的"点赞"和"在看",或者直接转发pyq,



        近期更新的文章:
        魔方的征途 - 魔方如何选择?
        MySQL中用户密码存在特殊字符的使用场景
        企业IT运维故障定位方法及工具
        技术高手是如何炼成的?
        中国民航安全运行的最强大脑

        近期的热文:
        "红警"游戏开源代码带给我们的震撼

        文章分类和索引:
        公众号1100篇文章分类和索引

        文章转载自bisal的个人杂货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论