【问题标题】:How to implement a Keyword Search in MySQL?如何在 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%'

【问题讨论】:

    标签: sql mysql search


    【解决方案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%'
          

          【讨论】:

          • 嗯,据我所知,最晚的包含所有以前的。
          猜你喜欢
          • 2017-08-06
          • 1970-01-01
          • 1970-01-01
          • 2010-10-07
          • 1970-01-01
          • 1970-01-01
          • 2018-03-26
          • 1970-01-01
          相关资源
          最近更新 更多