Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  Using Collation in INFORMATION_SCHEMA Searches

12.8.7 在 INFORMATION_SCHEMA 搜索中使用排序

INFORMATION_SCHEMA 表中的字符串列具有 utf8mb3_general_ci 排序,该排序是大小写不敏感的。然而,对于在文件系统中表示的对象(例如数据库和表),INFORMATION_SCHEMA 字符串列中的搜索可能是大小写敏感或大小写不敏感,具体取决于基础文件系统的特征和 lower_case_table_names 系统变量的设置。例如,如果文件系统是大小写敏感的,那么搜索可能是大小写敏感的。

假设查询搜索 SCHEMATA.SCHEMA_NAME 列以查找 test 数据库。在 Linux 中,文件系统是大小写敏感的,因此比较 SCHEMATA.SCHEMA_NAME'test' 匹配,但比较与 'TEST' 不匹配:

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME = 'test';
+-------------+
| SCHEMA_NAME |
+-------------+
| test        |
+-------------+

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME = 'TEST';
Empty set (0.00 sec)

这些结果发生在 lower_case_table_names 系统变量设置为 0 时。lower_case_table_names 设置为 1 或 2 会导致第二个查询返回与第一个查询相同的(非空)结果。

Note

禁止以不同于服务器初始化时的 lower_case_table_names 设置启动服务器。

在 Windows 或 macOS 中,文件系统不是大小写敏感的,因此比较匹配 'test''TEST'

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME = 'test';
+-------------+
| SCHEMA_NAME |
+-------------+
| test        |
+-------------+

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME = 'TEST';
+-------------+
| SCHEMA_NAME |
+-------------+
| TEST        |
+-------------+

在这种情况下,lower_case_table_names 的值不起作用。

前面的行为是因为 utf8mb3_general_ci 排序不用于 INFORMATION_SCHEMA 查询中搜索文件系统中表示的对象。

如果 INFORMATION_SCHEMA 列上的字符串操作的结果与预期不同,可以使用明确的 COLLATE 子句来强制合适的排序(参见 第 12.8.1 节,“在 SQL 语句中使用 COLLATE”)。例如,要执行大小写不敏感的搜索,可以使用 COLLATE 与 INFORMATION_SCHEMA 列名:

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME COLLATE utf8mb3_general_ci = 'test';
+-------------+
| SCHEMA_NAME |
+-------------+
| test        |
+-------------+

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME COLLATE utf8mb3_general_ci = 'TEST';
+-------------+
| SCHEMA_NAME |
+-------------+
| test        |
+-------------+

您也可以使用 UPPER()LOWER() 函数:

WHERE UPPER(SCHEMA_NAME) = 'TEST'
WHERE LOWER(SCHEMA_NAME) = 'test'

尽管可以在具有大小写敏感文件系统的平台上执行不区分大小写的比较,如上所示,但这并不一定是正确的做法。在这些平台上,可能存在多个名称仅在大小写上不同的对象。例如,名为 cityCITYCity 的表都可以同时存在。请考虑搜索是否应该匹配所有这些名称或仅匹配一个,并编写相应的查询。以下比较的第一个(使用 utf8mb3_bin)是区分大小写的;其他的则不是:

WHERE TABLE_NAME COLLATE utf8mb3_bin = 'City'
WHERE TABLE_NAME COLLATE utf8mb3_general_ci = 'city'
WHERE UPPER(TABLE_NAME) = 'CITY'
WHERE LOWER(TABLE_NAME) = 'city'

INFORMATION_SCHEMA 字符串列中搜索引用的值时,使用 utf8mb3_general_ci 排序规则,因为 INFORMATION_SCHEMA 是一个“虚拟”数据库,不在文件系统中表示。例如,与 SCHEMATA.SCHEMA_NAME 的比较将匹配 'information_schema''INFORMATION_SCHEMA',无论平台如何:

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME = 'information_schema';
+--------------------+
| SCHEMA_NAME        |
+--------------------+
| information_schema |
+--------------------+

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME = 'INFORMATION_SCHEMA';
+--------------------+
| SCHEMA_NAME        |
+--------------------+
| information_schema |
+--------------------+