在 MySQL 中,SQL 模式(SQL Mode)用于定义服务器支持的 SQL 语法以及数据校验规则。合理设置 SQL 模式有助于提升数据的严谨性和程序的兼容性。
一、查看当前 SQL 模式
可以通过以下命令查看当前会话或全局的 SQL 模式:
SELECT @@sql_mode; -- 或查看全局模式 SELECT @@global.sql_mode;
执行后会返回一个由多个模式名称组成的字符串,例如:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
二、常见 SQL 模式说明
STRICT_TRANS_TABLES:启用严格模式,对于事务表,插入非法或缺失值时会报错而不是警告。 ONLY_FULL_GROUP_BY:要求 SELECT 列表中的所有字段都必须出现在 GROUP BY 子句中。 NO_ZERO_DATE:禁止使用 '0000-00-00' 这类无效日期。 NO_ZERO_IN_DATE:禁止日期中的月或日为 0,如 '2024-00-01'。 ERROR_FOR_DIVISION_BY_ZERO:除以零操作将产生错误而非 NULL。 NO_AUTO_CREATE_USER:禁止 GRANT 语句自动创建用户(已从 MySQL 8.0 起废弃)。 NO_ENGINE_SUBSTITUTION:如果指定的存储引擎不可用,抛出错误而不是替换为默认引擎。三、临时设置 SQL 模式(重启失效)
可以动态修改当前会话或全局的 SQL 模式:
-- 设置当前会话的 SQL 模式 SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_DATE'; -- 设置全局 SQL 模式(影响新连接) SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_DATE';
注意:通过 SET GLOBAL 设置后,已存在的会话不会受影响,仅对新建立的连接生效。
四、永久配置 SQL 模式
要使设置永久生效,需修改 MySQL 配置文件(my.cnf 或 my.ini):
找到配置文件位置,通常位于:
Linux:/etc/my.cnf或
/etc/mysql/my.cnfWindows:
C:\ProgramData\MySQL\MySQL Server x.x\my.ini
在 [mysqld] 段落下添加或修改 sql-mode:
[mysqld] sql-mode = "STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
- 保存文件并重启 MySQL 服务:
# Linux 示例 sudo systemctl restart mysql # Windows net stop mysql net start mysql
五、推荐配置建议
开发环境:可适当宽松,便于调试,如:''或
ALLOW_INVALID_DATES生产环境:建议启用严格模式,如:
sql-mode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
MySQL 8.0 默认模式为:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
基本上就这些。设置 SQL 模式不复杂,但容易忽略其对应用行为的影响,尤其是迁移数据库或升级版本时,应检查模式一致性。
