文档首页
MySQL 8.4 参考手册
8.4 中文镜像

MySQL 8.4 参考手册 · 中文镜像

正文为中文,英文原文默认隐藏。点击任意中文段落即可展开 / 收起对应英文原文。

打开官方英文原文 ↗

译文由机器翻译生成,仅供理解参考;有疑问请以官方英文原文为准。

中文点击中文段落可显示 / 隐藏英文原文本页译文覆盖 91%

12.8.4 表达式中的排序规则可强制性12.8.4 Collation Coercibility in Expressions

在绝大多数语句中,很明显 MySQL 使用哪种排序规则来解决比较操作。例如,在以下情况下,应该清楚比较使用的排序规则是列 x 的排序规则:In the great majority of statements, it is obvious what collation MySQL uses to resolve a comparison operation. For example, in the following cases, it should be clear that the collation is the collation of column x:

SELECT x FROM T ORDER BY x;
SELECT x FROM T WHERE x = x;
SELECT DISTINCT x FROM T;

然而,对于多个操作数,可能会产生歧义。例如,该语句执行列 x 与字符串字面值 'Y' 之间的比较:However, with multiple operands, there can be ambiguity. For example, this statement performs a comparison between the column x and the string literal 'Y':

SELECT x FROM T WHERE x = 'Y';

如果 x 和 'Y' 具有相同的排序规则,则比较使用的排序规则不会有歧义。但如果它们具有不同的排序规则,比较应使用 x 的排序规则,还是 'Y' 的排序规则?x 和 'Y' 都有排序规则,那么哪一个排序规则优先?If x and 'Y' have the same collation, there is no ambiguity about the collation to use for the comparison. But if they have different collations, should the comparison use the collation of x, or of 'Y'? Both x and 'Y' have collations, so which collation takes precedence?

在比较之外的上下文中,也可能出现多种排序规则的混合。例如,多参数拼接操作,如 CONCAT(x,'Y'),将其参数组合以生成一个字符串。结果应该使用哪种排序规则?A mix of collations may also occur in contexts other than comparison. For example, a multiple-argument concatenation operation such as CONCAT(x,'Y') combines its arguments to produce a single string. What collation should the result have?

为了回答像这样的问题,MySQL 会检查一个项目的排序规则是否可以强制转换为另一个项目的排序规则。MySQL 按照以下方式分配强制性值:To resolve questions like these, MySQL checks whether the collation of one item can be coerced to the collation of the other. MySQL assigns coercibility values as follows:

  • 显式的 COLLATE 子句具有 0 的强制性(完全不可强制)。An explicit COLLATE clause has a coercibility of 0 (not coercible at all).

  • 两个具有不同排序规则的字符串的连接具有强制性 1。The concatenation of two strings with different collations has a coercibility of 1.

  • 列或存储过程参数或本地变量的排序规则具有强制性 2。The collation of a column or a stored routine parameter or local variable has a coercibility of 2.

  • 一个 “系统常量”(由诸如 USER() 或 VERSION() 等函数返回的字符串)具有 3 的可强制性。A “system constant” (the string returned by functions such as USER() or VERSION()) has a coercibility of 3.

  • 字面值的排序规则的强制性为 4。The collation of a literal has a coercibility of 4.

  • 数值或时间值的排序规则的强制性为 5。The collation of a numeric or temporal value has a coercibility of 5.

  • NULL 或者从 NULL 派生的表达式的强制性为 6。NULL or an expression that is derived from NULL has a coercibility of 6.

