• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 字符串字符集和校验规则

    每个字符串文字都有一个字符集和一个校验规则。

    对于简单语句,字符串具有和系统变量定义的连接默认字符集和校验规则。SELECT 'string'character_set_connectioncollation_connection

    字符串文字可能具有可选的字符集介绍程序和COLLATE子句,以将其指定为使用特定字符集和校验规则的字符串:

    [_charset_name]'string' [COLLATE collation_name]
    

    该表达式正式称为介绍者。它告诉解析器,“其后的字符串使用字符集。”导引器不会改变像串介绍人字符集会做。尽管可能会发生填充,但它不会更改字符串值。引入器只是一个信号。请参见“字符集简介”。_charset_namecharset_nameCONVERT()

    例子:

    SELECT 'abc';
    SELECT _latin1'abc';
    SELECT _binary'abc';
    SELECT _utf8mb4'abc' COLLATE utf8mb4_danish_ci;
    

    字符集介绍程序和COLLATE子句是根据标准SQL规范实现的。

    MySQL通过以下方式确定字符集和字符串文字的校验规则:

    • 如果同时_charset_name和指定,字符集和校验规则使用。必须是的允许校验规则。COLLATE collation_namecharset_namecollation_namecollation_namecharset_name
    • 如果_charset_name指定但未COLLATE指定,charset_name则使用字符集及其默认校验规则。要参见每个字符集的默认校验规则,请使用SHOW CHARACTER SET语句或查询INFORMATION_SCHEMACHARACTER_SETS表。
    • 如果_charset_name未指定但已指定,则使用系统变量和校验规则给定的连接默认字符集。必须是连接默认字符集的允许校验规则。COLLATE collation_namecharacter_set_connectioncollation_namecollation_name
    • 否则(既未指定,也_charset_name未指定),将使用和系统变量给出的连接默认字符集和校验规则。COLLATE collation_namecharacter_set_connectioncollation_connection

    例子:

    • 具有latin1字符集和latin1_german1_ci校验规则的非二进制字符串:

      SELECT _latin1'Müller' COLLATE latin1_german1_ci;
      
    • 具有utf8mb4字符集及其默认校验规则(即utf8mb4_general_ci)的非二进制字符串:

      SELECT _utf8mb4'Müller';
      
    • 具有binary字符集及其默认校验规则(即binary)的二进制字符串:

      SELECT _binary'Müller';
      
    • 具有连接默认字符集和utf8mb4_general_ci校验规则的非二进制字符串(如果连接字符集不是,则失败utf8mb4):

      SELECT 'Müller' COLLATE utf8mb4_general_ci;
      
    • 具有连接默认字符集和校验规则的字符串:

      SELECT 'Müller';
      

    引入程序指示以下字符串的字符集,但不更改解析器在字符串内执行转义处理的方式。解析器始终根据给出的字符集来解释转义character_set_connection

    以下示例显示,character_set_connection即使在引入器存在的情况下,也会使用Escape进行转义处理。这些示例使用SET NAMEScharacter_set_connection如“连接字符集和校验规则”中所讨论的那样改变),并使用HEX()函数显示结果字符串,以便可以看到确切的字符串内容。

    范例1:

    mysql> SET NAMES latin1;
    mysql> SELECT HEX('à\n'), HEX(_sjis'à\n');
    +------------	+-----------------	+
    | HEX('à\n')  	| HEX(_sjis'à\n')  	|
    +------------	+-----------------	+
    | E00A       	| E00A            	|
    +------------	+-----------------	+
    

    在此,à(十六进制值E0)后跟\n换行符的转义序列。使用的character_set_connection值解释转义序列latin1以产生文字换行符(十六进制值0A)。即使对于第二个字符串,也会发生这种情况。也就是说,_sjis介绍者不会影响解析器的转义处理。

    范例2:

    mysql> SET NAMES sjis;
    mysql> SELECT HEX('à\n'), HEX(_latin1'à\n');
    +------------	+-------------------	+
    | HEX('à\n')  	| HEX(_latin1'à\n')  	|
    +------------	+-------------------	+
    | E05C6E     	| E05C6E            	|
    +------------	+-------------------	+
    

    在此character_set_connectionsjis一个字符集,à其后跟\(十六进制值055C)的序列是有效的多字节字符。因此,字符串的前两个字节被解释为单个sjis字符,\而不被解释为转义字符。以下n(十六进制值6E)不解释为转义序列的一部分。即使对于第二个字符串也是如此。在_latin1引导不影响转义处理。