一、介绍
1、介绍
SQL_MODE
是 MySQL 中用来控制 SQL 语法和数据校验行为的系统变量。它可以设置为一个或多个模式(mode)的组合,用来影响 MySQL 的行为,比如语法解析方式、是否允许某些不规范的数据写入、GROUP BY 检查等。它会影响:
-
插入非法或不完整数据时是否报错
-
GROUP BY
的严格性 -
日期和时间的处理方式
-
是否允许
NULL
自动转换为0
等
简言之,sql_mode 是mysql的核心参数,控制着不合理sql的处理方式(兼容 or 报错)。
修改严格模式仅影响写,不影响读
2、查看当前的 sql_mode
(1)查看全局
SELECT @@GLOBAL.sql_mode; -- 查看全局
(2)查看当前会话
SELECT @@SESSION.sql_mode; -- 查看当前会话
3、 设置 sql_mode
(1)
临时设置(当前会话):
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
(2)永久设置全局(重启数据库后可能失效,建议配置在 my.cnf)
[mysqld]
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
4、默认设置和推荐设置
(1)MySQL 5.7 默认模式(部分)
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
(2)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_mode
选项
常见的 SQL_MODE
选项很多,但以下这些是 实际项目中最常遇到、最有影响力的模式。它们可以分为几类:严格性检查、日期处理、分组行为、语法兼容、函数行为等。
模式名 | 类型 | 说明 |
STRICT_TRANS_TABLES | 严格模式 | 如果列定义为 NOT NULL 或类型不匹配,插入非法值时报错(事务表)。推荐生产开启。 |
STRICT_ALL_TABLES | 严格模式 | 所有表(含非事务表)都执行严格检查,更严格。 |
ONLY_FULL_GROUP_BY | 分组行为 | GROUP BY 时所有非聚合列必须出现在 GROUP BY 中,否则报错。保证语义清晰。 |
NO_ZERO_IN_DATE | 日期检查 | 不允许日期中的月/日为 0,如 2025-00-01 ,会报错。 |
NO_ZERO_DATE | 日期检查 | 不允许 0000-00-00 这样的日期,防止错误数据。 |
ERROR_FOR_DIVISION_BY_ZERO | 严格性 | 遇到除以 0 的情况报错,而不是返回 NULL。 |
NO_ENGINE_SUBSTITUTION | 引擎行为 | 创建表时指定了不存在的存储引擎会报错(否则默认变成 InnoDB)。建议开启。 |
TRADITIONAL | 模式合集 | 组合了多个严格模式,相当于生产推荐配置的集合(推荐)。 |
ANSI_QUOTES | 语法兼容 | 把双引号 "identifier" 当作标识符(列名、表名),而不是字符串(兼容 ANSI SQL)。 |
PIPES_AS_CONCAT | 函数行为 | 将 ` |
IGNORE_SPACE | 函数调用 | 允许函数名后加空格,如 NOW () 也能被识别为函数。 |
NO_BACKSLASH_ESCAPES | 转义字符 | 禁止使用反斜杠 \ 作为转义符。 |
HIGH_NOT_PRECEDENCE | 运算优先级 | 改变 NOT 和 > 、= 等运算符的优先级。 |
1、严格模式
(1)介绍:
如果插入或更新的数据违反了字段约束(如 NOT NULL
、类型不匹配、超范围),严格模式会直接报错,阻止写入。
(2)设置方法:
STRICT_TRANS_TABLES
(推荐);或者使用更严格的STRICT_ALL_TABLES。
如
SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
STRICT_ALL_TABLES,ONLY_FULL_GROUP_BY,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION
2、宽松模式
(1)介绍
当插入/更新数据违反约束时,不会报错,而是自动调整数据或填充默认值,从而允许数据写入。
(2)设置方法
(Non-Strict / Lenient Mode),如
SET sql_mode = ''; -- 清除所有模式(最宽松)
当然也可以保留一些基本的模式,如:
SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION';