如何在 MySQL 中实现关键字搜索?

Posted

技术标签:

【中文标题】如何在 MySQL 中实现关键字搜索?【英文标题】:How to implement a Keyword Search in MySQL? 【发布时间】:2010-10-20 01:31:06 【问题描述】:

我是 SQL 编程新手。

我有一个表格作业,其中字段为idpositioncategorylocationsalary rangedescriptionrefno

我想从前端实现关键字搜索。关键字可以驻留在上表的任何字段中。

这是我尝试过的查询,但它包含很多重复的行:

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”返回 1621621651、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 中实现关键字搜索?

如何在 PaginatedDataTable Flutter Web 中实现搜索

Swift中实现用户输入防抖动的两种方法

Swift中实现用户输入防抖动的两种方法

在 Rails 4 中实现通用搜索

小程序中实现搜索功能