mysql 8.0默认启用更严格的sql_mode(如strict_all_tables、only_full_group_by),并移除no_auto_create_user等选项,导致insert/null处理、group by查询及grant建户行为与5.7不兼容,升级需逐条适配sql。

直接改 my.cnf 或 my.ini 是唯一能永久禁用严格模式的 DDL 配置方式——但注意,这不是 DDL,而是服务级配置;MySQL 本身没有“DDL 禁用严格模式”这回事。
为什么不能用 CREATE/ALTER DATABASE 或 TABLE 关闭严格模式?
严格模式由 sql_mode 全局变量控制,它不属于数据库或表的元数据,不随 DDL 持久化。你执行 CREATE DATABASE 或 ALTER TABLE 时传任何参数,都无法改变 sql_mode 值。试图在建表语句里加 STRICT=OFF 这类写法会报错或被忽略。
真正有效的配置位置和写法
必须编辑 MySQL 启动配置文件,且只在 [mysqld] 段生效:
- Linux 常见路径:
/etc/my.cnf或/etc/mysql/my.cnf - Windows 常见路径:
C:\ProgramData\MySQL\MySQL Server X.X\my.ini - 确认文件中存在
[mysqld]段,再在其下添加或修改sql_mode行
推荐写法(彻底关闭):sql_mode = ""
或保留部分安全选项(如生产环境需保留 NO_AUTO_CREATE_USER):sql_mode = "NO_ENGINE_SUBSTITUTION"
⚠️ 错误写法示例:
— sql-mode = ""(带连字符,MySQL 8.0+ 不识别)
— 写在 [client] 或 [mysql] 段下(无效)
— 用单引号包裹值:sql_mode = 'NO_ENGINE_SUBSTITUTION'(部分旧版本解析失败)
改完不重启,配置不会生效
MySQL 启动时才读取 my.cnf 中的 sql_mode。仅执行 SET GLOBAL sql_mode = '' 只影响当前运行实例,下次重启就恢复原值。
- Linux:运行
sudo systemctl restart mysql或sudo service mysql restart - Windows:用服务管理器重启 “MySQLXX” 服务,或命令行执行
net stop MySQLXX && net start MySQLXX - 验证是否生效:
SELECT @@GLOBAL.sql_mode;返回空字符串或不含STRICT_TRANS_TABLES即成功
容易被忽略的兼容性陷阱
MySQL 5.7 和 8.0 对 sql_mode 默认值差异极大,同一行配置在不同版本行为可能不同:
- MySQL 5.7 默认含
STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION - MySQL 8.0.19+ 默认新增
STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION - 若你从 5.7 升级到 8.0,仅注释掉旧
sql_mode行,新版本仍会加载默认严格模式
最稳妥做法:明确写出你要的完整值,而不是依赖“清空”或“注释”,尤其跨版本迁移时。











