MySQL 中的字符集和排序规则

来自Wikioe
Eijux讨论 | 贡献2021年3月28日 (日) 00:05的版本 →‎字符集库
跳到导航 跳到搜索


关于

MySQL Server 支持多种字符集。


要显示可用的字符集,请使用“INFORMATION_SCHEMA”的“CHARACTER_SETS”表或“SHOW CHARACTER SET”语句。

  • 默认情况下,“SHOW CHARACTER SET”语句显示所有可用字符集。它带有一个可选的“LIKE”或“WHERE”子句,该子句指示要匹配的字符集名称:
    mysql> SHOW CHARACTER SET LIKE 'latin%';
    +---------+-----------------------------+-------------------+--------+
    | Charset | Description                 | Default collation | Maxlen |
    +---------+-----------------------------+-------------------+--------+
    | latin1  | cp1252 West European        | latin1_swedish_ci |      1 |
    | latin2  | ISO 8859-2 Central European | latin2_general_ci |      1 |
    | latin5  | ISO 8859-9 Turkish          | latin5_turkish_ci |      1 |
    | latin7  | ISO 8859-13 Baltic          | latin7_general_ci |      1 |
    +---------+-----------------------------+-------------------+--------+
    


给定的字符集始终至少具有一个排序规则,大多数字符集具有多个排序规则。要列出字符集的显示归类,请使用“INFORMATION_SCHEMA”的“COLLATIONS”表或“SHOW COLLATION”语句。

  • 默认情况下,“SHOW COLLATION”语句显示所有可用的排序规则。它带有一个可选的“LIKE”或“WHERE”子句,该子句指示要显示的排序规则名称。
    mysql> SHOW COLLATION WHERE Charset = 'latin1';
    +-------------------+---------+----+---------+----------+---------+
    | Collation         | Charset | Id | Default | Compiled | Sortlen |
    +-------------------+---------+----+---------+----------+---------+
    | latin1_german1_ci | latin1  |  5 |         | Yes      |       1 |
    | latin1_swedish_ci | latin1  |  8 | Yes     | Yes      |       1 |
    | latin1_danish_ci  | latin1  | 15 |         | Yes      |       1 |
    | latin1_german2_ci | latin1  | 31 |         | Yes      |       2 |
    | latin1_bin        | latin1  | 47 |         | Yes      |       1 |
    | latin1_general_ci | latin1  | 48 |         | Yes      |       1 |
    | latin1_general_cs | latin1  | 49 |         | Yes      |       1 |
    | latin1_spanish_ci | latin1  | 94 |         | Yes      |       1 |
    +-------------------+---------+----+---------+----------+---------+
    


排序规则一般具有以下特征:

  • 两种不同的字符集不能具有相同的排序规则。
  • 每个字符集都有一个“默认排序规则”。
    例如,latin1 和 utf8 的默认排序规则分别为 latin1_swedish_ci 和 utf8_general_ci 。
    • “INFORMATION_SCHEMA”的“CHARACTER_SET”表和“SHOW CHARACTER SET”语句指示每个字符集的默认排序规则。
    • “INFORMATION_SCHEMA”的“COLLATIONS”表和“SHOW COLLATION”语句具有一列,该列指示每个排序规则是否为其字符集的默认字符集(如果是Yes,则为空)。
  • 排序规则名称以它们所关联的字符集的名称开头,通常后跟一个或多个后缀,以表示其他排序规则特征。

字符集库

字符集的库是字符集中的字符集合。

字符串表达式具有一个库属性,该属性可以具有两个值:

  1. ASCII:表达式只能包含 ASCII 字符;也就是说,Unicode 范围是U+0000到U+007F的字符。
  2. UNICODE:表达式可以包含 Unicode 范围U+0000到U+10FFFF的字符。这包括基本多语言平面(BMP)范围内的字符(U+0000至U+FFFF)和 BMP 范围外的辅助字符(U+10000至U+10FFFF)。
  • ASCII 范围是 UNICODE 范围的子集,因此具有 ASCII 库的字符串可以安全地转换,而不会丢失任何具有 UNICODE 库的字符串的信息集。也可以将其安全地转换为 ascii 字符集的超集的任何字符集。 (所有 MySQL 字符集都是ascii的超集,但swe7除外,后者将一些标点符号重用为瑞典的带重音符号的字符.)
  • 在大多数情况下,当排序规则强制性的规则不足以解决歧义性时,MySQL 否则会返回“非法的排序规则混合”错误,因此使用库可以在表达式中进行字符集转换。


