MySQL 您现在的位置是:首页 > 开发笔记 > MySQL

MySQL的两种严格模式有什么区别

来源:惠达浪原创 发布时间:2019-05-05 最后更新:2019-05-11 2185已围观

摘要在安装某商场软件时,提及到MySQL中的sql-mode设置,特意上网查了一下关于STRICT_TRANS_TABLES和STRICT_ALL_TABLES的区别,记录在此备用。

STRICT_TRANS_TABLES 和 STRICT_ALL_TABLES的区别

在测试一款商城时,发现在安装过程中需要禁掉 STRICT_TRANS_TABLES 模式,而我使用的是 MySQL 5.7,因此好奇为什么要禁掉,便上网查了一下,翻到了这个区别的相关资料,因此记下我自己的理解。

准备两个测试表,分别是 test_innodb 和 test_myisam,每个表只有两个字段,分类是 id 和 val,其中 val 字段类型为 int 类型。

1、STRICT_TRANS_TABLES模式(只对支持事务的表启动严格模式)

InnoDB引擎

因为InnoDB支持事务,因此在插入SQL语句失败的情况下,会报错,并回滚全部数据。


示例1:数据类型不符

insert into test_innodb (val) values (12), ('string')

报错:

TIM截图20190505105757.png


示例2:数据超出范围

insert into test_innodb (val) values (12), (2147483648)

报错:

TIM截图20190505111935.png


结果:

TIM截图20190505112535.png

数据表为空,因为出错后回滚,所以没有数据。

MyISAM引擎

由于MyISAM引擎不支持事务,因此分两种情况。


1、第一条数据出错。

无论多少条数据,只要第一条出错,系统会报错,同时插入数据行为中止,宏观上看就是一条记录也没有。

insert into test_myisam (val) values ('string'), (15)

报错:

TIM截图20190505111935.png

结果就是数据表为空:

TIM截图20190505112535.png


2、第一条数据正确,后边的数据出错。

只要第一条数据正确,无论后边是什么样的数据都不会报错!错误的数据系统会自动处理,将其转换成最接近该数据类型的值并插入。如果实在不能隐式转换,则插入该字段的默认值。

此时我好象明白了为什么从MySQL 5.7开始,字段为什么老是提示需要默认值的原因了,是不是为了防这手的?当然这也是我猜的,没证实。

insert into test_myisam (val) values (13), ('string'), (2147483648), (-2147483649)

没有报错,查看结果:

TIM截图20190505113918.png

从数据中可以看出,第 1 条为正常数据,而第 2 条记录是将字符串转换成整数,因此为 0,第 3 条和第 4 条记录是因为数据超出整形范围, 因此转换成最接近的数值。

2、STRICT_ALL_TABLES模式(对所有的表都启用严格模式)

InnoDB引擎

在该情况下,与 STRICT_TRANS_TABLES 模式完全相同,不再复述。

MyISAM引擎

如果在插入记录的过程中发现数据错误,则报错,中止插入数据,但在报错之前已经插入的数据正常存在。其实这也很容易理解,毕竟MyISAM引擎不支持事务,所以发现了错误也没有办法回滚嘛。

insert into test_myisam (val) values (13), ('string'), (2147483648), (-2147483649)

报错:

TIM截图20190505105757.png

结果是只有第 1 条数据插入成功:

TIM截图20190505134123.png

总结

所以为了便于记忆,总结出简单的结果如下:

  • 对于 InnoDB 引擎来说,因为支持事务,所以无论哪种严格模式都是出错就回滚

  • 对于 MyISAM 引擎来说,由于不支持事务,不能进行数据回滚,因此 STRICT_TRANS_TABLES 模式下会对数据隐式转换STRICT_ALL_TABLES 模式下出错后的数据不插入

很赞哦! (534)


评论

猜你喜欢

站点信息

  • 开发框架ThinkCMF 8.0.1
  • PHP版本:8.3.15
  • 操作系统:Linux
  • 运行环境:nginx/1.24.0
  • 数据库: MySQL 8.0.24