一尘不染

MySQL匹配具有ASCII版本的Unicode字符

mysql

我正在运行MySQL 5.1.50,并具有一个如下表:

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 |

我遇到的问题是MySQL正在将Unicode字符与ascii版本匹配。例如,当我搜索包含’é’的单词时,它将匹配具有’e’的单词,反之亦然:

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)

我从PHP和命令行控制台获得了这些结果。如何从SELECT查询中获得准确的匹配?

谢谢!


阅读 275

收藏
2020-05-17

共1个答案

一尘不染

您指定的nametext CHARACTER SET utf8 COLLATE utf8_unicode_ci告诉MySQL 在匹配和排序时将
eé 视为等效。这种归类和utf8_general_ci两者使很多事情都等效。

一旦您学习了如何阅读图表,http://www.collat​​ion-
charts.org/是一个很好的资源,这很容易。

如果希望将 eé 等视为不同,则必须选择其他排序规则。要找出服务器上的排序规则(假设您限于UTF-8编码):

mysql> show collation like 'utf8%';

并选择使用归类图作为参考。

还有一个特殊的排序规则utf8_bin,其中没有对等项,它是二进制匹配项。

唯一的MySQL的Unicode排序规则我所知道的是不特定语言的utf8_unicode_ciutf8_general_ciutf8_bin。他们很奇怪。排序规则的真正目的是使计算机像人们期望的那样进行匹配和排序。匈牙利语和土耳其语字典的条目根据不同的规则排序。指定排序规则后,您可以根据此类本地规则进行排序和匹配。

例如,丹麦人似乎认为e和é等效,但冰岛人则不这样做:

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

另一个方便的技巧是用一堆您感兴趣的字符填充一列表(通过脚本更容易),然后MySQL可以告诉您等效项:

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,ä,á           |
+-----------------+
2020-05-17