2011-07-01 34 views
8

Tôi đang chạy MySQL 5.1.50 và có một bảng trông như thế này:MySQL phù hợp với các ký tự unicode với phiên bản ascii

organizations | CREATE TABLE `organizations` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, 
    `url` text CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, 
    `phone` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, 
    `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    KEY `id` (`id`) 
) ENGINE=MyISAM AUTO_INCREMENT=25837 DEFAULT CHARSET=utf8 | 

Vấn đề tôi đang gặp là MySQL là phù hợp với các ký tự unicode với các phiên bản ascii . Ví dụ khi tôi tìm kiếm một từ với điều đó chứa một 'é', nó sẽ phù hợp với cùng một từ có một 'e' thay vào đó, và ngược lại:

mysql> SET NAMES utf8; 
Query OK, 0 rows affected (0.00 sec) 

mysql> SELECT id, name FROM `organizations` WHERE `name` = 'Universite de Montreal'; 
    +-------+-------------------------+ 
| id | name     | 
+-------+-------------------------+ 
| 16973 | Université de Montreal | 
+-------+-------------------------+ 
1 row in set (0.01 sec) 

tôi nhận được những kết quả cả hai từ PHP và bảng điều khiển dòng lệnh. Làm thế nào tôi có thể nhận được kết quả chính xác từ các truy vấn SELECT của tôi?

Cảm ơn!

Trả lời

11

Bạn đã ghi rõ cột name như text CHARACTER SET utf8 COLLATE utf8_unicode_ci mà nói với MySQL để xem xét eé như tương đương phù hợp và phân loại. Đó là collation và utf8_general_ci cả hai làm cho rất nhiều thứ tương đương.

http://www.collation-charts.org/ là tài nguyên tuyệt vời khi bạn tìm hiểu cách đọc biểu đồ, điều này khá dễ dàng.

Nếu bạn muốn eé vv để được xem xét khác nhau sau đó bạn phải chọn một collation khác nhau. Để tìm hiểu những gì collations trên máy chủ của bạn (giả sử bạn đang hạn chế để mã UTF-8):

mysql> show collation like 'utf8%'; 

Và chọn sử dụng các bảng xếp hạng đối chiếu như một tài liệu tham khảo.

Một đối chiếu đặc biệt khác là utf8_bin trong đó không có sự tương đương, đó là kết quả trùng khớp nhị phân.

Chỉ các bản thu thập MySQL MySQL duy nhất mà tôi biết không phải là ngôn ngữ cụ thể là utf8_unicode_ci, utf8_general_ciutf8_bin. Họ khá kỳ lạ. Mục đích thực sự của một collation là làm cho máy tính phù hợp và sắp xếp như một người từ một nơi nào đó mong đợi. Từ điển tiếng Hung-ga-ri và Thổ Nhĩ Kỳ có các mục nhập theo thứ tự theo các quy tắc khác nhau. Chỉ định collation cho phép bạn sắp xếp và kết hợp theo các quy tắc cục bộ như vậy.

Ví dụ, có vẻ như Đan Mạch xem xét e và é tương đương nhưng Iceland không:

mysql> select _utf8'e' collate utf8_danish_ci 
    -> = _utf8'é' collate utf8_danish_ci as equal; 
+-------+ 
| equal | 
+-------+ 
|  1 | 
+-------+ 

mysql> select _utf8'e' collate utf8_icelandic_ci 
    -> = _utf8'é' collate utf8_icelandic_ci as equal; 
+-------+ 
| equal | 
+-------+ 
|  0 | 
+-------+ 

Một lừa tiện dụng là để điền vào một bảng một cột với một loạt các ký tự mà bạn đang quan tâm đến (đó là dễ dàng hơn từ một kịch bản) và sau đó MySQL có thể cho bạn biết equivalencies:

mysql> create table t (c char(1) character set utf8); 
mysql> insert into t values ('a'), ('ä'), ('á'); 
mysql> select group_concat(c) from t group by c collate utf8_icelandic_ci; 
+-----------------+ 
| group_concat(c) | 
+-----------------+ 
| a    | 
| á    | 
| ä    | 
+-----------------+ 

mysql> select group_concat(c) from t group by c collate utf8_danish_ci; 
+-----------------+ 
| group_concat(c) | 
+-----------------+ 
| a,á    | 
| ä    | 
+-----------------+ 

mysql> select group_concat(c) from t group by c collate utf8_general_ci; 
+-----------------+ 
| group_concat(c) | 
+-----------------+ 
| a,ä,á   | 
+-----------------+ 
+0

Cảm ơn rất nhiều vì đã trả lời kỹ lưỡng! – user825466

+0

Wow !!! Bạn đã giải thích rõ ràng! Cám ơn rất nhiều. –

1

Bạn đã đặt đối chiếu thành utf8_unicode_ci tương đương với các ký tự latin có dấu. Thông tin bổ sung có thể được tìm thấy here.

+0

user825466 đã thiết lập 'đối chiếu utf8_unicode_ci' và đây là lý do tại sao MySQL trả về trận đấu như một trong những ví dụ mà ông hay cô không muốn. –

+0

@fsb - Vâng, tôi đã giải thích cho người viết câu hỏi * tại sao * họ đã nhìn thấy sự đối chiếu. Tôi đọc câu hỏi là họ không biết thực tế. – borrible

+0

Cả hai đều đúng - tôi không biết tại sao, và tôi cũng không muốn điều đó xảy ra. Tôi đã kết thúc viết mã xung quanh nó với PHP, nhưng nếu nhu cầu phát sinh trong tương lai tôi sẽ chỉ định collation trong câu lệnh SELECT. Cảm ơn. – user825466

1

có một điều bạn có thể làm với chuỗi truy vấn của bạn là để giải mã nó ...

< ?php 
$query="उनकी"; // some Unicode characters 
$query=urldecode($query); 
$qry= "SELECT * FROM table WHERE books LIKE '%$query%'"; 

//rest of the code.... 
?> 

nó làm việc cho tôi.:)

0

tôi phát hiện ra, rằng bạn sẽ có được kết quả yêu cầu sử dụng REGEXP

SELECT * FROM table WHERE name REGEXP 'namé'; 

Nhưng điều này không giúp đỡ nếu bạn cố gắng nhóm chính xác theo tên.

4

Tất nhiên, điều này sẽ làm việc:

SELECT * FROM table WHERE name LIKE BINARY 'namé'; 
+0

Tôi đã thử tất cả các loại biến thể đối chiếu và '% º%' (chỉ số thứ tự, không phải biểu tượng độ) giữ được những thứ không phù hợp. Thấy điều này và thử nó và nó hoạt động như một sự quyến rũ. Cảm ơn! – RobinHood70

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