MySQL表名大小写问题

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> MySQL表名大小写问题

MySQL表名大小写问题

在Navicat中执行检索MySQL表的操作,提示此表不存在,但库中有此表,

[SQL]select * from tbl;
[Err] 1146 - Table ‘bisal.tbl’ doesn’t exist

问题其实不难,这和MySQL的一个参数有关,lower_case_table_names。官方介绍了这个参数的使用,不同平台该参数,有不同默认值,

https://dev.mysql.com/doc/refman/5.7/en/identifier-case-sensitivity.html

How table and database names are stored on disk and used in MySQL is affected by the lower_case_table_namessystem variable, which you can set when starting mysqld. lower_case_table_names can take the values shown in the following table. This variable does not affect case sensitivity of trigger identifiers. On Unix, the default value oflower_case_table_names is 0. On Windows, the default value is 1. On OS X, the default value is 2.

MySQL表名大小写问题

If you are using MySQL on only one platform, you do not normally have to change the lower_case_table_names variable from its default value. However, you may encounter difficulties if you want to transfer tables between platforms that differ in file system case sensitivity. For example, on Unix, you can have two different tables named my_table andMY_TABLE, but on Windows these two names are considered identical. To avoid data transfer problems arising from lettercase of database or table names, you have two options:     Use lower_case_table_names=1 on all systems. The main disadvantage with this is that when you use SHOW TABLESor SHOW DATABASES, you do not see the names in their original lettercase.     Use lower_case_table_names=0 on Unix and lower_case_table_names=2 on Windows. This preserves the lettercase of database and table names. The disadvantage of this is that you must ensure that your statements always refer to your database and table names with the correct lettercase on Windows. If you transfer your statements to Unix, where lettercase is significant, they do not work if the lettercase is incorrect.

Exception: If you are using InnoDB tables and you are trying to avoid these data transfer problems, you should setlower_case_table_names to 1 on all platforms to force names to be converted to lowercase.

Linux平台下检索这个参数,默认值是0,说明大小写敏感,

mysql show variables like 'lower_case_table_names'; +------------------------------------+--------+ | Variable_name                    | Value | +------------------------------------+--------+ | lower_case_table_names   | 0        | +------------------------------------+--------+ 1 row in set (0.01 sec)

设置my.cnf配置文件lower_case_table_names=1,重启MySQL,

[mysqld]

lower_case_table_names=1

此时参数值改为1,

mysql show variables like 'lower_case_table_names'; +------------------------------------+--------+ | Variable_name                    | Value | +------------------------------------+--------+ | lower_case_table_names   | 1        | +------------------------------------+--------+ 1 row in set (0.01 sec)

在Oracle中,比如我就想建一张小写TBL的表,可以使用create table “tbl”,用引号来引用,读取的时候则需要用引号,否则会用大写TBL来检索,找不到这张表,如果创建对象没有使用引号,存入数据字典,会默认将小写的对象名,转换为大写存储。

对于Oracle中大小写对象名,斗佛曾经有篇文章的总结,值得借鉴,

MySQL表名大小写问题

ORACLE在创建对像时如果没有加引号,对存入数据字典时都会将对像名小写字母转换成大写字母存储,如mytable将转换成MYTABLE;如果创建时加了引号,则以引号内的实际字符存储。

访问时如果没加引号则会将小写字母转换成大写字母再访问,如mytable将转换成MYTABLE;如果加了引号则以引号内的实际字符访问。

ORACLE在读取数据字典时只要发现对像名里有小写字母或者是除字母汉字以外开头的字符都认为是大小写敏感的,并且要求在访问时需要加上引号。

这篇文章,总结了些常见的数据库,对于对象大小写的处理,

http://blog.sina.com.cn/s/blog_5d8c53c70102vdyi.html

hsql: 不区分大小写。

MySQL:Windows下不区分大小写;Linux下database名,table名区分大小写,column名不区分;在MySQL中加” “或者‘’都不行, 他们代表字符串;Linux下默认是大写。


注:这就是lower_case_table_names参数在不同平台,默认值不同导致的现象。

Oracle:不区分大小写,全是大写。Oracle中" "的作用是强制区分大小写 Oracle在建表或者字段时,如果没有双引号,Oracle会把表名、字段名全部转化为大写字母然后写入数据字典。访问数据字典时,没有双引号Oracle会将其转化成大写然后再去数据字段中查找。如果加上双引号则能区分大小写。不仅仅关键字不区分大小写,函数名,过程名,表名称,pl/sql块中变量名,用户名,密码等都不区分大小写。所以在Oracle中,还是建议全部用大写。

postgresql:表名、字段名都是区分大小写的,在SQL语句中对大小写是不敏感的,如果要查询大写字母的字段,同样要加上双引号。表、视图、序列的命令尽量使用小写。

SQL Server:默认情况下,不区分大小写。可以通过collate Chinese_PRC_CS_AS来要求区分大小写,可以通过collate Chinese_PRC_CI_AS恢复默认的不区分大小写。

另外,MySQL修改lower_case_table_names参数,有些帖子说会导致原来的大写的表名无法识别,解决办法是,

(1) 在修改配置之前一定先将所有表的表结构和表数据导出做备份;
(2) 删除原来的表;
(3) 修改配置;
(4) 将表结构和表数据导入。
按照上面的步骤操作之后,表名就不区分大小写了。

这个操作,相当于初始化数据字典。

可见,一个大小写敏感,在不同数据库,有不同处理逻辑,即使在一个MySQL中,不同平台,同样各有区别,但是要明白其中的原因,了解了其中原理,才能让我们知道如何控制,实现我们的需求,这才是最重要。

如果您觉得本文有帮助,欢迎关注转发:bisal的个人杂货铺,

MySQL表名大小写问题 MySQL表名大小写问题
本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> MySQL表名大小写问题


 上一篇
Lost connection to MySQL server错误 Lost connection to MySQL server错误
一套MySQL的数据库,之前一直可以远程访问,但最近从笔记本,使用Navicat工具访问,提示错误,无法连接, ping和telnet端口均正常,关于2013错误, Lost connection to MySQL server
下一篇 
EDB(,PG)对于执行计划的解读 EDB(,PG)对于执行计划的解读
今天同事提出了一个EDB数据库中SQL语句的性能问题,碰巧最近手头的一个系统,进行了重构开发,即将投产,用的也是EDB,想必和他打交道的机会不少,确实属于小白,有待学习的地方自然不少。 关于什么是EDB,可以参考《》。 这个性能问