一个因MySQL大小写敏感导致的问题
做一个积极的人
编码、改bug、提升自己
我有一个乐园,面向编程,春暖花开!
00 MYSQL对大小写敏感
见字如面,见标题知内容。你有遇到过因为MYSQL对大小写敏感而被坑的体验吗?
之前看过阿里巴巴Java开发手册,在MySql建表规约里有看到:
【强制】表名、字段名必须使用小写字母或数字 , 禁止出现数字开头,禁止两个下划线中间只 出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
说明: MySQL 在 Windows 下不区分大小写,但在 Linux 下默认是区分大小写。因此,数据库名、 表名、字段名,都不允许出现任何大写字母,避免节外生枝。
正例: aliyun _ admin , rdc _ config , level 3_ name 反例: AliyunAdmin , rdcConfig , level 3 name
如果没有真正遇到过类似的问题,有时候干巴巴的看这些规约体会不深,理解起来似懂非懂,并且也只是死记硬背而已。
01 一个表字母大小故事
最近自己在鼓捣一个项目玩玩,在自己本机上开发和测试过程中一直没有问题,但是部署到Linux服务器上后,发现有报错,日志信息大概是:
MySQLSyntaxErrorException: Table 'kytu.tb_sutyHo' doesn't exist
出现了问题,有点郁闷,本地开发好好的,怎么部署服务器就不行了。有鬼……不过莫慌。看着错误提示很明显,不就是tb_sutyHo
表不存在吗!
①于是我不慌不忙打开nv(navicat),查看这个表在不在,一看还真在,数据库中显示的tb_sutyho
,不过h是小写;
②查看代码发现代码中还真把表名写成tb_sutyHo
,就一个h写成大写H了。
问题找到了,原来是不小心写SQL的时候没有写对表名,改一下表名就搞定了,功能也一切正常了。一般情况下故事到这里也就应该结束了?问题找到了,也修复了,万事大吉了,稍后就可以吃鸡了。
对于不会玩吃鸡的我,到这里并没有结束,找到问题和解决问题的确很重要,但是找到问题出现的根源更重要,这样就能在下次规避此类问题,作为一个程序员不要两次掉入一个坑里。
我在想这个问题,本地Window环境怎么就一直没有出现这个报错提示呢?非要等我部署服务器才出现,这到底是什么问题?(如果你对Mysql大小敏感很了解,以下内容可以跳过….)
于是就利用搜索引擎,发现Mysql中控制数据库名和表名的大小写敏感由参数lower_case_table_names
控制。
在本机Window环境查看如下:
mysql> show variables like '%case%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| lower_case_file_system | ON |
| lower_case_table_names | 1 |
+------------------------+-------+
在Linux服务器查看如下:
mysql> show variables like '%case%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| lower_case_file_system | OFF |
| lower_case_table_names | 0 |
+------------------------+-------+
从上面的结果已经可以看出不同了,然而对这两个参数还没有感觉,不知道具体是什么意思。
在介绍lower_case_table_names
的时候,顺便也说一下lower_case_file_system
。
lowercasefile_system
此变量描述数据目录所在的文件系统上文件名的区分大小写。 OFF表示文件名区分大小写,ON表示它们不区分大小写。此变量是只读的,因为它反映了文件系统属性并设置它对文件系统没有影响。
lowercasetable_names
该参数为静态,可设置为0、1、2。
0 --大小写敏感。(Unix,Linux默认) 创建的库表将原样保存在磁盘上。如create database TeSt;将会创建一个TeSt的目录,create table AbCCC …将会原样生成AbCCC.frm。 SQL语句也会原样解析。
1 --大小写不敏感。(Windows默认) 创建的库表时,MySQL将所有的库表名转换成小写存储在磁盘上。 SQL语句同样会将库表名转换成小写。 如需要查询以前创建的Testtable(生成Testtable.frm文件),即便执行select * from Testtable,也会被转换成select * from testtable,致使报错表不存在。
2 --大小写不敏感(OS X默认) 创建的库表将原样保存在磁盘上。 但SQL语句将库表名转换成小写。
On Windows the default value is 1. On macOS, the default value is 2. On Linux, a value of 2 is not supported; the server forces the value to 0 instead.
在Windows上,默认值为1。在macOS上,默认值为2。在Linux上不支持值2;服务器强制该值为0。
并且官网也提示说:如果在数据目录驻留在不区分大小写的文件系统(例如Windows或macOS)上的系统上运行MySQL,则不应将lowercasetable_names设置为0。
我自己在我的window10环境尝试设置lower_case_table_names
为0的时候,MySQL的服务怎么也启动不能,启动服务报错。windows系统对大小写不敏感,见下图:
注: 如果要修改lower_case_table_names
这个值,windows下修改my.ini ,Linux下修改my.cnf配置文件,需要重启服务,具体操作可以自行上网找资料。
02 注意事项
修改lowercasetable_names导致的常见不良隐患: 如果在lower_case_table_names=0
时,创建了含有大写字母的库表,改为lower_case_table_names=1
后,则会无法被查到。
首先设置lower_case_table_names=0
CREATE TABLE `Student` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(25) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
show tables;
+----------------+
| Tables_in_aflyun |
+----------------+
| Student |
+----------------+
再设置lower_case_table_names=1
,执行查询,不管表名是大写还是小写,都提示表不存在。
mysql> select * from Student;
1146 - Table 'aflyun.Student' doesn't exist
mysql> select * from student;
1146 - Table 'aflyun.student' doesn't exist
解决方法:如果要将默认的lower_case_tables_name
为0设置成1,需先将已经存在的库表名转换为小写。
针对仅表名存在大写字母的情况:
①、lower_case_tables_name=0
时,执行rename table
成小写。
②、设置lower_case_tables_name=1
,重启生效。
针对库名存在大写字母的情况:
①、lower_case_tables_name=0
时,使用mysqldump
导出,并删除老的数据库。
②、设置lower_case_tables_name=1
,重启生效。
③、导入数据至实例,此时包含大写字母的库名已转换为小写。
03 总结
有了踩坑的经验,对开头说的阿里Mysql规约理解更加深入了。操作系统不同导致大小写敏感不一致。我们在开发时,应该按大小写敏感的原则去开发,这样可以使开发的程序兼容不同的操作系统。因此,建议在开发测试环境下把lower_case_table_names
的值设为0,便于在开发中就严格控制代码大小写敏感,提高代码的兼容和严谨。
04 参考资料
MySQL大小写敏感问题lowercasetablenames & lowercasefilesystem
谢谢你的阅读,如果您觉得这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到!祝你每天开心愉快!
不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!
愿你我在人生的路上能都变成最好的自己,能够成为一个独挡一面的人
© 每天都在变得更好的阿飞云
一个因MySQL大小写敏感导致的问题的更多相关文章
- MySQL skip-character-set-client-handshake导致的一个字符集问题
http://www.quweiji.com/mysql-skip-character-set-client-handshake%E5%AF%BC%E8%87%B4%E7%9A%84%E4%B8%80 ...
- 【已解决】Windows下 MySQL大小写敏感 解决方案及分析
Windows下 MySQL大小写敏感配置 zoerywzhou@163.com http://www.cnblogs.com/swje/ 作者:Zhouwan 2017-3-27 最近在window ...
- MySQL Flush导致的等待问题
--MySQL Flush导致的等待问题 -------------------------------2014/07/13 前言 在实际生产环境中有时会发现大量的sql语句处于waiting for ...
- MySQL大小写敏感问题和命名规范
注:本文大部内容参考自互联网相关文章 1.MySQL大小写敏感规则 MySQL中,一个库会对应一个文件夹,库里的表会则以文件的方式存放在文件夹内,所以,操作系统对大小写的敏感性决定了数据库和表的大小写 ...
- Centos7 下mysql大小写敏感问题
在Centos7 下mysql大小写敏感问题,会导致程序运行时找不到对应的表. 解决办法: 第一步:编辑/etc/my.cnf文件,在[mysqld]节下 添加 lower_case_table_na ...
- Docker容器内Mysql大小写敏感方案解决
Docker容器内Mysql大小写敏感方案解决 一.(lower_case_table_names)参数说明 二.Docker 部署 MySql 并修改为大小写不敏感 2.1直接在Docker启动的时 ...
- 一个基于mysql构建的队列表
通常大家都会使用redis作为应用的任务队列表,redis的List结构,在一段进行任务的插入,在另一端进行任务的提取. 任务的插入 $redis->lPush("key:task:l ...
- 分享一个解决MySQL写入中文乱码的方法
分享一个解决MySQL写入中文乱码的方法 之前有发帖请教过如何解决MySQL写入中文乱码的问题.但没人会,或者是会的人不想回答.搜索网上的答案并尝试很多次无效,所以当时就因为这个乱码问题搁浅了一个软件 ...
- mysql大小写敏感(默认为1,不敏感)
在 MySQL 中,数据库和表其实就是数据目录下的目录和文件,因而,操作系统的敏感性决定数据库和表命名的大小写敏感.这就意味着数据库和表名在 Windows 中是大小写不敏感的,而在大多数类型的 Un ...
随机推荐
- mac 不限速下载大文件
打开终端后,需要在终端处键入一下代码: 「注意:此处代码不完整, 完整版请 关注微信公众号:「100秒分享」,回复编号「334」获取」 cd ~/Downloads && git cl ...
- mysql 实现同一个sql查询 分页数据 和总记录数
$get_sql = "SELECT sql_calc_found_rows field1,field2 FROM table WHERE name = '1' order by add_t ...
- layui跨域问题的解决
跨域问题的解决 由于浏览器存在同源策略,所以如果 layui(里面含图标字体文件)所在的地址与你当前的页面地址不在同一个域下,即会出现图标跨域问题.所以要么你就把 layui 与网站放在同一服务器 ...
- Java 数组元素逆序Reverse的三种方式
Java 数组元素逆序Reverse的三种方式 本文链接:https://blog.csdn.net/xHibiki/article/details/82930521 题目 代码实现 说明 int ...
- 手把手教你MyEclipseUML建模(下)
手把手教你MyEclipseUML建模(下) 点击访问:手把手教你MyEclipseUML建模(上) 1.用UML 2建模 MyEclipse提供了以下UML 2特性: UML 2图:类.组件.部署. ...
- [Java复习] 分布式事务 Part 2
分布式事务了解吗?如果解决分布式事务问题的? 面试官心里: 只要聊到你做了分布式系统,必问分布式事务,起码得知道有哪些方案,一般怎么来做,每个方案的优缺点是什么. 为什么要有分布式事务? 分布式事务实 ...
- [Java复习] 分布式PRC - Dubbo
分布式RPC框架 dubbo常见问题: 1. 问dubbo的工作原理:服务注册,注册中心,服务生产者,消费者,代理通信,负载均衡 2. 问网络通信,序列化: dubbo协议,长连接,NIO,hessi ...
- ISO/IEC 9899:2011 条款6.2.2——标识符的连接
6.2.2 标识符的连接 1.在不同作用域中声明的一个标识符或在同一作用域多次出现的一个标识符可以被用作对同一个对象或函数的引用,通过一个称为连接的过程.[注:在两个不同的标识符之间没有连接.]有三种 ...
- Java中声明泛型方法
泛型是什么意思在这就不多说了,而Java中泛型类的定义也比较简单,例如:public class Test<T>{}.这样就定义了一个泛型类Test,在实例化该类时,必须指明泛型T的具体类 ...
- ASP如何将table导出EXCEL表格
网页导出excel表格非常常用,对于一些加载<table>的数据网页,经常会用到这种功能,下面和大家分享一下ASP如何导出EXCEL表格 工具/原料 ASP编辑器 方法/步骤 ...