分享好友 系统运维首页 频道列表

MySQL 5.7之关于SQL_MODE的设置

服务器其它  2023-02-07 19:520

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

查看更多关于【服务器其它】的文章

展开全文
相关推荐
反对 0
举报 0
评论 0
图文资讯
热门推荐
优选好物
更多热点专题
更多推荐文章
mysql_pconnect的水挺深,apache下的数据库长连接
  php的mysql持久化连接,美好的目标,却拥有糟糕的口碑,往往令人敬而远之。这到底是为啥么。近距离观察后发现,这家伙也不容易啊,要看apache的脸色,还得听mysql指挥。  对于做为apache模块运行的php来说,要实现mysql持久化连接,首先得取决于apache这个

0评论2023-02-10314

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:端

0评论2023-02-10743

PHP从零开始:Apache+PHP+MySQL安装配置
初学一个东西,最怕的恐怕就是环境配置了。我就经常碰到这样的事而浪费很多时间。  今天在网上搜索到一个图文并茂的Apache+PHP+MySQL教程,按着一步一步安装和配置下来,很快就搞定了!这里贴一下教程的地址,希望其他初学者也可以很快搞定~http://tech.163

0评论2023-02-10575

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

0评论2023-02-10830

windows支持apache、mysql、php集成环境推荐wampserver3.2 64位版本
对英文不感冒的同学很容易下载到更新包,而且官方的下载速度很慢,此文件为官方原版下载,现在分享给大家。链接:https://pan.baidu.com/s/1LYyJi6FddvkQQNrLp4L6Ww 提取码:edsaMD5: 4C32136656EB25E2951E1539D264339ESHA1: 15EAC178B27EE5298883DC3BA351B81

0评论2023-02-10547

如何搭建lamp(CentOS7+Apache+MySQL+PHP)环境
如何搭建lamp(CentOS7+Apache+MySQL+PHP)环境在网上搜资料,自己在本地虚拟机上尝试搭建,弄了整整一天一夜,终于弄好了.网上的资料,虽然很多,但大多都是重复的,拿去试了之后,又很多都不能得到正确的结果.最终找到了适合我的linux环境的搭建方式;在这里贴出来:这

0评论2023-02-10797

CentOS 6下搭建Apache+MySQL+PHP+SSL
网上的一些文章都已经比较老了,现在版本高了之后,其实配置是很省力的(不考虑什么负载的话)分享全过程,出了文中提到的安装epel rpmfushion 源指令不同外,其他的过程也适用与Centos 51.安装CentOS 6 ,可以选择最小安装,也可以安装桌面2.升级系统yum upda

0评论2023-02-10744

lnamp完整版[linux+apache2.4+php5.6.6+mysql5.6]
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

0评论2023-02-10810

Mac上安装PHP、Apache、MySQL
Mac自带php5.6版本,要升级到php7.3 步骤如下1,brew 安装php ,如果没有安装,访问https://brew.sh/index_zh-cn安装在终端输入以下内容,不用指定安装php版本,会自动升级到最新版本,同时brew会自动updatebrew install php 2,查看php版本php -vp.p1 { mar

0评论2023-02-10338

vm虚拟机上安装apache+php+ftp+mysql
我在vm虚拟机上想安装 winxp和linux,然后在linux机上装apache+php+ftp+mysql,以下为我的按装过程:   1:连通虚拟机:两个虚拟机都选Host-Onl,查看主机VirtualBox Host-Only Network ip地址为192.168.56.1,那我让linux,windowsxp都让为该网址192.168.5

0评论2023-02-10729

window XP下 php5.5+mysql+apache2+phpmyadmin安装
        学了将近大半年的php了,还没有装过独立的php环境,一直用的集成的。记得刚学时,一头雾水,不知改怎么搭配环境,就觉得特别复杂,各种看不懂,今天还是自己在XP环境下搭配了一个。        首先,下载php5.5、mysql、apache2、phpmyadmin安装

0评论2023-02-10472

Windows7环境下Apache连接MySQL提示“连接已重置”的解决办法
win7下手动搭建wamp环境,碰到的几个坑总结下,1.能正常访问php和html类型文件,但是访问项目文件时老是连接被重置,后来总结是数据库的问题,就写测试用例测试php能否成功调用数据库, 1 ?php 2echo "mysql"; 34$mysql_conf = array( 5 'host'= '127.0.0.1',

0评论2023-02-10619

搭建linux+nginx+mysql+php环境
说明:操作系统:CentOS 5.6 32位准备篇:一、配置好IP、DNS 、网关,确保使用远程连接工具能够连接服务器二、配置防火墙,开启80端口、3306端口vi /etc/sysconfig/iptables-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT #允许80端口通

0评论2023-02-10710

WINXP下安装IIS+PHP5+MySQL5 +Apache
作者: CNETNews.com.cn 2008-08-19 14:06:02 关键词: Apache 服务器 PHP5 IIS WinXP   1.从官方网站下载安装程序。  http://www.php.net/下载Win下的Zip安装包,因为自带安装程序的文件不全。  http://www.mysql.com/ 下载Win下的最新版本即可。  h

0评论2023-02-10848

更多推荐