这是一个奇怪的难题,AFAIK utf8_bin应该保证每个重音都正确地存储在数据库中,即没有奇怪的转换为ASCII。所以我有这样的表:
DEFAULT CHARSET=utf8 COLLATE=utf8_bin
然而当我尝试比较/查询/根据MySQL的“Krąków”和“Kraków”这样的条目时,这是相同的字符串。
出于好奇,我也尝试了utf8_polish,并且MySQL声称对于波兰人来说“a”和“ą”没有任何区别。
那么如何设置MySQL表,这样我就可以安全地存储unicode字符串,而不会丢失重音等等?
服务器:MySQL 5.5 + openSUSE 11.4,客户端:Windows 7 + MySQL Workbench 5.2。
CREATE TABLE `Cities` (
`city_Name` VARCHAR(145) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`city_Name`)
) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
请注意,我无法为列设置不同的 utf8_bin,因为整个表格是utf8_bin,因此实际上列的排序规则会重置为默认值。
答案 0 :(得分:2)
解决方案的所有学分都归 bobince 所示,所以请在我的问题上投票。
这个问题的解决方案有些奇怪,我冒这么说的风险说MySQL已经破了。
所以,我们说我用utf8创建了一个表,并没有为列做任何事情。后来我意识到我需要严格比较字符,所以我将表和列的排序规则更改为utf8_bin。解决了吗?
不,现在MySQL看到了 - 表确实是utf8_bin,但是列也是utf8_bin,这意味着列使用表的DEFAULT排序规则。但是,MySQL没有意识到先前的默认值与当前默认值不同。因此,比较仍然不起作用。
因此,您必须摆脱列的默认值,以及超出排序范围的某些外来价值"家庭" (如果是" utf8xxx"表示没有其他" utf8xxx")。一旦它被甩掉,你就会看到没有说"默认"在列排序规则中,您可以设置utf8_bin,现在评估为默认值,但由于我们来自非默认排序规则,所有内容都会按预期启动。
不要忘记在每一步都应用更改。
答案 1 :(得分:0)
MySQL默认字符集和排序规则(在服务器范围内,但每个连接可以更改)适用于创建表时。创建表后更改默认值不会影响现有表。
字符集和排序规则是各列的属性。它们可以从表格范围的默认设置,但它们属于列。
utf8的字符集应足以允许所有欧洲语言正确表示。你绝对应该能够将“a”和“±”存储为两个不同的字符。
utf8-bin的排序规则会产生一个案例和带重音字符的敏感排序规则。
以下是文本值和归类行为之间差异的一些示例。我正在使用三个示例字符串:'abcd','ĄBCD'和'ąbcd'。最后两个有A-ogonek信。
第一个例子说,使用utf8字符表示和utf8_general_ci排序规则,三个字符串每个都按用户指定显示,但它们比较相等。这是在不区分a和±的整理中预期的。这是一种典型的不区分大小写的排序规则,其中所有变体字符的排序等于没有任何变音标记的字符。
SET NAMES 'utf8' COLLATE 'utf8_general_ci';
SELECT 'abcd', 'ąbcd' , 'abcd' < 'ąbcd', 'abcd' = 'ąbcd';
false true
下一个例子表明,在不区分大小写的波兰语排序规则中,a出现在±之前。我不懂波兰语,但我怀疑波兰语电话簿中的As和Ą是分开的。
SET NAMES 'utf8' COLLATE 'utf8_polish_ci';
SELECT 'abcd', 'ĄBCD' , 'ąbcd', 'abcd' < 'ĄBCD', 'abcd' < 'ąbcd' , 'ąbcd' = 'ĄBCD'
true true true
下一个示例显示了utf8_bin排序规则会发生什么。
SET NAMES 'utf8' COLLATE 'utf8_bin';
SELECT 'abcd', 'ĄBCD' , 'ąbcd', 'abcd' < 'ĄBCD', 'abcd' < 'ąbcd' , 'ąbcd' = 'ĄBCD'
true true false
在这种情况下,有一个非直观的事情需要注意。 'abcd'&lt; 'ĄBCD'为真(而'abcd'&lt;'带有纯ASCII的ABCD'为假)。如果你在语言上思考,这是一个奇怪的结果。这是因为两个A-ogonek字符在utf8中都具有高于所有abc和ABC字符的二进制值。所以:如果你对ORDER BY操作使用utf8-bin校对,你会得到语言上奇怪的结果。
你说'Krąków'和'Kraków'比较平等,你对此感到困惑。当使用的排序规则是utf8_general_ci时,它们做比较相等。但他们没有使用utf8_bin或utf8_polish_ci。根据MySQL中的波兰语支持,这两个城市名称的拼写是不同的。
在设计应用程序时,您需要弄清楚您希望所有这些在语言上如何工作。 'Krąków'和'Kraków'是同一个地方吗? 'Ąaron'和'Aaron'是同一个人吗?如果是这样,你想要utf8_general_ci。
您可以考虑更改您显示的表格,如下所示:
ALTER TABLE Cities
MODIFY COLUMN city_Name
VARCHAR(145)
CHARACTER SET utf8
COLLATE utf8_general_ci
这将按照您希望的方式设置表格中的列。