• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 在 INFORMATION_SCHEMA 搜索中使用校验


    表中的字符串列INFORMATION_SCHEMA的校验规则为utf8_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在这种情况下,的值没有区别。

    出现上述现象的原因utf8_general_ci是,INFORMATION_SCHEMA当搜索与文件系统中表示的对象相对应的值时,校验规则未用于查询。

    如果对INFORMATION_SCHEMA列进行字符串操作的结果与预期的不同,则解决方法是使用显式COLLATE子句强制进行适当的校验规则(请参见“在SQL语句中使用COLLATE”)。例如,为了执行不区分大小写的搜索中,使用COLLATEINFORMATION_SCHEMA列名:

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

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

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

    尽管即使在具有区分大小写的文件系统的平台上也可以执行不区分大小写的比较,如所示,但这不一定总是正确的做法。在这样的平台上,可能有多个对象的名称仅在字母大小写上不同。例如,名为cityCITY和的表City可以同时存在。考虑搜索是应该匹配所有这样的名称还是仅匹配一个,然后相应地编写查询。以下第一个比较(带有utf8_bin)区分大小写;其他不是:

    WHERE TABLE_NAME COLLATE utf8_bin = 'City'
    WHERE TABLE_NAME COLLATE utf8_general_ci = 'city'
    WHERE UPPER(TABLE_NAME) = 'CITY'
    WHERE LOWER(TABLE_NAME) = 'city'
    

    INFORMATION_SCHEMA字符串列中搜索引用INFORMATION_SCHEMA自身的值时,确实会使用utf8_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 	|
    +--------------------	+