9.2.2. 标识符区分大小写 在 MySQL 中,数据库对应于数据目录中的目录。数据库中的每个表对应于数据库目录中的至少一个文件(可能更多,取决于存储引擎)。因此,底层操作系统的大小写敏感性在数据库和表名的大小写敏感性中起作用。这意味着数据库和表名在 Windows 中不区分大小写,而在大多数 Unix 中区分大小写。一个值得注意的例外是 Mac OS X,它基于 Unix,但使用不区分大小写的默认文件系统类型 (HFS+)。但是,Mac OS X 也支持 UFS 卷,它与任何 Unix 一样区分大小写。请参阅第 1.8.4 节,“标准 SQL 的 MySQL 扩展”。
注意 尽管在某些平台上数据库和表名不区分大小写,但您不应在同一语句中使用不同大小写来引用给定的数据库或表。以下语句不起作用,因为它同时将表称为 my_table 和 MY_TABLE:
mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1; 列、索引和存储的例程名称在任何平台上都不区分大小写,列别名也不区分。触发器名称区分大小写,这与标准 SQL 不同。
默认情况下,表别名在 Unix 上区分大小写,但在 Windows 或 Mac OS X 上不区分大小写。以下语句在 Unix 上不起作用,因为它将别名称为 a 和 A:
mysql> SELECT col_name FROM tbl_name AS a -> WHERE a.col_name = 1 OR A.col_name = 2; 但是,在 Windows 上允许使用相同的语句。为避免此类差异引起的问题,最好采用一致的约定,例如始终使用小写名称创建和引用数据库和表。建议使用此约定以实现最大的便携性和易用性。
表和数据库名称如何存储在磁盘上并在 MySQL 中使用受 lower_case_table_names 系统变量的影响,您可以在启动 mysqld 时设置该变量。lower_case_table_names 可以采用下表中显示的值。在 Unix 上,lower_case_table_names 的默认值为 0。在 Windows 上,默认值为 1。在 Mac OS X 上,默认值为 2。
值 含义 0 表和数据库名称使用 CREATE TABLE 或 CREATE DATABASE 语句中指定的字母大小写存储在磁盘上。名称比较区分大小写。如果您在具有不区分大小写文件名的系统(例如 Windows 或 Mac OS X)上运行 MySQL,则不应将此变量设置为 0。如果在不区分大小写的文件系统上使用 --lower-case-table-names=0 将此变量强制为 0,并使用不同的字母大小写访问 MyISAM 表名,则可能会导致索引损坏。1 表名以小写形式存储在磁盘上,名称比较不区分大小写。MySQL 在存储和查找时将所有表名转换为小写。此行为也适用于数据库名称和表别名。2 表和数据库名称使用 CREATE TABLE 或 CREATE DATABASE 语句中指定的字母大小写存储在磁盘上,但 MySQL 在查找时将它们转换为小写。名称比较不区分大小写。这仅适用于不区分大小写的文件系统!InnoDB 表名以小写形式存储,如 lower_case_table_names=1。如果您只在一个平台上使用 MySQL,您通常不必更改 lower_case_table_names 变量的默认值。但是,如果要在文件系统区分大小写不同的平台之间传输表,则可能会遇到困难。例如,在 Unix 上,您可以有两个不同的表,名为 my_table 和 MY_TABLE,但在 Windows 上,这两个名称被认为是相同的。
在所有系统上使用 lower_case_table_names=1。这样做的主要缺点是,当您使用 SHOW TABLES 或 SHOW DATABASES 时,您看不到原始字母大小写的名称。
在 Unix 上使用 lower_case_table_names=0,在 Windows 上使用 lower_case_table_names=2。这将保留数据库和表名的字母大小写。这样做的缺点是您必须确保您的语句在 Windows 上始终以正确的字母大小写引用您的数据库和表名。如果您将语句转移到字母大小写很重要的 Unix,如果字母大小写不正确,它们将不起作用。
例外:如果您正在使用 InnoDB 表并试图避免这些数据传输问题,则应在所有平台上将 lower_case_table_names 设置为 1 以强制将名称转换为小写。
如果您计划在 Unix 上将 lower_case_table_names 系统变量设置为 1,则必须先将旧数据库和表名转换为小写,然后再停止 mysqld 并使用新变量设置重新启动它。要对单个表执行此操作,请使用 RENAME TABLE:
将表 T1 重命名为 t1;要转换一个或多个整个数据库,请在设置 lower_case_table_names 之前转储它们,然后删除数据库,并在设置 lower_case_table_names 后重新加载它们:
使用 mysqldump 转储每个数据库:
mysqldump --databases db1 > db1.sql mysqldump --databases db2 > db2.sql ... 对每个必须重新创建的数据库执行此操作。
使用 DROP DATABASE 删除每个数据库。
停止服务器,设置 lower_case_table_names,然后重新启动服务器。
重新加载每个数据库的转储文件。因为设置了 lower_case_table_names,所以每个数据库和表名将在重新创建时转换为小写:
mysql < db1.sql mysql < db2.sql ... 如果根据二进制排序规则它们的大写形式相等,则对象名称可能被视为重复。对于游标、条件、过程、函数、保存点、存储的例程参数和存储的程序局部变量的名称也是如此。对于列名、约束名、数据库名、使用 PREPARE 准备的语句、表、触发器、用户和用户定义的变量的名称,情况并非如此。