再谈关于mysql中文模糊查找问题!

许多朋友在使用mysql进行中文模糊查找时(如select * from mytable where mysqlname like "%中文%"),就象我现在一样,找到不应找到的行!
有一些朋友提出了解决办法,大致有两种:
其一,加字段属性binary(),
其二,改my.cfg启动参数为default-character-set =gbk(或gb2312).
我从问题的根本原因分析,
其一,字母大小不区分问题(通过方法一可以解决)
其二,这是大多数人没有想到的,我以前也没有想到,
例:
汉字“不”的第1、2字节ascii值分别为:178与187
汉字“安”的第1、2字节ascii值分别为:176与178
汉字“花”的第1、2字节ascii值分别为:187与168
聪明的人已经看出来了:在字符串“安花”中模糊查找字符“不”字时,mysql系统也会认为两者区配!
我的mysql-4.0.12没有解决上述问题。不过我采用一个较笨的办法解决了!
针对以上问题,各位高手有何解决办法!!!一起来说一说!
(提出办法者可得100分)

---------------------------------------------------------------

1: my.ini 文件中加入 default-character-set =gb2312
2: 字段不要加 Binary 属性
3: 执行 select * from mytable where mysqlname like "%不%"
---------------------------------------------------------------

需要说明的是
1:
2:
是最重要的,

如果是查询汉字,
select * from mytable where mysqlname like "%不%"

如果是大小字区分查询英文字符,
select * from mytable where mysqlname like Binary("%A%")

如果上述条件均要
select * from mytable where mysqlname like "%不%" AND mysqlname like Binary("%A%")

不过像这类情况,
已不再建议使用 LIKE '%a%' 形式了
建议使用 全文索引 与 正则表达式 来匹配字串

---------------------------------------------------------------

CREATE TABLE t3 (
name char(9) NOT NULL default ''
) TYPE=MyISAM;

Dumping data for table 't3'

INSERT INTO t3 (name) VALUES("安花");
INSERT INTO t3 (name) VALUES("不1a");
INSERT INTO t3 (name) VALUES("安花a");
INSERT INTO t3 (name) VALUES("1安花A");
INSERT INTO t3 (name) VALUES("1安花1");
INSERT INTO t3 (name) VALUES("A");
INSERT INTO t3 (name) VALUES("1A1");

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16 to server version: 4.0.12-nt-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> use test;
Database changed
mysql> SHOW VARIABLES LIKE 'character_set';
+---------------+--------+
¦ Variable_name ¦ Value ¦
+---------------+--------+
¦ character_set ¦ gb2312 ¦
+---------------+--------+
1 row in set (0.00 sec)

mysql> SELECT * FROM t3;
+--------+
¦ name ¦
+--------+
¦ 安花 ¦
¦ 不1a ¦
¦ 安花a ¦
¦ 1安花A ¦
¦ 1安花1 ¦
¦ A ¦
¦ 1A1 ¦
+--------+
7 rows in set (0.00 sec)

mysql> SELECT * FROM t3 WHERE name LIKE "%不%";
+------+
¦ name ¦
+------+
¦ 不1a ¦
+------+
1 row in set (0.00 sec)

mysql>
---------------------------------------------------------------

不过像这类情况,
已不再建议使用 LIKE '%a%' 形式了
建议使用 全文索引 与 正则表达式 来匹配字串

当你使用 LIKE '%a%' 形式时,
这个查询将不能使用该字段上的索引,
所以这个查询将耗费很大的时间,
所以建议使用 全文索引
---------------------------------------------------------------

MySQL-Front Dump 2.5

Host: localhost Database: test

--------------------------------------------------------

Server version 4.0.12-nt-log

Table structure for table 't3'

CREATE TABLE t3 (
name char(12) NOT NULL default '',
name2 char(12) NOT NULL default '',
FULLTEXT KEY name (name,name2)
) TYPE=MyISAM;

Dumping data for table 't3'

