首页 文章

mysql在utf8_general_ci中区分大小写

提问于
浏览
11

我有一个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 回答

  • 1

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

    “按字符的代码值排序”和“按字符的二进制表示排序”之间存在差异,这种区别只出现在utf16_bin中,因为有代理 . 假设utf16_bin(utf16的二进制排序规则)是“逐字节”的二进制比较而不是“逐字符” . 如果是这样,utf16_bin中的字符顺序将与utf8_bin中的顺序不同 . 例如,下图显示了两个罕见的字符 . 第一个字符在E000-FFFF范围内,因此它大于代理但小于补充 . 第二个字符是补充 . 代码点字符utf8 utf16


    0FF9D HALFWIDTH KATAKANA LETTER N EF BE 9D FF 9D
    10384 UGARITIC LETTER DELTA F0 90 8E 84 D8 00 DF 84
    图表中的两个字符按代码点值排序,因为0xff9d <0x10384 . 并且它们按utf8值排序,因为0xef <0xf0 . 但是如果我们使用逐字节比较,它们不是按utf16值排序,因为0xff> 0xd8 . 所以MySQL的utf16_bin校对不是“逐字节” . 它是“按代码点” . 当MySQL在utf16中看到一个补充字符编码时,它会转换为字符的代码点值,然后进行比较 . 因此,utf8_bin和utf16_bin是相同的排序 . 这与UCS_BASIC排序规则的SQL:2008标准要求一致:“UCS_BASIC是一种排序规则,其排序完全取决于要排序的字符串中字符的Unicode标量值 . 它适用于UCS角色曲目 . 由于每个字符集都是UCS指令集的子集,因此UCS_BASIC校对可能适用于每个字符集 . 注11:字符的Unicode标量值是其代码点,被视为无符号整数 . “

    因此,如果涉及这些列的比较始终区分大小写,则应将列的排序规则设置为 utf8_bin (这样即使您忘记在查询中另行指定,它们仍将保持区分大小写);或者如果只有特定查询区分大小写,则可以指定使用 COLLATE 关键字来使用 utf8_bin 排序规则:

    SELECT * FROM table WHERE id = 'iSZ6fX' COLLATE utf8_bin
    
  • 0

    最好使用带有'utf8_bin'的列而不是在查询中指定条件,因为它可以减少出错的可能性 .

  • 13

    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
    

相关问题