MySQL默认sql_mode浅析

 更新时间:2023年03月29日 09:50:05   作者:刘牌  
这篇文章主要为大家介绍了MySQL默认sql_mode浅析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

SQL mode

今天我们来分享一下MySQL的SQL mode , 这也是我们比较容易忽略的一点,我们在一开始安装数据库的时候其实就要先考虑要保留哪些SQL mode,去除哪些,合理的配置能够减少很多不必要的麻烦。

MySQL 5.7默认的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, and NO_ENGINE_SUBSTITUTION

这是MySQL官网的原文描述:“These modes were added to the default SQL mode in MySQL 5.7: The ONLY_FULL_GROUP_BY and STRICT_TRANS_TABLES modes were added in MySQL 5.7.5. The NO_AUTO_CREATE_USER mode was added in MySQL 5.7.7. The ERROR_FOR_DIVISION_BY_ZERO, NO_ZERO_DATE, and NO_ZERO_IN_DATE modes were added in MySQL 5.7.8. For additional discussion regarding these changes to the default SQL mode value, see SQL Mode Changes in MySQL 5.7.”

show sql mode

SELECT @@GLOBAL.sql_mode;

SELECT @@SESSION.sql_mode;

set sql mode

设置为GLOBAL,那么所有的客户端都会受到影响,不过要拥有SUPER权限才能进行设置,也就是root用户,设置SESSION,那么受影响的只是当前的连接会话。

SET GLOBAL sql_mode ='ONLY_FULL_GROUP_BY'

SET SESSION sql_mode ='ONLY_FULL_GROUP_BY'

下面我们就针对默认设置的这几种SQL mode进行详细的讲解,其他的哪些大家可以去官网参考。

docs.oracle.com/cd/E17952_0…

默认的SQL mode

ONLY_FULL_GROUP_BY

设置了这个值,如果使用GROUP BY,在SELECT后面出现的字段,在GROUP BY后面必须出现,不然报错如下

Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'blue.shop.price' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

如下使用的是MySQL默认的sql_mode

ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

那么下面的语句就会报错,因为GROUP BY后面只有一个字段,而SELECT * 是查出所有字段,所以就报错。

SELECT * FROM shop GROUP BY article 

这样写就不会报错

SELECT * FROM shop GROUP BY article , dealer , price

不过我们不可能使用一个GROUP BY,后面还要跟着所有字段,显然不合理,那么就应该将其关闭,只需要将其去掉就行

STRICT_TRANS_TABLES

严格模式控制MySQL如何处理数据更改语句中的无效或缺失值,如INSERT或UPDATE。一个值可能因多种原因无效。例如,它可能具有列的错误数据类型,或者它可能超出了范围。如果要插入的新行不包含定义中没有显式DEFAULT子句的非null列的值,则该值缺失。

比如我们的某个字段设置不能为NULL,而我们插入的数据这个字段为NULL,那么就不能通过,就会报错如下:

1364 - Field 'dealer' doesn't have a default value

那么这个问题要怎么解决呢?我相信这个问题大家经常遇到,一般是我们在插入数据的时候实体的属性没有赋值,所以导致这个问题,所以我们会去检查代码,然后给属性赋值,另外一种做法就是去除STRICT_TRANS_TABLES,这样就不会进行校验,不过是极其不推荐这样做的,因为要我们要保证数据的完整性,所以必须在代码层面做好工作。

NO_ZERO_IN_DATE

NO_ZERO_IN_DATE模式会影响服务器是否允许年部分不为零但月或日部分为0的日期。(该模式影响日期,如“2010-00-01”或“2010-01-00”,但不影响“0000-00-00”。要控制服务器是否允许'0000-00-00',请使用NO_ZERO_DATE模式。)NO_ZERO_IN_DATE的效果还取决于是否启用严格SQL模式,如果没有启用严格SQL模式STRICT_TRANS_TABLES,那么启用了NO_ZERO_IN_DATE也没用。

如下SQL的日期月和日为0,启用了严格模式STRICT_TRANS_TABLES和NO_ZERO_IN_DATE,那么就会报错。

INSERT INTO `blue`.`shop` (`article`, `dealer` ,`price`,`date`) VALUES ('商品5', '5', 5.00, '2022-00-00');

1292 - Incorrect datetime value: '2022-00-00' for column 'date' at row 1

去除严格模式STRICT_TRANS_TABLESNO_ZERO_IN_DATE就不会报错。

NO_ZERO_DATE

上面的NO_ZERO_IN_DATE可以插入'0000-00-00',如果使用了严格模式STRICT_TRANS_TABLES和NO_ZERO_DATE,那么就不可以插入'0000-00-00'。

