我在“utf8 - UTF-8 Unicode”中有一个模式作为charset和“utf8_spanish_ci”的整理。
所有内部表都是InnoDB,具有与上述相同的字符集和排序规则。
问题出现了:
使用类似
的查询SELECT *
FROM people p
WHERE p.NAME LIKE '%jose%';
我得到83个结果行。我应该有84个结果,因为我知道。
更改位置:
WHERE p.NAME LIKE '%JOSE%';
我得到完全相同的83行。 使用JoSe,Jose,JOSe等组合。报告所有相同的83行。
问题来自游戏中的重音。如果:
WHERE p.NAME LIKE '%josé%';
我没有结果。 0行。
但如果我这样做:
WHERE p.NAME LIKE '%JOSÉ%';
我得到一行结果,所以1行。这是唯一一个以“jose”和“大写”重音的行。
我尝试过使用josÉ,或JoSÉ或我做的任何组合,只要重音符号保持大写或不大写,因为它确实存储在数据库中并且仍然返回唯一的行。如果我用JOSE中的大写字母组合突然改变“é”为“é”,它将不返回任何行。
所以结论:
我想要什么?
COLLATION
上的LIKE
等解决方案对我不起作用,不知道为什么......
我该怎么办?
提前致谢!
修改
如果我喜欢这样的话:
WHERE p.NAME LIKE '%jose%' COLLATE utf8_general_ci;
我收到错误:
COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1'
我也改变了列上所有可能的排序规则!
如果我这样做:
WHERE p.NAME LIKE _utf8 '%jose%' COLLATE utf8_general_ci;
报告了相同的83行,好像我什么都没做......
答案 0 :(得分:11)
您已尝试对搜索和排序使用不区分重音的排序规则。
http://dev.mysql.com/doc/refman/5.0/en/charset-collation-implementations.html
问题是,您的NAME
列似乎存储在latin1(8位)字符集中。这就是mySQL对你抱怨的原因:
COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1'
如果您尝试
,您可能会得到所需的结果 WHERE CONVERT(p.NAME USING utf8) LIKE _utf8 '%jose%' COLLATE utf8_general_ci;
但是,要小心!
当您在WHERE语句中的列上使用任何类型的函数(在此示例中为CONVERT)时,您将失败MySQL尝试使用索引优化搜索。如果这个项目变得很大(也就是说,如果你的表中有很多行),你需要以utf8格式存储数据,而不是latin1。 (您可能已经知道,您的LIKE '%whatever%'
搜索词也会破坏MySQL的索引。)
答案 1 :(得分:8)
万一其他人偶然发现了这个问题,我找到了解决问题的方法,至少对我而言。
我正在使用PHP从数据库中插入和检索记录。即使我的数据库,表和列是utf8,以及PHP文件的编码,事实是PHP和MySQL之间的连接中使用的编码是使用latin1进行的。我设法使用
找到了这个$mysqli->character_set_name();
其中$mysqli
是您的对象。
为了使搜索按预期开始工作,为带有重音符号的字符返回重音不敏感和大小写的句子记录,我必须明确设置连接的字符集。
为此,您只需执行以下操作:
$mysqli->set_charset('utf8');
其中$ mysqli是你的mysqli对象。如果您有一个包装数据库功能的数据库管理类,这很容易应用于完整的应用程序。如果没有,您必须在打开连接的任何地方明确设置它。
我希望这可以帮助别人,因为我已经对此感到害怕!