阿波罗的战车
更改字符串的一个(或两者)的排序规则以使它们匹配,或者添加一个COLLATE从句到你的表情。这“校对”到底是什么?如下文所述字符集和排序规则:A 字符集是一组符号和编码。一个校对用于比较字符集中字符的一组规则。让我们用一个假想字符集的例子来明确区分。假设我们有一个有四个字母的字母表:“A”, “B”, “a”, “b“我们给每个字母一个数字:“A” = 0, “B” = 1, “a” = 2, “b“=3.信”A“是一个符号,数字0是编码为“A“,这四个字母及其编码的组合是字符集.假设我们要比较两个字符串值,“A“和”B“最简单的方法是查看编码:0表示“A“和1代表”B“因为0小于1,我们说“A“小于”B“我们刚才做的是对我们的字符集进行排序。排序规则是一组规则(在本例中只有一条规则):“比较编码”。我们称之为最简单的排序规则双星校对。但是如果我们想说小写字母和大写字母是等价的呢?那么我们至少有两个规则:(1)处理小写字母“a“和”b“相当于”A“和”B“;(2)然后比较编码。我们称之为a不区分大小写校对。它比二进制排序要复杂一些。在现实生活中,大多数字符集都有许多字符:不仅仅是“A“和”B“但是整个字母,有时是多重字母或东方文字系统,有数千个字符,还有许多特殊的符号和标点符号。在现实生活中,大多数校对都有许多规则,不仅是关于是否区分字母,还包括是否区分口音(“重音”是一个附加在一个字符上的标记,就像在德语中那样)。Ö),以及多字符映射(例如“Ö” = “OE“在两个德国校勘中的一个)。下面给出了进一步的例子校对效果实例.好的,但是MySQL如何决定对给定表达式使用哪种排序规则呢?如下文所述表达的校对:在大多数语句中,很明显MySQL使用什么排序规则来解决比较操作。例如,在以下情况下,应该清楚地看到,排序规则是列的排序规则。charset_name:SELECT x FROM T ORDER BY x;SELECT x FROM T WHERE x = x;SELECT DISTINCT x FROM T;但是,对于多个操作数,可能存在歧义。例如:SELECT x FROM T WHERE x = 'Y';比较是否使用列的排序规则?x,或者字符串文字。'Y'?双管齐下x和'Y'有排序,那么哪个排序优先?标准SQL使用以前称为“矫顽力”的规则来解决这些问题。[ deletia ]MySQL使用具有以下规则的矫顽力值来解决歧义:如果双方都是Unicode,或者双方都不是Unicode,则这是一个错误。如果其中一方具有Unicode字符集,另一方具有非Unicode字符集,则具有Unicode字符集的侧获胜,并将自动字符集转换应用于非Unicode侧。例如,以下语句不返回错误:SELECT CONCAT(utf8_column, latin1_column) FROM t1;它返回一个结果,该结果的字符集为utf8和同样的校对utf8_column..值.的值latin1_column自动转换为utf8在连接之前。对于操作数来自同一字符集的操作数的操作,但该操作混合了_bin校对和_ci或_cs校对_bin使用校对。这类似于混合非二进制字符串和二进制字符串的操作如何将操作数计算为二进制字符串,只是用于排序规则而不是数据类型。使用矫顽力最低的排序规则。如果双方具有相同的矫顽力,那么:那么,什么是“非法拼贴”呢?当表达式比较两个字符串的不同排序规则(但具有相同的矫顽力)和矫顽力规则无法帮助解决冲突时,就会出现“排序规则的非法组合”。这是在上述报价的第三个要点下所描述的情况.问题中给出的特别错误,Illegal mix of collations (latin1_general_cs,IMPLICIT) and (latin1_general_ci,IMPLICIT) for operation '=',告诉我们,两个具有相同矫顽力的非Unicode字符串之间有一个相等的比较。它还告诉我们,排序规则不是在语句中显式地给出的,而是从字符串的源(例如列元数据)中隐含的。这一切都很好,但是如何解决这些错误呢?正如上面引用的手册摘要所表明的那样,这个问题可以通过多种方式解决,其中有两种是明智的,建议如下:如果仅为解决这一错误而部署其他人,则其他的做法将是非常糟糕的:强制字符串中的一个(或两者)具有其他的矫顽力值,以便优先。使用CONCAT()或CONCAT_WS()将导致字符串的矫顽力为1;(如果在存储的例程中)使用参数/局部变量将导致字符串的矫顽力为2。更改字符串的一个(或两者)的编码,以便一个是Unicode,另一个不是。这可以通过将代码转换为CONVERT(expr USING transcoding_name);或通过更改数据的基本字符集(例如修改列、更改character_set_connection用于文字值,或以不同的编码和更改从客户端发送它们。character_set_client/添加字符集介绍器)。请注意,如果无法在新字符集中编码某些所需字符,则更改编码将导致其他问题。更改字符串的一个(或两者)的编码,使它们都相同,并将一个字符串更改为使用相关的_bin校对。以上详细介绍了更改编码和排序规则的方法。如果实际需要应用比_bin校对。明示COLLATE子句的矫顽力为0。(一点也不能矫顽力)具有不同排序规则的两个字符串的连接具有1的矫顽力。列的排序规则、存储的例程参数或局部变量的矫顽力为2。“系统常量”(由函数返回的字符串,如USER()或VERSION())矫顽力为3。文字的排序规则具有4的矫顽力。NULL或派生自NULL矫顽力为5。更改一个字符串(或两个字符串)的排序规则,以便它们匹配,并且不再有任何歧义。如何做到这一点取决于字符串的来源:文字表达式采用collation_connection表的值采用列元数据中指定的排序规则。强迫一条字符串不可强制。我省略了以下引述:MySQL分配矫顽力值如下:因此,只需添加一个COLLATE子句到比较中使用的字符串之一将强制使用该排序规则。