INSERT INTO t3 (name, name2) VALUES("1", "安换岚缮");
INSERT INTO t3 (name, name2) VALUES("2", "不会吧");
INSERT INTO t3 (name, name2) VALUES("3", "不会吧1");
INSERT INTO t3 (name, name2) VALUES("4", "不会吧 1");
INSERT INTO t3 (name, name2) VALUES("5", "真的不会吧");
INSERT INTO t3 (name, name2) VALUES("6", "真的 不会吧");

mysql> SELECT * FROM t3;
+------+-------------+
¦ name ¦ name2 ¦
+------+-------------+
¦ 1 ¦ 安换岚缮 ¦
¦ 2 ¦ 不会吧 ¦
¦ 3 ¦ 不会吧1 ¦
¦ 4 ¦ 不会吧 1 ¦
¦ 5 ¦ 真的不会吧 ¦
¦ 6 ¦ 真的 不会吧 ¦
+------+-------------+
6 rows in set (0.01 sec)

查找词 "不会吧"

mysql> SELECT * FROM t3 WHERE MATCH (name,name2)
-> AGAINST ('不会吧'IN BOOLEAN MODE);
+------+-------------+
¦ name ¦ name2 ¦
+------+-------------+
¦ 2 ¦ 不会吧 ¦
¦ 4 ¦ 不会吧 1 ¦
¦ 6 ¦ 真的 不会吧 ¦
+------+-------------+
3 rows in set (0.00 sec)

查找以词 "不会吧" 开头的任意词句

mysql> SELECT * FROM t3 WHERE MATCH (name,name2)
-> AGAINST ('不会吧*' IN BOOLEAN MODE);
+------+-------------+
¦ name ¦ name2 ¦
+------+-------------+
¦ 2 ¦ 不会吧 ¦
¦ 4 ¦ 不会吧 1 ¦
¦ 6 ¦ 真的 不会吧 ¦
¦ 3 ¦ 不会吧1 ¦
+------+-------------+
4 rows in set (0.01 sec)

查找以词 "不会吧" 开头的任意词句 并 去除词 "真的"

mysql> SELECT * FROM t3 WHERE MATCH (name,name2)
-> AGAINST ('+不会吧* -真的' IN BOOLEAN MODE);
+------+----------+
¦ name ¦ name2 ¦
+------+----------+
¦ 2 ¦ 不会吧 ¦
¦ 4 ¦ 不会吧 1 ¦
¦ 3 ¦ 不会吧1 ¦
+------+----------+
3 rows in set (0.00 sec)

在上例中,
我们可以看出 MySQL 的全文索引对双字节处理的支持还不太好,
¦ 5 ¦ 真的不会吧 ¦
这一行记录始终未能查询出来,
这是因为在西文中词是以一个空格为分隔的,
:(
希望在将来的版本中
MySQL 对此能有所改进

而用正则表达式也是会有问题的,

查找词 "不会吧"

mysql> SELECT * FROM t3 WHERE name2 REGEXP "不会吧";
+------+-------------+
¦ name ¦ name2 ¦
+------+-------------+
¦ 1 ¦ 安换岚缮 ¦
¦ 2 ¦ 不会吧 ¦
¦ 3 ¦ 不会吧1 ¦
¦ 4 ¦ 不会吧 1 ¦
¦ 5 ¦ 真的不会吧 ¦
¦ 6 ¦ 真的 不会吧 ¦
+------+-------------+
6 rows in set (0.00 sec)

查找以词 "不会吧" 开头的

mysql> SELECT * FROM t3 WHERE name2 REGEXP "^不会吧";
+------+----------+
¦ name ¦ name2 ¦
+------+----------+
¦ 2 ¦ 不会吧 ¦
¦ 3 ¦ 不会吧1 ¦
¦ 4 ¦ 不会吧 1 ¦
+------+----------+
3 rows in set (0.00 sec)

查找以词 "不会吧" 结束的

mysql> SELECT * FROM t3 WHERE name2 REGEXP "不会吧$";
+------+-------------+
¦ name ¦ name2 ¦
+------+-------------+
¦ 2 ¦ 不会吧 ¦
¦ 5 ¦ 真的不会吧 ¦
¦ 6 ¦ 真的 不会吧 ¦
+------+-------------+
3 rows in set (0.00 sec)

Published At
Categories with 数据库类
Tagged with
comments powered by Disqus