文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  在 INFORMATION_SCHEMA 搜索中使用排序规则

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 会导致第二个查询返回与第一个查询相同的(非空)结果。

注意

禁止使用与服务器初始化时使用的设置不同的 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 排序规则。

如果 INFORMATION_SCHEMA 列上的字符串操作结果与预期不符,则解决方法是使用显式 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 的表可以同时存在。请考虑搜索应该匹配所有这些名称还是仅匹配一个名称,并相应地编写查询。以下第一个比较(使用 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 字符串列中搜索引用 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 |
+--------------------+