2011-08-02 33 views
8

Tôi đang lưu trữ các chuỗi Unicode trong cơ sở dữ liệu MySQL bằng một ứng dụng web Django. Tôi có thể lưu trữ dữ liệu Unicode tốt, nhưng khi truy vấn, tôi thấy rằng ée được đối xử như thể họ là những nhân vật giống nhau:Tại sao MySQL xử lý é giống như 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>] 

Đây cũng là trường hợp khi sử dụng MySQL shell trực tiếp:

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) 

Dưới đây là các thiết lập cơ sở dữ liệu charset:

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/ | 
+--------------------------+------------------------------------------------------+ 

đây là sơ đồ bảng:

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 

và đây là những tùy chọn Tôi đang đi qua qua DATABASES thiết lập của Django:

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

Lưu ý rằng tôi đã cố gắng thiết lập collation bảng để utf8_bin, không có hiệu lực:

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) 

Làm thế nào tôi có thể nhận được MySQL để điều trị những nhân vật khác nhau?

+0

Vui lòng đăng đầu ra của 'SHOW CREATE TABLE tablename', trong đó' tablename' là tên của bảng chứa cột có liên quan . – Hammerite

+0

Tôi đã chỉnh sửa câu hỏi để đưa vào lược đồ bảng. Cảm ơn. – claymation

Trả lời

9

Bạn đã ở gần đó khi bạn thay đổi bảng đối chiếu, nhưng không hoàn toàn. Trong MySQL, mỗi cột trong một bảng có bộ ký tự và collation riêng. Bảng này có bộ ký tự và collation riêng của nó, nhưng điều này không ghi đè các collations cột; nó chỉ xác định những gì collation sẽ được cho các cột mới được thêm vào mà bạn không chỉ định collation. Vì vậy, bạn chưa thay đổi collation của cột mà bạn quan tâm.

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

Bạn cần đặt một đối chiếu xử lý dấu phụ là quan trọng. Hãy thử sử dụng utf8_bin

+0

Tôi đã thử đặt bảng đối chiếu thành '' utf8_bin'', nhưng điều đó dường như không giúp ích gì. Có cái gì khác tôi cần phải làm khác hơn: '' ALTER TABLE auth_user COLLATE utf8_bin''? – claymation

+2

@claymation: 'ALTER TABLE… COLLATE' là thực tế' ALTER TABLE… DEFAULT COLLATE' sẽ chỉ ảnh hưởng đến các cột mới được thêm vào. Bạn cần chạy 'ALTER TABLE auth_user CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin'. – Quassnoi

1

Tôi nghĩ rằng điều quan trọng là phải biết bảng mã của bảng và trường bạn đang truy vấn.

Câu trả lời cho câu hỏi của bạn có thể được tìm thấy ở đây
http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-sets.html

Có lẽ lĩnh vực bạn đang truy vấn có utf8_general_ci charset.
Để có được những gì bạn muốn, bạn nên thiết lập charset của lĩnh vực đó như utf8_unicode_ci

Hãy nhớ rằng, như hướng dẫn nói, các truy vấn trên utf8_unicode_ci lĩnh vực charset là chậm hơn so với các truy vấn trên utf8_general_ci lĩnh vực

Các vấn đề liên quan