我有一个 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'" );
最好使用utf8_bin
因为,即使在 UTF-8 中不可能,但在一般情况下,理论上是可能的(例如 UTF-16 中发生的情况)same表示的字符串不同的编码,二进制比较无法理解,但二进制排序规则可以。正如下面记录的Unicode 字符集 http://dev.mysql.com/doc/en/charset-unicode-sets.html:
“按字符的代码值排序”和“按字符的二进制表示形式排序”之间存在差异,这种差异仅出现在utf16_bin
,因为代理人。
假设utf16_bin
(二进制排序规则utf16
)是“逐字节”而不是“逐字符”的二进制比较。如果是这样的话,字符的顺序utf16_bin
会与顺序不同utf8_bin
。例如,下图显示了两个罕见的字符。第一个字符在范围内E000-FFFF
,因此它大于替代项但小于补充项。第二个字符是补充字符。
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
图表中的两个字符按代码点值排序,因为0xff9d
< 0x10384
。它们按顺序排列utf8
值因为0xef
< 0xf0
。但它们并不是按顺序排列的utf16
值,如果我们使用逐字节比较,因为0xff
> 0xd8
.
所以MySQL的utf16_bin
排序规则不是“逐字节”。它是“按代码点”。当 MySQL 发现增补字符编码时utf16
,它转换为字符的代码点值,然后进行比较。所以,utf8_bin
and utf16_bin
是相同的顺序。这与 UCS_BASIC 排序规则的 SQL:2008 标准要求一致:“UCS_BASIC 是一种排序规则,其中排序完全由要排序的字符串中字符的 Unicode 标量值确定。它适用于 UCS 字符库。由于每个字符库都是 UCS 库的子集,因此 UCS_BASIC 排序规则可能适用于每个字符集。注 11:字符的 Unicode 标量值是被视为无符号整数的代码点。”
因此,如果涉及这些列的比较将always区分大小写,您应该将列的排序规则设置为utf8_bin
(这样即使您忘记在查询中另外指定,它们也会保持区分大小写);或者如果只有特定查询区分大小写,您可以指定utf8_bin
应该使用排序规则COLLATE
关键词:
SELECT * FROM table WHERE id = 'iSZ6fX' COLLATE utf8_bin
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)