mysql在utf8_general_ci中区分大小写

时间:2013-09-11 09:44:44

标签: php mysql binary collation

我有一个mysql数据库,其中我使用utf8_general_ci(不区分大小写),在我的表中我有一些像ID这样的列与区分大小写的数据(例如:'iSZ6fX'或'AscSc2')

要从小写字母区分大写,最好只在这些列上设置utf8_bin,如下所示:

CREATE TABLE  `test` (
`id` VARCHAR( 32 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL ,
`value1` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci

或者在所有列上使用utf8_general_ci并在php查询中使用“BINARY”,例如:

mysqli_query( $link, "SELECT * FROM table WHERE BINARY id = 'iSZ6fX'" );

3 个答案:

答案 0 :(得分:14)

最好使用utf8_bin归类,因为即使在UTF-8中不可能,在一般情况下理论上可能(例如UTF-16发生)相同的字符串由不同的编码表示,二进制比较不理解,但二进制校对会。正如Unicode Character Sets所述:

  

“按字符的代码值排序”和“按字符的二进制表示排序”之间存在差异,这种区别只出现utf16_bin,因为有代理。

     

假设utf16_binutf16的二进制排序规则)是“逐字节”的二进制比较,而不是“逐个字符”。如果是这样,则utf16_bin中的字符顺序为utf8_bin 1}}与E000-FFFF中的顺序不同。例如,下图显示了两个罕见的字符。第一个字符在0xff9d范围内,因此它大于代理但小于补充。第二个字符是补充。

Code point  Character                    utf8         utf16
----------  ---------                    ----         -----
0FF9D       HALFWIDTH KATAKANA LETTER N  EF BE 9D     FF 9D
10384       UGARITIC LETTER DELTA        F0 90 8E 84  D8 00 DF 84
     

图表中的两个字符按代码点值排序,因为0x10384< utf8。它们按0xef值排序,因为0xf0< utf16。但是,如果我们使用逐字节比较,它们不会按0xff值排序,因为0xd8> utf16_bin

     

所以MySQL的utf16校对不是“逐字节”。它是“按代码点”。当MySQL在utf8_bin中看到一个补充字符编码时,它会转换为字符的代码点值,然后比较。因此,utf16_binutf8_bin排序相同。这与UCS_BASIC排序规则的SQL:2008标准要求一致:“UCS_BASIC是一种排序规则,其排序完全取决于要排序的字符串中字符的Unicode标量值。它适用于UCS角色曲目。由于每个字符集都是UCS指令集的子集,因此UCS_BASIC校对可能适用于每个字符集。注11:字符的Unicode标量值是其代码点,被视为无符号整数。“

因此,如果涉及这些列的比较总是区分大小写,则应将列的排序规则设置为utf8_bin(这样即使您忘记指定它们也会保持区分大小写否则在你的查询中);或者,如果只有特定查询区分大小写,您可以指定使用COLLATE关键字来使用SELECT * FROM table WHERE id = 'iSZ6fX' COLLATE utf8_bin 排序规则:

{{1}}

答案 1 :(得分:1)

最好使用带有&utff8_bin'的列。而不是在查询中指定条件,因为它减少了错误的可能性。

答案 2 :(得分:0)

BINARY作为列属性的效果与MySQL 4.1之前的效果不同。以前,BINARY导致一个被视为二进制字符串的列。二进制字符串是一个没有字符集或排序规则的字节字符串,它与具有二进制排序规则的非二进制字符串不同。

但是现在

BINARY运算符将其后面的字符串转换为二进制字符串。这是一种简单的方法,可以逐个字节而不是逐个字符地强制进行比较。 BINARY也会导致尾随空格很重要。 BINARY str是CAST的简写(str AS BINARY)。

字符列定义中的BINARY属性具有不同的效果。使用BINARY属性定义的字符列将分配列字符集的二进制排序规则。每个字符集都有一个二进制排序规则。例如,latin1字符集的二进制排序规则是latin1_bin,因此如果表默认字符集是latin1,则这两个列定义是等效的:

CHAR(10) BINARY

CHAR(10) CHARACTER SET latin1 COLLATE latin1_bin