如何在 MySQL 中实现关键字搜索?
Posted
技术标签:
【中文标题】如何在 MySQL 中实现关键字搜索?【英文标题】:How to implement a Keyword Search in MySQL? 【发布时间】:2010-10-20 01:31:06 【问题描述】:我是 SQL 编程新手。
我有一个表格作业,其中字段为id
、position
、category
、location
、salary range
、description
、refno
。
我想从前端实现关键字搜索。关键字可以驻留在上表的任何字段中。
这是我尝试过的查询,但它包含很多重复的行:
SELECT
a.*,
b.catname
FROM
job a,
category b
WHERE
a.catid = b.catid AND
a.jobsalrange = '15001-20000' AND
a.jobloc = 'Berkshire' AND
a.jobpos LIKE '%sales%' OR
a.jobloc LIKE '%sales%' OR
a.jobsal LIKE '%sales%' OR
a.jobref LIKE '%sales%' OR
a.jobemail LIKE '%sales%' OR
a.jobsalrange LIKE '%sales%' OR
b.catname LIKE '%sales%'
【问题讨论】:
【参考方案1】:对于 VARCHAR 字段上的单个关键字,您可以使用 LIKE
:
SELECT id, category, location
FROM table
WHERE
(
category LIKE '%keyword%'
OR location LIKE '%keyword%'
)
对于描述,您通常最好添加全文索引并执行Full-Text Search(仅限 MyISAM):
SELECT id, description
FROM table
WHERE MATCH (description) AGAINST('keyword1 keyword2')
【讨论】:
选择一个。 * , b.catname FROM job a, categiry b WHERE a.catid = b.catid AND a.jobsalrange = '15001-20000' AND a.jobloc = 'Berkshire' AND a.jobpos LIKE '%sales%' OR a. jobloc LIKE '%sales%' OR a.jobsal LIKE '%sales%' OR a.jobref LIKE '%sales%' OR a.jobemail LIKE '%sales%' OR a.jobsalrange LIKE '%sales%' OR b. catname LIKE '%sales%' acually 这是我尝试过的查询,但它包含很多重复的行。 您只需将 OR 括起来:WHERE a=b AND c=d AND (e LIKE f OR g LIKE i) 我不认为它只是MYISAM了。 mysql 5.6.4 及更高版本支持 InnoDB 全文搜索。 dev.mysql.com/doc/refman/5.6/en/fulltext-restrictions.html (仅限 MyISAM):评论节省了我尝试在 innoDB 上进行全文搜索的时间【参考方案2】:SELECT
*
FROM
yourtable
WHERE
id LIKE '%keyword%'
OR position LIKE '%keyword%'
OR category LIKE '%keyword%'
OR location LIKE '%keyword%'
OR description LIKE '%keyword%'
OR refno LIKE '%keyword%';
【讨论】:
选择一个。 * , b.catname FROM job a, categiry b WHERE a.catid = b.catid AND a.jobsalrange = '15001-20000' AND a.jobloc = 'Berkshire' AND a.jobpos LIKE '%sales%' OR a. jobloc LIKE '%sales%' OR a.jobsal LIKE '%sales%' OR a.jobref LIKE '%sales%' OR a.jobemail LIKE '%sales%' OR a.jobsalrange LIKE '%sales%' OR b. catname LIKE '%sales%' acually 这是我尝试过的查询,但它包含很多重复的行。 您在表 b 中是否有多个具有相同 catid 的条目? @santanu 您需要执行连接以避免笛卡尔连接(重复值),请参见此处en.wikipedia.org/wiki/Cartesian_product【参考方案3】:理想情况下,有一个包含字段的关键字表:
Keyword
Id
Count (possibly)
在关键字上有索引。在另一个表上创建一个插入/更新/删除触发器,以便在更改行时,提取每个关键字并将其放入(或替换)该表。
您还需要一个不计为关键字的单词表(if、and、so、but、...)。
通过这种方式,您将获得想要查找关键字的查询的最佳速度,并且您可以(相对容易地)实现更复杂的查询,例如“包含 Java 和 RCA1802”。
"LIKE"
查询可以工作,但它们也不能扩展。
【讨论】:
【参考方案4】:就个人而言,我不会在 ID 字段或任何其他数字字段上使用 LIKE
字符串比较。搜索 ID#“216”返回 16216、21651、3216087、5321668...,以此类推;薪水也是如此。
另外,如果您想使用准备好的语句来防止 SQL 注入,您可以使用如下查询字符串:
SELECT * FROM job WHERE `position` LIKE CONCAT('%', ? ,'%') OR ...
【讨论】:
【参考方案5】:您可以在此处的线程中找到另一个更简单的选项:Match Against..,11.9.2. Boolean Full-Text Searches 中提供更详细的帮助
这是以防万一有人需要更紧凑的选项。这将需要在表中创建一个索引 FULLTEXT,这很容易完成。
有关如何创建索引 (MySQL) 的信息:MySQL FULLTEXT Indexing and Searching
在FULLTEXT
索引中,您可以列出多个列,结果将是一个带有名为search
的索引的SQL 语句:
SELECT *,MATCH (`column`) AGAINST('+keyword1* +keyword2* +keyword3*') as relevance FROM `documents`USE INDEX(search) WHERE MATCH (`column`) AGAINST('+keyword1* +keyword2* +keyword3*' IN BOOLEAN MODE) ORDER BY relevance;
我尝试了多个列,但没有运气。即使索引中允许有多个列,您仍然需要为每个列创建一个索引才能与 Match/Against 语句一起使用。
根据您的标准,您可以使用任一选项。
【讨论】:
【参考方案6】:我将解释我通常喜欢的方法:
首先,您需要考虑到,对于这种方法,您将牺牲内存以提高计算速度。 其次,您需要拥有编辑表结构的权限。
1) 添加一个字段(我通常称之为“摘要”),用于存储表中的所有数据。
该字段将如下所示:
“n-n1-n2-n3-n4-n5-n6-n7-n8-n9”等..其中n是一个单词
我使用正则表达式将“”替换为“-”来实现这一点。 该字段是将所有表数据“消化”在一个字符串中的结果。
2) 在摘要字段上使用 LIKE 语句 %keyword%:
SELECT * FROM table WHERE digest LIKE %keyword%
您甚至可以构建一个带有小循环的 qUery,这样您就可以同时搜索多个关键字,如下所示:
SELECT * FROM table WHERE
digest LIKE %keyword1% AND
digest LIKE %keyword2% AND
digest LIKE %keyword3% ...
【讨论】:
我喜欢标记化关键字的多个“LIKE”语句。 这个解决方案看起来更有希望。但是如何才能在一开始就显示出更好的匹配结果呢? 你的解决方案非常适合我。【参考方案7】:我知道这有点晚了,但我对我们的应用程序所做的就是这样。希望这会对某人有所帮助。但它对我有用:
SELECT * FROM `landmarks` WHERE `landmark_name` OR `landmark_description` OR `landmark_address` LIKE '%keyword'
OR `landmark_name` OR `landmark_description` OR `landmark_address` LIKE 'keyword%'
OR `landmark_name` OR `landmark_description` OR `landmark_address` LIKE '%keyword%'
【讨论】:
嗯,据我所知,最晚的包含所有以前的。以上是关于如何在 MySQL 中实现关键字搜索?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 LINQ 在 NHibernate 3 中实现关键字搜索?