MySQL中数据库与数据目录内的数据库目录相对应,每个表对应所在的数据库对应的目录下边的一系列文件,触发器也与特定的文件关联。因此,底层操作系统对大小写的敏感性与在其上运行的数据库的大小写敏感性息息相关。这也意味着,库名、表明、触发器名在Windows系统下大小写不敏感而在多数类Unix系统下大小写敏感,一个例外是OS X系统下(默认使用HFS+文件系统)大小写不敏感。然而,OS X还支持UFS文件系统,此时对大小写又是敏感的。至于列、索引、存储例程和事件在任何平台上都是大小写不敏感的。
除了底层文件OS外,lower_case_table_name系统变量也影响MySQL处理对象名称的大小写敏感性。需注意的是,无论大小写是否敏感,在同一语句中分别用大写、小写对同一对象进行引用会触发错误:
mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;
默认情况下表别名在Unix也是大小写敏感的,在Windows或OS X上大小写不敏感。下边的语句可在Windows或OS X系统上成功执行但在Unix上会失败。
mysql> SELECT col_name FROM tbl_name AS a WHERE a.col_name = 1 OR A.col_name = 2;
针对上述各种情况,最好的策略是使用统一的约定,如创建和引用表时统一使用小写。
lower_case_table_names 变量影响MySQL中表名和数据库名如何在磁盘上存储以及如何在SQL中使用。需注意的是该变量的配置不影响触发器名称的大小写敏感性,也即,触发器的大小也敏感性完全由底层操作系统决定。该变量可能的取值如下:
0:表、库名在磁盘上以定义中的大小写存储,比较时大小写敏感。不能在大小写不敏感的操作系统如Windows或OS X上运行的MySQL中将变量值调整为0,这样,使用不同的大小写名称访问MyISAM表时会造成索引损坏。
1:表、库名在磁盘上以定义中名称对应的小写名称存储,比较时转换为小写形式比较,也即大小写不敏感。这一规则也适用于别名。
2:表、库名在磁盘上以定义中的大小写存储,比较时转换为小写形式比较,也即比较时大小写不敏感。这一设置仅可运行在大小写不敏感的文件系统上。
若仅在单一平台使用MySQL则可不必调整该参数,保留默认值即可。然而,这可能会在不同平台间迁移表时造成麻烦。比如,默认情况下Unix平台上课存在my_table和MY_TABLE但在Windows平台上这两者被认为是一样的。为避免此种情况有两种办法:
1:在所有平台上使用lower_case_table_names=1,所带来的唯一缺点是使用show databases或showtables时无法看到原始的表名,而都是转换成小写后的表名。
2:在Unix平台使用lower_case_table_names=0,在Windows平台使用lower_case_table_names=2.缺点是必须保证Windows平台下的SQL语句中表名、库名的引用必须完全符合定义中的大小写。否则迁移到Unix平台后可能造成语句不工作。
需要特别注意的地方:若要在Unix平台将lower_case_table_names设置为1需要在停止mysqld并重启前将旧的数据库名和表名重命名为小写的形式:
若是单个表:RENAME TABLE T1 TO t1;
若是一个或多个库:先备份、再删库、在设置参数值为1后重启服务并重新导入备份。
lower_case_table_name为全局静态变量、调整需重启服务,且将该参数由0调整为1时会影响到之前有大写字母出现的库名、表名,会提示找不到。所以调整参数并重启服务前务必先将对应的库、表名重命名为对应的小写。