MySQL 5.7之关于SQL_MODE的设置

   2023-02-07 学习力0
核心提示:目录一、sql_mode用来解决下面几类问题二、MySQL5.7中sql_mode参数默认值的说明(如下为MySQL 5.7.27版本)三、sql_mode 设置和修改总结sql_mode是个容易被忽视的变量,在5.5默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入

sql_mode是个容易被忽视的变量,在5.5默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入。

在5.6中强化了该值设置,5.7中更注重了安全规范性,这个值默认为严格模式

一、sql_mode用来解决下面几类问题

通过设置sql mode,可以完成不同严格程度的数据校验,有效保障数据准备性。

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

二、MySQL5.7中sql_mode参数默认值的说明(如下为MySQL 5.7.27版本)

  • ONLY_FULL_GROUP_BY

对于使用 GROUP BY 进行查询的SQL,不允许 SELECT 部分出现 GROUP BY 中未出现的字段,也就是 SELECT 查询的字段必须是 GROUP BY 中出现的或者使用聚合函数的或者是具有唯一属性的。

create table test(name varchar(10),value int);
insert into test values ('a',1),('a',20),('b',23),('c',15),('c',30);
#默认情况是可能会写出无意义或错误的聚合语句:
SET sql_mode='';
select * from test group by name;
select value,sum(value) from test group by name;
# 使用该模式后,写法必须标准
SET sql_mode='ONLY_FULL_GROUP_BY';
select name,sum(value) from test group by name;
-- 错误写法则报错
select value,sum(value) from test group by name;
# 报错终止
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test.test.value' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
  • STRICT_TRANS_TABLES

该选项针对事务性存储引擎生效,对于非事务性存储引擎无效,该选项表示开启strict sql模式。在strict sql模式下,在INSERT或者UPDATE语句中,插入或者更新了某个不符合规定的字段值,则会直接报错中断操作

create table test(value int(1));
SET sql_mode=''; #默认只要第一个值
 
insert into test(value) values('a'),(1); #不报错
insert into test(value) values(2),('a'); #不报错
select * from test;
+------------+
| value      |
+------------+
|          0 |
|          1 |
|          2 |
|          0 |
+------------+
#后面删除表不再说明!
drop table test; 
create table test(value int(1));
 
SET sql_mode='STRICT_TRANS_TABLES'; #每个值都判断
 
insert into test(value) values('a'),(1);
#报错,第一行'a'错误。
ERROR 1366 (HY000): Incorrect integer value: 'a' for column 'value' at row 1
  • NO_ZERO_IN_DATE

MySQL中插入的时间字段值,不允许日期和月份为零

create table test(value date);
SET sql_mode='';
insert into test(value) values('2020-00-00'); #结果为 '2020-00-00'
 
SET sql_mode='NO_ZERO_IN_DATE';
insert into test(value) values('2021-00-00'); #不符合,转为 '0000-00-00'
  • NO_ZERO_DATE

MySQL中插入的时间字段值,不允许插入 ‘0000-00-00’ 日期

create table test(value date);
 
SET sql_mode='';
insert into test(value) values('0000-00-00'); #无警告 warning
 
SET sql_mode='STRICT_TRANS_TABLES';
insert into test(value) values('0000-00-00'); #无警告 warning
 
SET sql_mode='NO_ZERO_DATE';
insert into test(value) values('0000-00-00'); #有警告 warning
 
SET sql_mode='NO_ZERO_DATE,STRICT_TRANS_TABLES'
insert into test(value) values('0000-00-00');
# 报错终止
ERROR 1292 (22007): Incorrect date value: '0000-00-00' for column 'value' at row 1
  • ERROR_FOR_DIVISION_BY_ZERO

INSERT或者UPDATE语句中,如果数据被0除,则出现警告(非strict sql模式下)或者错误(strict sql模式下)。

  • 当该选项关闭时,数字被0除,得到NULL且不会产生警告
  • 当该选项开启且处于非strict sql模式下,数字被0除,得到NULL但是会产生警告
  • 当该选项开启且处于strict sql模式下,数字被0除,产生错误且中断操作
create table test(value int);
 
SET sql_mode='';  
select 10/0;  #无警告 warning
insert into test(value) values(10/0);   #无警告 warning
 
SET sql_mode='STRICT_TRANS_TABLES'; 
select 10/0;   #无警告 warning
insert into test(value) values(10/0);  #无警告 warning
 
SET sql_mode='ERROR_FOR_DIVISION_BY_ZERO'; 
select 10/0;  #有警告 warning
insert into test(value) values(10/0);  #有警告 warning
 
SET sql_mode='ERROR_FOR_DIVISION_BY_ZERO,STRICT_TRANS_TABLES';
select 10/0; #有警告 warning
insert into test(value) values(10/0); 
#报错:ERROR 1365 (22012): Division by 0
  • NO_AUTO_CREATE_USER

禁止GRANT创建密码为空的用户

SET sql_mode='';
grant all on test.* to test01@'localhost';  #不报错(无需要设置密码)
SET sql_mode='NO_AUTO_CREATE_USER';
# 报错
ERROR 1133 (42000): Can't find any matching row in the user table

#正确 写法,需要设置密码
grant all on test.* to test01@'localhost' identified by 'test01...';
  • NO_ENGINE_SUBSTITUTION

在使用CREATE TABLE或者ALTER TABLE语法执行存储引擎的时候,如果设定的存储引擎被禁用或者未编译,会产生错误。

# 查看当前支持的存储引擎
show engines;

set sql_mode='';
create table test(id int) ENGINE="test";
Query OK, 0 rows affected, 2 warnings (0.03 sec)

