Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 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 的值在这个上下文中没有影响。

前面的行为是因为对 INFORMATION_SCHEMA 查询时,不使用 utf8mb3_general_ci 排序规则来搜索与文件系统中的对象相应的值。

如果字符串操作结果与期望不同,可以使用明确的 COLLATE 子句强制使用合适的排序规则(见第12.8.1节,“SQL 语句中的 COLLATE”)。例如,进行不区分大小写的搜索,可以使用 COLLATEINFORMATION_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的表可以同时存在。考虑是否应该匹配所有这些名称还是只匹配一个,并编写查询语句。

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字符串列中搜索值,指向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 |
+--------------------+