规范化MySQL查询中的重音字符

Geo*_*old 16 mysql sql utf-8 diacritics collate

我希望能够进行规范化重音字符的查询,例如:

é, è, and ê
Run Code Online (Sandbox Code Playgroud)

在使用'='和'like'的查询中,所有都被视为'e'.我有一行将用户名字段设置为' rené ',我希望能够将它与' rene '和' rené ' 匹配.

我试图用MySQL 5.0.8中的'collat​​e'子句来做这件事.我收到以下错误:

mysql> select * from User where username = 'rené' collate utf8_general_ci;
ERROR 1253 (42000): COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1'
Run Code Online (Sandbox Code Playgroud)

FWIW,我的表创建时:

CREATE TABLE `User` (
  `id` bigint(19) NOT NULL auto_increment,
  `username` varchar(32) NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `uniqueUsername` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=56790 DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)

sfu*_*ger 9

出错的原因不是表格,而是输入的字符集,即查询中的"rené".行为取决于character_set_connection变量:

用于没有字符集导入器和数字到字符串转换的文字的字符集.

使用MySQL客户端,使用SET NAMES以下命令进行更改:

SET NAMES'charset_name'语句等同于这三个语句:

SET character_set_client = charset_name;
SET character_set_results = charset_name;
SET character_set_connection = charset_name;
Run Code Online (Sandbox Code Playgroud)

(来自http://dev.mysql.com/doc/refman/5.5/en/charset-connection.html)

示例输出:

mysql> set names latin1;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from User where username = 'rené' collate utf8_general_ci;
ERROR 1253 (42000): COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1'

mysql> set names utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from User where username = 'rené' collate utf8_general_ci;
Empty set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

另外,使用可以使用'字符集介绍器'显式设置字符集:

mysql> set names latin1;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from User where username = _utf8'rené' collate utf8_general_ci;
Empty set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

我知道这个问题已经很老了但是由于谷歌带领我来这里提出相关问题,我虽然仍然值得回答:)


Tat*_*nen 7

我建议您使用真实用户名将规范化版本保存到表中.动态更改编码可能很昂贵,并且您必须在每次搜索的每一行再次进行转换.

如果您使用的是PHP,则可以使用iconv()来处理转换:

$username = 'rené';
$normalized = iconv('UTF-8', 'ASCII//TRANSLIT', $string);
Run Code Online (Sandbox Code Playgroud)

然后你只需保存两个版本并使用标准化版本进行搜索,并使用普通用户名进行显示.只要您将搜索字符串标准化,比较和选择将比标准化列快很多:

$search = mysql_real_escape_string(iconv('UTF-8', 'ASCII//TRANSLIT', $_GET['search']));
mysql_query("SELECT * FROM User WHERE normalized LIKE '%".$search."%'");
Run Code Online (Sandbox Code Playgroud)

当然,如果您有多个需要规范化的列,则此方法可能不可行,但在您的特定情况下,这可能正常工作.


Fel*_*oni 5

我在MySQL中实现了一个strtr php function/tr unix命令,你可以在这里获得源代码

您可以使用:

SELECT tr(name, 'áäèëî', 'aaeei') FROM persons
Run Code Online (Sandbox Code Playgroud)

或剥去一些角色

SELECT tr(name, 'áäèëî', null) FROM persons
Run Code Online (Sandbox Code Playgroud)