select table_name,engine from information_schema.tables where table_schema='test' and table_name='test'; # 转为默认存储引擎
+------------+--------+
| table_name | engine |
+------------+--------+
| test       | InnoDB |
+------------+--------+
SET sql_mode='NO_ENGINE_SUBSTITUTION';
create table test(id int) ENGINE=test;
# 报错
ERROR 1286 (42000): Unknown storage engine 'test'

三、sql_mode 设置和修改

方式一: 这是一个可修改全局变量

> show variables like '%sql_mode%';
> set @@sql_mode="NO_ENGINE_SUBSTITUTION"
> set session sql_mode='STRICT_TRANS_TABLES';

方式二: 通过修改配置文件(需要重启生效)

# vim /etc/my.cnf
[mysqld]
......
sql_mode="NO_ENGINE_SUBSTITUTION"
......

总结

SQL_MODE在非严格模式下,会出现很多意料不到的结果。建议线上开启严格模式。但对于线上老的环境,如果一开始就运行在非严格模式下,切忌直接调整,毕竟两者的差异性还是相当巨大。

官方默认的SQL_MODE一直在发生变化,MySQL 5.5, 5.6, 5.7就不尽相同,但总体是趋严的,在对数据库进行升级时,其必须考虑默认的SQL_MODE是否需要调整。

在进行数据库迁移时,可通过调整SQL_MODE来兼容其它数据库的语法。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文地址:https://blog.csdn.net/qq_25854057/article/details/114587257
 
标签: MySQL 5.7 SQL MODE
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • mysql_pconnect的水挺深,apache下的数据库长连
      php的mysql持久化连接,美好的目标,却拥有糟糕的口碑,往往令人敬而远之。这到底是为啥么。近距离观察后发现,这家伙也不容易啊,要看apache的脸色,还得听mysql指挥。  对于做为apache模块运行的php来说,要实现mysql持久化连接,首先得取决于apache这个
    02-10
  • linux下mysql开启远程访问权限及防火墙开放3306端口
    linux下mysql开启远程访问权限及防火墙开放3306
    开启mysql的远程访问权限默认mysql的用户是没有远程访问的权限的,因此当程序跟数据库不在同一台服务器上时,我们需要开启mysql的远程访问权限。主流的有两种方法,改表法和授权法。相对而言,改表法比较容易一点,个人也是比较倾向于使用这种方法,因此,这
    02-10
  • php+apache+mysql
    apache2.4.7+php5.4[http://www.myhack58.com/Article/sort099/sort0100/2012/35578.htm] apachehttpd.conf:DocumentRoot:网站根目录,默认/htdocsDirectoryIndex:默认显示的文件名.默认index.html,可以有多个值.如index.html index.jsp.用空格分开Listen:端
    02-10
  • Windows下搭建apache+mysql+php开发环境
    Windows下搭建apache+mysql+php开发环境
      最近因在windows环境下搭建php开发环境遇到了各式各样的问题,故在此加以归纳总结。目的有二,一是为了避免以后再次遇到类似的问题,二是为需要的同学提供启示和借鉴。  一:下载需要的软件apache   httpd-2.2.22-win32-x86-no_ssl.msimysql     mys
    02-10
  • PHP从零开始:Apache+PHP+MySQL安装配置
    初学一个东西,最怕的恐怕就是环境配置了。我就经常碰到这样的事而浪费很多时间。  今天在网上搜索到一个图文并茂的Apache+PHP+MySQL教程,按着一步一步安装和配置下来,很快就搞定了!这里贴一下教程的地址,希望其他初学者也可以很快搞定~http://tech.163
    02-10
  • Linux测试环境搭建apache+mysql+php
    LinuxRed Hat Enterprise Linux Server release 5.4 (Tikanga)Kernel \r on an \mApache +Mysql+php搭建准备:Apache postgresql-libs-8.1.11-1.el5_1.1.i386.rpmapr-1.2.7-11.el5_3.1.i386.rpmapr-util-1.2.7-7.el5_3.2.i386.rpmhttpd-2.2.3-31.el5.i386.rpm
    02-10
  • windows支持apache、mysql、php集成环境推荐wam
    对英文不感冒的同学很容易下载到更新包,而且官方的下载速度很慢,此文件为官方原版下载,现在分享给大家。链接:https://pan.baidu.com/s/1LYyJi6FddvkQQNrLp4L6Ww 提取码:edsaMD5: 4C32136656EB25E2951E1539D264339ESHA1: 15EAC178B27EE5298883DC3BA351B81
    02-10
  • 如何搭建lamp(CentOS7+Apache+MySQL+PHP)环境
    如何搭建lamp(CentOS7+Apache+MySQL+PHP)环境在网上搜资料,自己在本地虚拟机上尝试搭建,弄了整整一天一夜,终于弄好了.网上的资料,虽然很多,但大多都是重复的,拿去试了之后,又很多都不能得到正确的结果.最终找到了适合我的linux环境的搭建方式;在这里贴出来:这
    02-10
  • CentOS 6下搭建Apache+MySQL+PHP+SSL
    网上的一些文章都已经比较老了,现在版本高了之后,其实配置是很省力的(不考虑什么负载的话)分享全过程,出了文中提到的安装epel rpmfushion 源指令不同外,其他的过程也适用与Centos 51.安装CentOS 6 ,可以选择最小安装,也可以安装桌面2.升级系统yum upda
    02-10
  • lnamp完整版[linux+apache2.4+php5.6.6+mysql5.
    Lnamp环境安装实录将采用的开源软件:Apache [WEB动态脚本服务器,做nginx的反向代理8080端口]Tengine [WEB静态文件服务器80端口]MySQL PHP 1.Apache安装A.apr安装wget -c http://mirror.bjtu.edu.cn/apache/apr/apr-1.5.1.tar.gztar -zxvf apr-1..5.tar.gzcd
    02-10
点击排行