MySQL 大小写敏感

因为近期工作上的要求, 需要对之前代码进行重新排查. 由于开发人员换了一批又一批, 每个人有自己的习惯, 没有形成良好的规范, 例如大小写问题等等, 今日就简单探究一下数据库语言的大小写敏感问题.

MySQL

平时写 SQL 语句时, 并没有感觉到大小写的区别, 那么意味着 MySQL 大小写不敏感吗?
答案是否定的. MySQL 在 Windows 下大小写不敏感,但在 Linux 下默认大小写敏感.
(说着有点绕口,简言之, 敏感就是区分大小写, 不敏感就是无论大写小写都行)
如何控制大小写敏感 ( 在 my.ini 文件中可修改)

MySQL 控制库名、表名大小写敏感的参数是: lower_case_table_names
lower_case_file_system  	ON(不敏感)   OFF(敏感)   
		文件名是否区分大小写(只读不可改), windows不区分, linux区分;
lower_case_table_names 		0 (敏感)     1(不敏感)     2(不敏感)
		参数对应的默认系统 	  linux       windows      MAC OS X
0 : 在磁盘中就按照给定的大小写进行存储, 查询时同样按照给定大小写执行SQL
1 : 在磁盘中按照小写存储, 查询时也会将SQL转化为小写再执行
2 : 在磁盘中就按照给定的大小写进行存储, 查询时将SQL转化为小写执行

就现在而言 MySQL 使用场景在 linux 居多( 默认是 OFF,0 ), 通常都是在 Windows 本机( 默认是 ON,1 ) 测试, 然后将其部署在 Linux 上运行. 在此类情况下通常会出现开发程序在操作系统之间不兼容的情况. 例如:

1. 在 windows 操作系统上 set lower_case_table_names = 1 ;
2. create table STUdent (...);
3. 在 windows 上编写查询程序 select * from STUdent; (可以查询)
4. 将程序部署在 Linux 中就会出错:
	因为在 windows 上已经完成按照小写进行存储,此时存在磁盘中的表就是 student !
	由于 windows 将你写的查询语句转化成小写来执行,故 select * from STUdent 可以查询; 
	但是在 Linux 中, 是使用给定大小写执行查询语句,故 select * from STUdent 去查询在磁盘中已经存在的小写的表 student, 故报错 `STUdent` doesn't exists!
5. 将属性 set lower_case_table_names = 0 ,同理;

故, 修改lower_case_table_names参数容易导致兼容性问题

Oracle

Oracle的数据字典中,对表名和字段名的存储默认使用大写, 但是也允许小写;
执行语句时不分大小写的原因是:
oracle先解析SQL语句,把小写的字母转换成大写的再执行;
故, 出于优化建议, SQL 语句通常使用大写.

结论

综上, 我们在开发中应该保持严谨的态度, 按照大小写敏感的原则去进行开发. 这样可以使开发的程序在不同操作系统中更具生命力.

例如, 阿里开发手册中对于建库建表的规范要求:

【强制】表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只
出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
说明:MySQL 在 Windows 下不区分大小写,但在 Linux 下默认是区分大小写。因此,数据库名、表名、字段名,都不允许出现任何大写字母,避免节外生枝。
正例:aliyun_admin,rdc_config,level3_name
反例:AliyunAdmin,rdcConfig,level_3_name
拓展

为了解释 oracle 同样支持小写, 索性将 单引号、双引号、反引号在 MySQL 与 Oracle 中的区别总结一番

MySQL
单引号:将字符串常量括起来,若常量本身带有单引号,除了转义,还可以使用双引号整体括起;
	'student' 
	stu'dent转义: 'stu\'dent' 或 'stu''dent'(单引号对其转义)
	stu'dent双引号括起: "stu'dent" 
双引号:将字符串常量括起来,若常量本身带有双引号,除了转义,还可以使用单引号整体括起;
	say:"Hello"的转义: "say:\"Hello\"" 或"say:""Hello"""(两个双引分别转义)
    say:"Hello"单引号括起: 'say:"Hello"'
    注: mysql中双引号引用在某些版本中会报错,为了避免,尽量使用单引号来操作字符串!
反引号:区别保留字(就是关键字)与普通字符的符号;
	create table desc;   报错
	create table `desc`; 创建成功
	注:即使表名和字段名不是数据库保留字,尽可能也养成加上反引号的好习惯,这也可以避免错误,保证开发的顺利进行
Oracle
单引号:将字符串常量括起来;
双引号:强制区分大小写,就是之前提出 Oracle 同样支持小写;
	CREATE TABLE "StUdEnT" (...);
	建表时使用双引号严格指定大小写,在查询时就要使用相同的方式,如下,否则报错
	SELECT * FROM "StUdEnT";
反引号:  不存在