9.2.3 区分大小写的标识符

在 MySQL 中,数据库与 data 目录中的目录相对应。数据库中的每个 table 都对应于数据库目录中的至少一个文件(可能还有更多文件,具体取决于存储引擎)。触发器也对应于文件。因此,基础 os 的区分大小写在数据库,table 和触发器名称的区分大小写中起作用。这意味着这些名称在 Windows 中不区分大小写,但在大多数 Unix 版本中都区分大小写。 macOS 是一个值得注意的 exception,它是基于 Unix 的,但是使用了不区分大小写的默认文件系统类型(HFS)。但是,macOS 还支持 UFS 卷,这与任何 Unix 一样都区分大小写。参见第 1.8.1 节“标准 SQL 的 MySQL 扩展”。系统变量lower_case_table_names也影响服务器处理标识符区分大小写的方式,如本节后面所述。

Note

尽管数据库,table 和触发器名称在某些平台上不区分大小写,但您不应在同一语句中使用不同的大小写形式引用其中之一。以下语句不起作用,因为它同时将 table 引用为my_tableMY_TABLE

mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;

列,索引,存储的例程和事件名称在任何平台上都不区分大小写,列别名也不区分大小写。

但是,日志文件组的名称区分大小写。这与标准 SQL 不同。

默认情况下,table 别名在 Unix 上区分大小写,但在 Windows 或 macOS 上不区分大小写。以下语句在 Unix 上不起作用,因为它同时将别名引用为aA

mysql> SELECT col_name FROM tbl_name AS a
       WHERE a.col_name = 1 OR A.col_name = 2;

但是,在 Windows 上允许使用相同的语句。为避免此类差异引起的问题,最好采用一致的约定,例如始终使用小写名称创建和引用数据库和 table。建议使用此约定,以实现最大的可移植性和易用性。

lower_case_table_names系统变量会影响 table 和数据库名称在磁盘上的存储方式以及在 MySQL 中的使用方式,您可以在启动mysqld时设置该变量。 lower_case_table_names可以采用下 table 中显示的值。此变量不会影响触发器标识符的区分大小写。在 Unix 上,默认值lower_case_table_names为 0.在 Windows 上,默认值为 1.在 macOS 上,默认值为 2.

ValueMeaning
0table 和数据库名称使用CREATE TABLECREATE DATABASE语句中指定的字母大小写存储在磁盘上。名称比较区分大小写。如果您在具有不区分大小写的文件名(例如 Windows 或 macOS)的系统上运行 MySQL,则不要将该变量设置为 0.如果在不区分大小写的文件系统上使用--lower-case-table-names=0将此变量强制为 0,并使用不同的字母大小写访问MyISAMtable 名,则可能导致索引损坏。
1table 名以小写形式存储在磁盘上,名称比较不区分大小写。 MySQL 在存储和查找时将所有 table 名转换为小写。此行为也适用于数据库名称和 table 别名。
2table 名和数据库名使用CREATE TABLECREATE DATABASE语句中指定的字母大小写存储在磁盘上,但是 MySQL 在查找时将它们转换为小写。名称比较不区分大小写。这仅适用于不区分大小写的文件系统! InnoDBtable 名和视图名以小写形式存储,与lower_case_table_names=1一样。

如果仅在一个平台上使用 MySQL,通常不必从其默认值更改lower_case_table_names变量。但是,如果要在文件系统区分大小写不同的平台之间传输 table,则可能会遇到困难。例如,在 Unix 上,可以有两个不同的 table,分别名为my_tableMY_TABLE,但是在 Windows 上,这两个名称被认为是相同的。为避免数据库或 table 名的字母大写引起的数据传输问题,您有两种选择:

  • 在所有系统上使用lower_case_table_names=1。这样做的主要缺点是,当您使用SHOW TABLESSHOW DATABASES时,看不到其名称的原始字母大写。

  • 在 Unix 上使用lower_case_table_names=0,在 Windows 上使用lower_case_table_names=2。这将保留数据库和 table 名的字母大小写。这样做的缺点是,必须确保在 Windows 上,语句始终以正确的字母大小写引用数据库和 table 名。如果将语句转移到大写字母大的 Unix,则如果大写字母不正确,则它们将不起作用。

exception :如果您使用的是InnoDBtable,并且试图避免这些数据传输问题,则应在所有平台上将lower_case_table_names设置为 1,以强制将名称转换为小写。

如果计划在 Unix 上将lower_case_table_names系统变量设置为 1,则必须先将旧的数据库和 table 名转换为小写,然后再停止mysqld并使用新的变量设置重新启动它。为此,请使用RENAME TABLE

RENAME TABLE T1 TO t1;

要转换一个或多个完整数据库,请在设置lower_case_table_names之前转储它们,然后删除数据库,并在设置lower_case_table_names之后重新加载它们:

mysqldump --databases db1 > db1.sql
mysqldump --databases db2 > db2.sql
...

对必须重新创建的每个数据库执行此操作。

  • 使用DROP DATABASE删除每个数据库。

  • 停止服务器,设置lower_case_table_names,然后重新启动服务器。

  • 重新加载每个数据库的转储文件。因为设置了lower_case_table_names,所以每个数据库和 table 名在重新创建时都将转换为小写:

mysql < db1.sql
mysql < db2.sql
...

如果对象名称的大写形式根据二进制排序规则相等,则可以将它们视为重复项。对于游标,条件,过程,函数,保存点,存储的例程参数,存储的程序局部变量和插件的名称,这是正确的。对于列,约束,数据库,分区,使用PREPARE编写的语句,table,触发器,用户和用户定义的变量的名称,则不正确。

文件系统区分大小写会影响在INFORMATION_SCHEMAtable 的字符串列中的搜索。有关更多信息,请参见第 10.8.7 节“在 INFORMATION_SCHEMA 搜索中使用归类”