sql_mod的合理设置

xiaolv
8
2025-01-03

1. 宽松模式vs严格模式

宽松模式:

如果设置的是宽松模式,那么我们在插入数据的时候,即便是给了一个错误的数据,也可能会被接受,并且不报错。

举例:我在创建一个表时,该表中有一个字段为name,给name设置的字段类型时 char(10) ,如果我在插入数据的时候,其中name这个字段对应的有一条数据的长度超过了10 ,例如'1234567890abc',超过了设定的字段长度10,那么不会报错,并且取前10个字符存上,也就是说你这个数据被存为了'1234567890',而'abc'就没有了。但是,我们给的这条数据是错误的,因为超过了字段长度,但是并没有报错,并且mysql自行处理并接受了,这就是宽松模式的效果。

应用场景:通过设置sql mode为宽松模式,来保证大多数sql符合标准的sql语法,这样应用在不同数据 库之间进行 迁移 时,则不需要对业务sql进行较大的修改。

严格模式:

出现上面宽松模式的错误,应该报错才对,所以MySQL5.7版本就将sql_mode默认值改为了严格模式。所以在 生产等环境 中,我们必须采用的是严格模式,进而开发、测试环境的数据库也必须要设置,这样在开发测试阶段就可以发现问题。并且我们即便是用的MySQL5.6,也应该自行将其改为严格模式。

开发经验 :MySQL等数据库总想把关于数据的所有操作都自己包揽下来,包括数据的校验,其实开发中,我们应该在自己开发的项目程序级别将这些校验给做了,虽然写项目的时候麻烦了一些步骤,但是这样做之后,我们在进行数据库迁移或者在项目的迁移时,就会方便很多。 改为严格模式后可能会存在的问题:

改为严格模式后可能会存在的问题:

若设置模式中包含了 NO_ZERO_DATE ,那么MySQL数据库不允许插入零日期,插入零日期会抛出错误而不是警告。例如,表中含字段TIMESTAMP列(如果未声明为NULL或显示DEFAULT子句)将自动分配 DEFAULT '0000-00-00 00:00:00'(零时间戳),这显然是不满足sql_mode中的NO_ZERO_DATE而报错。

2. 宽松模式示例

宽松模式举例1:

select * from employees group by department_id limit 10;
​
set sql_mode = '';
​
select * from employees group by department_id limit 10;

宽松模式举例2:

CREATE TABLE t1(
    id INT PRIMARY KEY,
    l_name VARCHAR(20),
    age   INT
);
​
set sql_mode = '';
​
insert into t1(l_name,age) values('aaa','aaa');
​
select * from t1;

通过上面两个截图可以看出,当我们使用宽松模式时,插入数据时,错误的类型也能插入进去,但这在实际应用场景中是不允许的。

所以,一般我们都不会去使用宽松模式。

3. 模式查看和设置

查看当前的sql_mode

select @@session.sql_mode;
​
select @@global.sql_mode;
​
# 或者
​
show variables like 'sql_mode';

临时设置方式:

设置当前窗口中设置sql_mode

SET GLOBAL sql_mode = 'modes...'; #全局
​
SET SESSION sql_mode = 'modes...'; #当前会话

示例:

#改为严格模式。此方法只在当前会话中生效,关闭当前会话就不生效了。
SET SESSION sql_mode='STRICT_TRANS_TABLES';
​
#改为严格模式。此方法在当前服务中生效,重启MySQL服务后失效。
SET GLOBAL sql_mode='STRICT_TRANS_TABLES';

永久设置方式:

在/etc/my.cnf中配置sql_mode

在my.cnf文件(windows系统是my.ini文件),新增:

[mysqld]
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

然后重启MySQL。 当然生产环境上是禁止重启MySQL服务的,所以采用 临时设置方式 + 永久设置方式 来解决线上的问题, 那么即便是有一天真的重启了MySQL服务,也会永久生效了。

动物装饰