首页 > 数据库 >[MYSQL] MYSQL 8解决 Invalid default value for `created_at`(timestamp)

[MYSQL] MYSQL 8解决 Invalid default value for `created_at`(timestamp)

时间:2024-02-26 14:24:10浏览次数:30  
标签:00 created default timestamp explicit DEFAULT defaults MYSQL 默认值

1 问题描述

  • 问题背景

执行 从 MYSQL 5.7 导出,并在 MYSQL 8.0.33 的数据库中执行 DDL 建表语句时,报Invalid default value for 'create_at'

...
  `create_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间/created time',
...

2 原因分析

  • 表面原因:导出的DDL版本不是 MYSQL8 , timestamp类型的字段DDL中存在 DEFAULT '0000-00-00 00:00:00'

2.1 根本原因1:explicit_defaults_for_timestamp

  • explicit_defaults_for_timestamp 系统变量决定MySQL服务端对timestamp列中的默认值和NULL值的不同处理方法。
  • 此变量自MySQL 5.6.6 版本引入,分为全局级别和会话级别,可动态更新,默认值为OFF。
  • 在 MYSQL 8.0 之中默认值改为了on
  • explicit_defaults_for_timestamp=OFF,表示使用默认的timestamp默认格式
  • timestamp类型的默认格式是什么样的呢?
1.和其它字段类型不一样,这个字段默认为not null.而且不允许设置default null.
2.第一列timestamp字段,如果不强制指定默认值或on update属性的话,就会默认设为DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP。
3.非第一列timestamp字段,如果不强制指定默认值,DEFAULT ‘0000-00-00 00:00:00’
4.往该列中插入null值,会自动转化为默认值;
  • explicit_defaults_for_timestamp=ON,则关闭timestamp default的特性:
1. 如果没有被显示指定not null,则默认为null; 
2. 默认值也会是null而非CURRENT_TIMESTAMP; 
3. 如果指定了not null属性,inset式不指定该字段的值,且 strict sql_mode(SQL_MODE=STRICT_TRANS_TABLES) 下,会报错。非strict sql_mode下允许插入’0000-00-00 00:00:00’;
  • 解决思路:

执行以下sql语句,重启mysql服务

SHOW GLOBAL VARIABLES LIKE "explicit_defaults_for_timestamp";
SET persist explicit_defaults_for_timestamp=OFF;

-- mysql8.0 新增了持久化修改全局变量,
-- 使用 set persist 和修改配置文件的效果一致,重启之后无需再改一遍了

2.2 根本原因2:SQL_MODE = STRICT_TRANS_TABLES

  • explicit_defaults_for_timestamp=ON,则关闭timestamp default的特性:
如果指定了not null属性,inset式不指定该字段的值,且 strict sql_mode(SQL_MODE=STRICT_TRANS_TABLES) 下,会报错。非strict sql_mode下允许插入’0000-00-00 00:00:00’

3 解决方法

  • 方法1:换用datetime类型

  • 方法2:保持严格约束表的SQL模式,但修改timestamp字段的默认值的策略

修改timestamp字段的DDL定义(不修改timestamp的类型)

...
  -- `create_at` timestamp DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间/created time',
  `create_at` timestamp NULL DEFAULT current_timestamp COMMENT '创建时间/created time', -- current_timestamp  也可换成 NULL
  `create_by` varchar(15) NOT NULL DEFAULT '-1' COMMENT '创建人/creater. default: -1(super administrator)',
  -- `update_at` timestamp DEFAULT '0000-00-00 00:00:00' COMMENT '更新时间/modified time',
  `update_at` timestamp DEFAULT current_timestamp ON UPDATE current_timestamp COMMENT '更新时间/modified time',
  `update_by` varchar(15) NOT NULL DEFAULT '-1' COMMENT '更新人/updater. default: -1(super administrator)',
...
  • 方法2:关闭explicit_defaults_for_timestamp ,取消严格约束表的SQL模式 (未亲测)
  • Step1 设置explicit_defaults_for_timestamp = OFF
SHOW GLOBAL VARIABLES LIKE "explicit_defaults_for_timestamp";
SET persist explicit_defaults_for_timestamp=OFF;

-- mysql 8.0 新增了持久化修改全局变量,
-- 使用 set persist 和修改配置文件的效果一致,重启之后无需再改一遍了
  • Step2 改为非严格约束表的SQL模式(STRICT_TRANS_TABLES)
  • step2.1 在mysql的配置文件my.ini[mysqld]下面添加如下列;
  • step2.2 保存后重启
SHOW GLOBAL VARIABLES LIKE "sql_mode";

-- SET persist sql_mode="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
SET persist sql_mode="ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"

X 参考文献

标签:00,created,default,timestamp,explicit,DEFAULT,defaults,MYSQL,默认值
From: https://www.cnblogs.com/johnnyzen/p/18034226

相关文章

  • mysql为啥不用红黑树
    Mysql没有使用红黑树的原因主要是因为红黑树的层级较多,可能会导致大量的磁盘IO操作。红黑树是一种自平衡的二叉查找树,它的特点是根节点为黑色,叶子节点为黑色的空节点,红色节点下的子节点一定为黑色节点。从根节点到叶子节点所有的路径上存在相同数目的黑色节点。红黑树的平衡性保......
  • MySQL——去重复
    MySQL——去重复把查询结果去除重复记录。注意:原表数据不会被修改,只是查询结果去重。使用的关键字为:distinct。语法结构:selectdistinct字段名from表名;distinct不能以这种形式出现:select字段名,distinct字段名from表名;会报错。distinct只能出现在所有字段的最前方......
  • MySQL备份恢复数据--binary-mode is enabled and mysql is run in non-interactive...
    使用mysqldump;MySQL自带的逻辑备份工具。mysqldump[选项]数据库名[表名]>脚本名mysqldump[选项]--数据库名[选项表名]>脚本名mysqldump[选项]--all-databases[选项]>脚本名备份mysqldump-hlocalhost-uwordpress-pwordpress_20200104>c......
  • mysql access denied for root ... mysqld –skip-grant-tables 命令失效 ... Failed
    <!--密码突然登录不上MySQL了,久了也不晓得是不是密码不正确...只能改密码...一年难得碰一次,感觉每次总有莫名其妙的问题--><!--修改方案只找到一个,就是无密码验证开启mysql服务,然后登录,设置新密码--><!--mysql版本不同有些命令无效,大概分高低两版本--><!--低版命令我......
  • 关于Windows上设置MySQL为外部可访问
    改表法。可能是你的帐号不允许从远程登陆,只能在localhost。这个时候只要在localhost的那台电脑,登入mysql后,更改"mysql"数据库里的"user"表里的"host"项,从"localhost"改称"%"1.mysql-uroot-pdtsdtsmysql>usemysql;mysql>updateusersethost='%&#......
  • win10搭建mysql5.7环境
    下载mysql5.7下载官网地址https://downloads.mysql.com/archives/community/解压到指定目录我解压到D:\ProgramFiles\mysql-5.7.44创建配置文件my.ini在上述目录中创建my.ini文件,并添加如下配置项#Foradviceonhowtochangesettingspleasesee#http://dev.m......
  • mysqldump
     dockerrun-d--namebaize-rancher--restart=always-p28080:8080rancher/server:v1.6.30\--db-host192.168.50.105\--db-port3306\--db-usercattle\--db-pass******\--db-namecattledockerlogs-fbaize-rancher--tail100#导出单个数据......
  • 加入mysql数据库实现完整的登录注册功能
    功能简介:用户有用户名(user),手机号(mobile),邮箱(email),密码(password).user为主键,mobile唯一保证一个手机号只能注册一个用户,邮箱不唯一并且可为空.故这里用户可以使用user和mobile登录,mobile还可以用找回密码,email仅用于找回密码在注册页面,输入手机号和密码注册用户......
  • Linux 安装 MySQL
    转自:https://blog.csdn.net/bugu_hhh/article/details/130625482使用阿里云CentOS7系统,安装过程中,会报libaio,查看与libaio相关的软件1yumlistlibaio安装1yuminstall-ylibaio*可以查看已安装的MySQL的版本1mysql-V 使用开启MySQL服务命令1syste......
  • Ubuntu22.04安装mysql8数据库
    1、去官网下载APT存储库文件2、到/usr/local目录下创建mysql目录并且用rz命令上传下载的文件若没有安装lrzsz自行安装。3、解压下载的文件)直接选择OK4、更新包信息5、安装设置初始密码选第二个选项6、登录数据库......