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排在ą之前。我不懂波兰语,但我猜波兰电话簿会把A和Ą分开。
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' < 'ĄBCD' 是true(而'abcd'与纯ASCII的'ABCD'是false)。如果您从语言学的角度考虑,那么这是一个奇怪的结果。这是因为两个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
这将按照您的要求设置表中的列。
utf8_bin
排序规则来进行重音和大小写敏感的比较,可以将其作为表格的排序规则或在比较时使用COLLATE utf8_bin;
。我不确定这是否是该问题的最终解决方案,或者是否有国家特定的排序规则是重音敏感的,但这是所有答案都建议的方法。 - Pekkacolumnname VARCHAR(100) CHARSET utf8 COLLATE utf8_bin NOT NULL
。DEFAULT
设置是在创建时确定的,但在列已经创建后更改设置不会起作用。使用SHOW CREATE TABLE tablename
命令查看现有列的字符集和排序规则。 - bobince