GreatSQL社区

搜索

KAiTO

0基础学MySQL数据库—从小白到大牛(20)大小写规范、sql_mode的合理设置 ...

KAiTO 已有 414 次阅读2022-10-18 09:17 |个人分类:零基础学习数据库|系统分类:其他


一、SQL大小写规范

Windows和Linux平台区别

在 SQL 中,关键字和函数名是不用区分字母大小写的,比如 SELECT、WHERE、ORDER、GROUP BY 等关键字,以及 ABS、MOD、ROUND、MAX 等函数名。

不过在 SQL 中,你还是要确定大小写的规范,因为在 Linux 和 Windows 环境下,你可能会遇到不同的大小写问题。 windows系统默认大小写不敏感 ,但是 linux系统是大小写敏感的

关键字和函数名是大小写不敏感的

通过如下命令查看:

Windows系统下mysql> SHOW VARIABLES LIKE '%lower_case_table_names%';+------------------------+-------+| Variable_name          | Value |+------------------------+-------+| lower_case_table_names | 1     |+------------------------+-------+1 row in set (0.36 sec)Linux系统下mysql> SHOW VARIABLES LIKE '%lower_case_table_names%';+------------------------+-------+| Variable_name          | Value |+------------------------+-------+| lower_case_table_names | 0     |+------------------------+-------+1 row in set (0.36 sec)

ower_case_table_names参数值的设置:

  • 默认为0,大小写敏感。
  • 设置1,大小写不敏感。创建的表,数据库都是以小写形式存放在磁盘上,对于sql语句都是转换为小写对表和数据库进行查找。
  • 设置2,创建的表和数据库依据语句上格式存放,凡是查找都是转换为小写进行。

两个平台上SQL大小写的区别具体来说:

MySQL在Linux下数据库名、表名、列名、别名大小写规则是这样的:

1、数据库名、表名、表的别名、变量名是严格区分大小写的`

2、关键字、函数名称在 SQL 中不区分大小写;

3、列名(或字段名)与列的别名(或字段别名)在所有的情况下均是忽略大小写的;

MySQL在Windows的环境下全部不区分大小写

Linux下大小写规则设置

当想设置为大小写不敏感时,要在my.cnf这个配置文件 [mysqld] 中加入lower_case_table_names=1 ,然后重启服务器。

==但是要在重启数据库实例之前就需要将原来的数据库和表转换为小写,否则将找不到数据库名==

==此参数适用于MySQL5.7==在MySQL 8下禁止在重新启动 MySQL 服务时将lower_case_table_names 设置成不同于初始化 MySQL 服务时设置的lower_case_table_names 值。如果非要将MySQL8设置为大小写不敏感,具体步骤为:

1、停止MySQL服务 2、删除数据目录,即删除 /var/lib/mysql 目录 3、在MySQL配置文件( /etc/my.cnf )中添加 lower_case_table_names=1 4、启动MySQL服务

SQL编写建议

如果你的变量名命名规范没有统一,就可能产生错误。这里有一个有关命名规范的建议:

  • 关键字和函数名称全部大写;
  • 数据库名、表名、表别名、字段名、字段别名等全部小写;
  • SQL 语句必须以分号结尾。 数据库名、表名和字段名在 Linux MySQL 环境下是区分大小写的,因此建议你统一这些字段的命名规则,比如全部采用小写的方式。

虽然关键字和函数名称在 SQL 中不区分大小写,也就是如果小写的话同样可以执行。但是同时将关键词和函数名称全部大写,以便于区分数据库名、表名、字段名。

二、sql_mode的合理设置

介绍

sqLmode会影响MySQL支持的SQL语法以及它执行的数据验证检查。通过设置sqLmode,可以完成不同严格程度的数据校验,有效地保障数据准确性。

MySQL服务器可以在不同的SQL模式下运行,并且可以针对不同的客户端以不同的方式应用这些模式,具体取决于sql_mode系统变量的值。

MySQL5.6和MySQL5.7默认的sqLmode模式参数是不一样的:

5.6的mode默认值为空(即:NO_ENGINE_SUBSTITUTION),其实表示的是一个空值,相当于没有什么模式设置,可以理解为宽松模式。在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入。
5.7的mode是STRICT_TRANS_TABLES也就是严格模式。用于进行数据的严格校验,错误数据不能插入,报error(错误),并且事务回滚。

宽松模式 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而报错。

模式查看和设置

select @@session.sql_mode;select @@global.sql_mode;show variables like 'sql_mode'; mysql> select @@session.sql_mode;+-----------------------------------------------------------------------------------------------------------------------+| @@session.sql_mode                                                                                                    |+-----------------------------------------------------------------------------------------------------------------------+| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |+-----------------------------------------------------------------------------------------------------------------------+1 row in set (0.00 sec)
  • 临时设置方式:设置当前窗口中设置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_ENGINE_SUBSTITUTION

然后重启MySQL 。

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


评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 立即注册

合作电话:010-64087828

社区邮箱:greatsql@greatdb.com

社区公众号
社区小助手
QQ群
GMT+8, 2024-4-19 20:07 , Processed in 0.012872 second(s), 8 queries , Redis On.
返回顶部