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

istrue 2003-04-28 11:01:53
许多朋友在使用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分)

...全文
321 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
shuixin13 2003-04-29
  • 打赏
  • 举报
回复
# 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)
istrue 2003-04-29
  • 打赏
  • 举报
回复
感谢!!!!!!
istrue 2003-04-29
  • 打赏
  • 举报
回复
都是binary惹的祸!!!!!
seeku 2003-04-29
  • 打赏
  • 举报
回复
我想 shuixin13(犬犬(心帆)) 说的已经比较清楚了

其实我以前一直没有用过binary属性,没有想到过这种问题
seeku 2003-04-29
  • 打赏
  • 举报
回复
mysql> CREATE TABLE `t3` (
-> `name` char(9) binary NOT NULL default ''
-> ) TYPE=MyISAM;
Query OK, 0 rows affected (0.47 sec)

mysql> insert into t3 (name) values ('我不是天使');
Query OK, 1 row affected (0.04 sec)

mysql> insert into t3 (name) values ('1安花2');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t3 (name) values ('1安花3');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t3 where name like '%不%';
+-----------+
| name |
+-----------+
| 我不是天?|
| 1安花2 |
| 1安花3 |
+-----------+
3 rows in set (0.06 sec)
istrue 2003-04-29
  • 打赏
  • 举报
回复
建表时,你试着:
CREATE TABLE `t3` (
`name` char(9) binary NOT NULL default ''
) TYPE=MyISAM;
试试,结果请通知!
seeku 2003-04-29
  • 打赏
  • 举报
回复
从manual看,建表的时候使用的character-set不是gbk,然后插入一些记录,
这个时候index不是根据gbk来建立的,后来如果把default-character-set改成
gbk,index还是没有该过来,必须要重新建立index。

manual提供了一个命令重新重新建立index的,但好像只能用于myisam类型的表,
不知道innodb怎么做?

你看看一下你的问题是否出在上面提到的情况?

另外,我也没有碰到过你说的情况,我也从来没有给字段名加引号的习惯
istrue 2003-04-29
  • 打赏
  • 举报
回复
劳烦兄弟把全文本索引的代码贴上来
istrue 2003-04-29
  • 打赏
  • 举报
回复
我也不知道!
我对一个同样内容的表,
加不加引号引起了两种不同的查找结果!
我用的当然是mysql-4.0.12,还包括win与linux下两个版本(linux下还没有调试)
swotcoder 2003-04-28
  • 打赏
  • 举报
回复
存放数据时还可以使用ISO-8859-1编码,不过有的你后悔的时候!
shuixin13 2003-04-28
  • 打赏
  • 举报
回复
需要说明的是
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%' 形式了
建议使用 全文索引 与 正则表达式 来匹配字串
shuixin13 2003-04-28
  • 打赏
  • 举报
回复
1: my.ini 文件中加入 default-character-set =gb2312
2: 字段不要加 Binary 属性
3: 执行 select * from mytable where mysqlname like "%不%"
shuixin13 2003-04-28
  • 打赏
  • 举报
回复
:)
你用的是 MySQL-4.0.12 ??
我重试了,
同样的结果,
反引号是不会对结果有什么影响的!

istrue 2003-04-28
  • 打赏
  • 举报
回复
你在以上例子中试着把表名与字段名的引号去掉看看!
另,我的全文索引不起作用,不知怎么回事
shuixin13 2003-04-28
  • 打赏
  • 举报
回复
>> 字段名与表名加上两个引号就可解决了!

????

`t3`
`name`
上面的那个反引号??
不关它们的事的,
最主要的是我所述的1\2两个条件,

==========

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

==========
当你使用 LIKE '%a%' 形式时,
这个查询将不能使用该字段上的索引,
所以这个查询将耗费很大的时间,
所以建议使用 全文索引
istrue 2003-04-28
  • 打赏
  • 举报
回复
开始我建的表就是会出现我所说的情况,而使用心帆朋友的方法却不会出现,真是奇怪,
找到一个下午,终于找到问题的症结:
答案非常离谱:
在建表时,字段名与表名加上两个引号就可解决了!
shuixin13 2003-04-28
  • 打赏
  • 举报
回复
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>

56,677

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