【问题标题】:How to search for a specific word in a row in MYSQL?如何在MYSQL中连续搜索特定单词?
【发布时间】:2010-06-17 19:01:11
【问题描述】:

我有一行以这种方式包含以逗号分隔的关键字(关键字 1、关键字 2、关键字 3),如图所示。当用户登录时,您知道他想要有关 (keyword1,keyword3) 的信息。现在,我有另一个表,其中包含与不同关键字相关的大量信息,该表有一行称为 (keywords),指示此信息是否适用于哪个关键字。如何根据关键字为用户呈现他需要的信息。

换句话说,如果用户想要关于(keyword3,keyword1)的信息,我如何去(信息)表并找到行中包含单词(keyword1)或单词(keyword3)的所有信息(关键字)?

对不起,如果这很复杂(我的解释),但我已尽力解释。

提前谢谢你:)

【问题讨论】:

    标签: php mysql


    【解决方案1】:

    请规范化您的表格,并对单个字段中的逗号分隔值保持高度怀疑。更灵活的设置是:

    用户
    身份证
    名字

    关键词
    id(或仅使用名称作为主键)
    名称
    ...

    USER_KEYWORDS
    用户ID
    关键字id

    信息
    身份证
    数据

    INFORMATION_KEYWORDS
    信息_id
    关键字id

    您的查询结果将类似于:

    SELECT information.data
    FROM users
    JOIN user_keywords ON user_keywords.user_id = users.id
    JOIN information_keywords ON information_keywords.keyword_id = user_keywords.keyword_id
    JOIN information ON information_keywords.information_id = information.id
    WHERE users.id = <id>
    

    【讨论】:

    • 感谢您的建议,我会尽我所能尽快更改数据库结构
    【解决方案2】:

    在您的 SQL 查询中使用 MySQL FIND_IN_SET function,如下所示:

     FROM TABLE t
    WHERE FIND_IN_SET(t.keywords, 'keyword1, keyword3') > 0
    

    【讨论】:

    • 会找到所有具有关键字 1 或关键字 3 的行(我的意思是,它们不必同时拥有两个关键字,只要它们至少有一个,就可以了)有这个条件? (t.keywords) 指的是什么?
    • @user220755:是的,只要您的表中存在关键字之一 - 就会返回记录。
    • 以及 t.keywords 代表什么(只是让我知道用什么代替它:))谢谢!
    • @user220755: t. 是一个表别名引用 - 我包含它是为了演示针对您的情况引用该列的位置。
    • 最后一个问题:有没有办法知道它找到了哪一个?比如有没有办法知道返回的信息只和keyword3有关?或关键字1或两者兼而有之? ((我非常感谢您的帮助))
    【解决方案3】:

    数据库设计的第一条规则:每行存储一个值。

    换句话说,您应该修改数据库以将每个关键字存储在单独的行中。

    【讨论】:

    • 感谢您的建议,我会尽我所能尽快更改数据库结构
    【解决方案4】:

    您是否考虑过更改数据模型?

    目前您在一列内有一个迷你表。也就是说,关键字列包含多个值,以逗号分隔。您将很难匹配这些关键字。

    更好的解决方案是制作一个表格 UserKeywords:

    User    Keyword
    Paul    snacks
    Paul    food
    Paul    beer
    Kelly   snacks
    Kelly   wine
    

    这样,您可以将这个表与信息表和用户表连接起来。

    【讨论】:

    • 感谢您的建议,我会尽我所能尽快更改数据库结构
    【解决方案5】:

    Sjoerd 是对的。关系数据库设置绝对是最好的解决方案。 我不确定 MySQL FIND_IN_SET() 但你可以解析出你的用户关键字并组成一个字符串,这样你的搜索查询最终会像这样:

    SELECT * FROM `information` WHERE MATCH(`keyword`) AGAINST('keyword1 keyword3' IN BOOLEAN MODE)
    

    在这种情况下,如果匹配任何一个,您的匹配项应该返回。

    您应该记住,“关键字”列必须是全文索引才能匹配,并且匹配仅适用于服务器上 php.ini 配置中定义的最少字符数。在大多数情况下,默认值为 4 个字符。 换句话说,您的关键字必须是 4 个或更多字符才能使用匹配。 话虽如此,您可以将查询字符串设置为执行以下操作:

    $user_keywords = array('keyword1', 'keyword3');
    
    if(count($user_keywords) == 1)
    {
        $word = $user_keywords[0];
    
        if(strlen($word) >= 4)
        {
            $query_str = "MATCH(`keyword`) AGAINST ('".$word."' IN BOOLEAN MODE)";
        }
        else
        {
            $query_str = "`keyword` LIKE '%".$word."%'";
        }
    
    }
    else
    {
        $query_str = "";
        foreach($user_keywords AS $key)
        {
            $query_str .= "`keyword` = '".$key."' OR ";
        }
        $query_str = substr($query_str, 0, -3);
    }
    
    $sql = "SELECT * FROM `information` WHERE ".$query_str;
    

    无论采用哪种方式,您都应该从将数据库转换为关系设置开始,除非您别无选择 - 就像您使用的第三方软件包不是您编写的那样,而且转换需要很长时间。

    此外,% 作为部分匹配的示例。如果您需要更多解释,请告诉我们。

    【讨论】:

      【解决方案6】:

      您的意思是LIKE 查询吗?查看http://dev.mysql.com/doc/refman/4.1/en/pattern-matching.html

      【讨论】:

      • LIKE 这个操作太简单了
      【解决方案7】:

      在做关键字类型查询时(希望做sjoerd解释的逐行的方法,我是MySql不常用的REGEXP功能的忠实粉丝。类似于like,它可以对所有字符进行部分搜索类似数据的单元格,没有搜索查询的各个部分所需的所有特殊字符。将其视为 Google for MySql

      一个例子:

      SELECT * from TABLE WHERE value REGEXP 'foo'

      【讨论】:

        猜你喜欢
        • 2015-05-22
        • 2017-08-06
        • 2023-03-17
        • 2022-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-20
        • 2015-09-15
        相关资源
        最近更新 更多