为什么MySQL处理é与e相同?

时间:2011-08-02 23:22:15

标签: mysql unicode utf-8 character-encoding collation

我使用Django Web应用程序将Unicode字符串存储在MySQL数据库中。我可以很好地存储Unicode数据,但在查询时,我发现ée被视为同一个字符:

In [1]: User.objects.filter(last_name='Jildén')
Out[1]: [<User: Anders Jildén>]

In [2]: User.objects.filter(last_name='Jilden')
Out[2]: [<User: Anders Jildén>]

直接使用MySQL shell时也是如此:

mysql> select last_name from auth_user where last_name = 'Jildén';
+-----------+
| last_name |
+-----------+
| Jildén   |
+-----------+
1 row in set (0.00 sec)

mysql> select last_name from auth_user where last_name = 'Jilden';
+-----------+
| last_name |
+-----------+
| Jildén   |
+-----------+
1 row in set (0.01 sec)

以下是数据库字符集设置:

mysql> SHOW variables LIKE '%character_set%';
+--------------------------+------------------------------------------------------+
| Variable_name            | Value                                                |
+--------------------------+------------------------------------------------------+
| character_set_client     | latin1                                               |
| character_set_connection | latin1                                               |
| character_set_database   | utf8                                                 |
| character_set_filesystem | binary                                               |
| character_set_results    | latin1                                               |
| character_set_server     | latin1                                               |
| character_set_system     | utf8                                                 |
| character_sets_dir       | /usr/local/Cellar/mysql/5.1.54/share/mysql/charsets/ |
+--------------------------+------------------------------------------------------+

这是表格架构:

CREATE TABLE `auth_user` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(30) CHARACTER SET utf8 NOT NULL,
    `first_name` varchar(30) CHARACTER SET utf8 NOT NULL,
    `last_name` varchar(30) CHARACTER SET utf8 NOT NULL,
    `email` varchar(200) CHARACTER SET utf8 NOT NULL,
    `password` varchar(128) CHARACTER SET utf8 NOT NULL,
    `is_staff` tinyint(1) NOT NULL,
    `is_active` tinyint(1) NOT NULL,
    `is_superuser` tinyint(1) NOT NULL,
    `last_login` datetime NOT NULL,
    `date_joined` datetime NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=7952 DEFAULT CHARSET=utf8 COLLATE=utf8_bin

以下是我通过Django的DATABASES设置传递的选项:

DATABASES = {
    'default': {
        # ...
        'OPTIONS': {
            'charset': 'utf8',
            'init_command': 'SET storage_engine=INNODB;',
        },
    },
}

请注意,我已尝试将表格排序设置为utf8_bin,但不起作用:

mysql> alter table auth_user collate utf8_bin;

mysql> select last_name from auth_user where last_name = 'Jilden';
+-----------+
| last_name |
+-----------+
| Jildén   |
+-----------+
1 row in set (0.00 sec)

我如何让MySQL将它们视为不同的字符?

3 个答案:

答案 0 :(得分:9)

当你改变表格整理时,你几乎就在那里,但并不完全。在MySQL中,表中的每一列都有自己的字符集和排序规则。该表具有自己的字符集和排序规则,但这不会覆盖列排序规则;它仅确定对于未指定排序规则的新列的排序规则。因此,您没有更改您感兴趣的列的排序规则。

ALTER TABLE tablename MODIFY columnname
    varchar(???) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL

答案 1 :(得分:8)

您需要设置将变音符号视为重要的排序规则。尝试使用utf8_bin

答案 2 :(得分:1)

我认为知道桌子的字符集和你要查询的字段是很重要的。

你的问题的答案可以在这里找到 http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-sets.html

也许你要查询的字段有 utf8_general_ci 字符集。
要获得您想要的内容,您应该将该字段的字符集设置为 utf8_unicode_ci

请注意,正如手册所述, utf8_unicode_ci 字符集字段上的查询比 utf8_general_ci 字段上的查询慢