ERROR_FOR_DIVISION_BY_ZERO

对于INSERT或者UPDATE中,如果被除数为0,那么就会产生错误,数据无法插入,MOD(N,M)也是一样

INSERT INTO `blue`.`shop` (`article`,dealer ,`price`,`date`) VALUES ('商品5', '5', MOD(10,0), '0000-00-00');

对于SELECT,如果被除数为0,那么就会返回NULL,MOD(N,M)也一样。

SELECT price / 0  FROM shop

报错信息: 1365 - Division by 0

NO_AUTO_CREATE_USER

不能使用grant命令创建密码为空的用户。

NO_ENGINE_SUBSTITUTION

如果指定了NO_ENGINE_SUBSTITUTION,我们在创建表或者修改表的时候,如果去指定了不存在或者不支持的存储引擎,那么就会报错,无法创建和修改,如果没有配置NO_ENGINE_SUBSTITUTION,那么就会将我们指定的存储引擎(不支持或者不存在)的存储引擎替换为默认的存储引擎,MySQL5.7后的默认存储引擎为InnoDB,所以就会自动设置为InnoDB。

如下我们创建表,将存储引擎设置为一个不存在的InnoDBTest,因为我们去除了NO_ENGINE_SUBSTITUTION,所以不会报错,并且会替换成默认的InnoDB

创建sql

CREATE TABLE store ( `name` VARCHAR ( 255 ) DEFAULT NULL ) ENGINE = InnoDBTest

查看创建过程

SHOW CREATE TABLE store

结果

CREATE TABLE `store` (
  `name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

MySQL存储引擎

SHOW ENGINES;

关于MySQL的SQL mode,就说到这里,我只列举了MySQL5.7默认的几种并对其进行讲解,有兴趣的话可以去了解其他的选项

以上就是MySQL默认sql_mode浅析的详细内容,更多关于MySQL默认sql_mode的资料请关注脚本之家其它相关文章!

相关文章

  • mysql误删root用户或者忘记root密码解决方法

    mysql误删root用户或者忘记root密码解决方法

    mysql误删root用户或者忘记root密码解决方法,需要的朋友可以参考下。
    2011-05-05
  • MySQL JOIN之完全用法

    MySQL JOIN之完全用法

    最近在做mysql的性能忧化,做到多表连接查询,比较头疼,看了一些join的资料,终于搞定,这里分享出来!
    2009-12-12
  • MySQL数据优化-多层索引

    MySQL数据优化-多层索引

    这篇文章主要介绍了MySQL数据优化 多层索引,文章围绕MySQL数据优化 多层索引的相关资料展开详细的内容,具有一定的参考价值,需要的小伙伴可以参考一下
    2021-12-12
  • MySQL权限控制和用户与角色管理实例分析讲解

    MySQL权限控制和用户与角色管理实例分析讲解

    用户经认证后成功登录数据库,之后服务器将通过系统权限表检测用户发出的每个请求操作,判断用户是否有足够的权限来实施该操作,这就是MySQL的权限控制过程
    2022-12-12
  • MySQL load语句详细介绍

    MySQL load语句详细介绍

    这篇文章主要介绍了MySQL load语句详细介绍,本文讲解了load的基本语法、文件的路径、配置选项、STARTING LINES选项、TERMINATED LINES选项等内容,需要的朋友可以参考下
    2014-12-12
  • centos下安装mysql服务器的方法

    centos下安装mysql服务器的方法

    本篇文章是对在centos下安装mysql服务器的方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • Mysql中tinyint(1)和tinyint(4)的区别详析

    Mysql中tinyint(1)和tinyint(4)的区别详析

    这篇文章主要给大家介绍了关于Mysql中tinyint(1)和tinyint(4)区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-02-02
  • MySQL regexp 命令详解

    MySQL regexp 命令详解

    REGEXP命令用于在查询中进行正则表达式匹配,支持多种符号和语法,如^、$、.、*、+、?、|、[]等,示例展示了如何匹配特定字符、数字、多个选项等,使用BINARY关键字可以区分大小写,本文介绍MySQL regexp 命令,感兴趣的朋友一起看看吧
    2025-03-03
  • mysql如何将sql查询的结果以百分比展示出来

    mysql如何将sql查询的结果以百分比展示出来

    这篇文章主要给大家介绍了关于mysql如何将sql查询的结果以百分比展示出来的相关资料,用到了MySQL字符串处理中的两个函数concat()和left()实现查询结果以百分比显示,需要的朋友可以参考下
    2023-08-08
  • mysql 表空间及索引的查看方法

    mysql 表空间及索引的查看方法

    mysql 表空间及索引的查看方法,需要的朋友可以参考下。
    2011-07-07

最新评论