以下讨论提供了表达式及其组成部分的示例,并描述了组成部分的使用如何更改字符串表达式求值:

  1. 字符串常量的库取决于字符串内容,并且可能与字符串字符集的库不同。考虑以下语句:
    SET NAMES utf8; SELECT 'abc';
    SELECT _utf8'def';
    SELECT N'MySQL';
    
    尽管在上述每种情况下,字符集均为utf8,但这些字符串实际上并不包含 ASCII 范围以外的任何字符,因此它们的字符集为 ASCII 而不是 UNICODE。
  2. 由于其字符集,具有 ascii 字符集的列具有ASCII指令库。在下表中,c1具有ASCII曲目:
    CREATE TABLE t1 (c1 CHAR(1) CHARACTER SET ascii);
    
    在没有库的情况下发生错误的情况下,库可以如何确定结果:
    CREATE TABLE t1 (
      c1 CHAR(1) CHARACTER SET latin1,
      c2 CHAR(1) CHARACTER SET ascii
    );
    INSERT INTO t1 VALUES ('a','b');
    SELECT CONCAT(c1,c2) FROM t1;
    
    没有曲目,则会发生此错误:
    ERROR 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT)
    and (ascii_general_ci,IMPLICIT) for operation 'concat'
    
    使用库,可以发生子集到超集(ascii到latin1)的转换,并返回结果:
    +---------------+
    | CONCAT(c1,c2) |
    +---------------+
    | ab            |
    +---------------+
    
  3. 具有一个字符串参数的函数将继承其参数库。 UPPER(_utf8'abc') 的结果具有ASCII指令库,因为其自变量具有ASCII指令库。 (尽管使用_utf8引入程序,但字符串'abc'不包含 ASCII 范围之外的字符.)
  4. 对于返回字符串但没有字符串参数并使用“character_set_connection”作为结果字符集的函数,如果“character_set_connection”为 ascii,则结果库为 ASCII,否则为 UNICODE:
    FORMAT(numeric_column, 4);
    
    使用库会改变 MySQL 评估以下示例的方式:
    SET NAMES ascii;
    CREATE TABLE t1 (a INT, b VARCHAR(10) CHARACTER SET latin1);
    INSERT INTO t1 VALUES (1,'b');
    SELECT CONCAT(FORMAT(a, 4), b) FROM t1;
    
    没有曲目,则会发生此错误:
    ERROR 1267 (HY000): Illegal mix of collations (ascii_general_ci,COERCIBLE)
    and (latin1_swedish_ci,IMPLICIT) for operation 'concat'
    
    使用曲目时,将返回结果:
    +-------------------------+
    | CONCAT(FORMAT(a, 4), b) |
    +-------------------------+
    | 1.0000b                 |
    +-------------------------+
    
  5. 具有两个或多个字符串参数的函数使用“最宽”参数表作为结果表,其中 UNICOD E比 ASCII 宽。考虑以下“CONCAT()”调用:
    CONCAT(_ucs2 X'0041', _ucs2 X'0042')
    CONCAT(_ucs2 X'0041', _ucs2 X'00C2')
    
    对于第一个调用,指令集为ASCII,因为两个参数都在 ASCII 范围内。对于第二个调用,由于第二个参数在 ASCII 范围之外,因此指令集为UNICODE。
  6. 函数返回值的库是根据仅影响结果的字符集和排序规则的那些参数的库确定的。
    IF(column1 < column2, 'smaller', 'greater')
    
    结果库为ASCII,因为两个字符串参数(第二个参数和第三个参数)都具有ASCII个库。即使 table 达式使用字符串值,第一个参数对于结果库也不重要。

UTF-8(用于元数据)