MySQL 使用可强制性值通过以下规则来解决歧义:MySQL uses coercibility values with the following rules to resolve ambiguities:

  • 使用具有最低可强制性值的排序规则。Use the collation with the lowest coercibility value.

  • 如果双方具有相同的可强制性值,则:If both sides have the same coercibility, then:

    • 如果双方都是 Unicode,或者双方都不是 Unicode,则会出错。If both sides are Unicode, or both sides are not Unicode, it is an error.

    • 如果一方是 Unicode 字符集,而另一方是非 Unicode 字符集,则 Unicode 字符集的一方胜出,并对非 Unicode 一方进行自动字符集转换。例如,以下语句不会返回错误:If one of the sides has a Unicode character set, and another side has a non-Unicode character set, the side with Unicode character set wins, and automatic character set conversion is applied to the non-Unicode side. For example, the following statement does not return an error:

      SELECT CONCAT(utf8mb4_column, latin1_column) FROM t1;
      

      它返回一个结果,其字符集为utf8mb4,并且使用与utf8mb4_column相同的校对规则。在连接之前,latin1_column的值会自动转换为utf8mb4。It returns a result that has a character set of utf8mb4 and the same collation as utf8mb4_column. Values of latin1_column are automatically converted to utf8mb4 before concatenating.

    • 对于操作数来自相同字符集但混合使用_bin校对规则和_ci或_cs校对规则的操作,将使用_bin校对规则。这类似于混合非二进制和二进制字符串的操作将操作数作为二进制字符串进行计算的方式,只不过是应用于校对规则而不是数据类型。For an operation with operands from the same character set but that mix a _bin collation and a _ci or _cs collation, the _bin collation is used. This is similar to how operations that mix nonbinary and binary strings evaluate the operands as binary strings, applied to collations rather than data types.

虽然自动转换不属于 SQL 标准,但标准确实指出每个字符集(就支持的字符而言)都是 Unicode 的“子集”。因为众所周知的原则是“适用于超集的原则也适用于子集,”我们认为 Unicode 的排序规则可以用于非 Unicode 字符串的比较。更一般地说,MySQL 使用字符集规格的概念,这有时可以用于确定字符集之间的子集关系,并启用对在其他情况下会产生错误的操作数进行转换。参见 第 12.2.1 节,“字符集规格”。Although automatic conversion is not in the SQL standard, the standard does say that every character set is (in terms of supported characters) a “subset” of Unicode. Because it is a well-known principle that “what applies to a superset can apply to a subset,” we believe that a collation for Unicode can apply for comparisons with non-Unicode strings. More generally, MySQL uses the concept of character set repertoire, which can sometimes be used to determine subset relationships among character sets and enable conversion of operands in operations that would otherwise produce an error. See Section 12.2.1, “Character Set Repertoire”.

下表说明了前述规则的一些应用。The following table illustrates some applications of the preceding rules.

比较Comparison 使用的排序规则Collation Used
column1 = 'A' 使用 column1 的排序规则Use collation of column1
column1 = 'A' COLLATE x 使用 'A' COLLATE x 的排序规则Use collation of 'A' COLLATE x
column1 COLLATE x = 'A' COLLATE y 错误Error

要确定字符串表达式的强制级别,请使用 COERCIBILITY() 函数(参见 第 14.15 节,“信息函数”):To determine the coercibility of a string expression, use the COERCIBILITY() function (see Section 14.15, “Information Functions”):

mysql> SELECT COERCIBILITY(_utf8mb4'A' COLLATE utf8mb4_bin);
        -> 0
mysql> SELECT COERCIBILITY(VERSION());
        -> 3
mysql> SELECT COERCIBILITY('A');
        -> 4
mysql> SELECT COERCIBILITY(1000);
        -> 5
mysql> SELECT COERCIBILITY(NULL);
        -> 6

对于将数值或时间值隐式转换为字符串的情况,例如在表达式 CONCAT(1, 'abc') 中的参数 1,结果是一个字符(非二进制)字符串,其字符集和排序规则由 character_set_connection 和 collation_connection 系统变量确定。参见 第 14.3 节,“表达式评估中的类型转换”。For implicit conversion of a numeric or temporal value to a string, such as occurs for the argument 1 in the expression CONCAT(1, 'abc'), the result is a character (nonbinary) string that has a character set and collation determined by the character_set_connection and collation_connection system variables. See Section 14.3, “Type Conversion in Expression Evaluation”.