Php 如何在MYSQL中搜索一行中的特定单词?

Php 如何在MYSQL中搜索一行中的特定单词?,php,mysql,Php,Mysql,我有一行的关键字是用逗号分隔的(关键字1,关键字2,关键字3),如图所示。当用户登录时,您知道他需要关于(关键字1、关键字3)的信息。现在,我有另一个表,它有一堆与不同关键字相关的信息,这个表有一行叫做(关键字),它指示这些信息是否适合哪个关键字。如何根据关键字为用户呈现所需的信息 换句话说,如果用户需要关于(关键字3,关键字1)的信息,我如何转到(信息)表并在行(关键字)中查找包含单词(关键字1)或单词(关键字3)的所有信息 对不起,如果这是复杂的(我的解释),但我尽力解释它 提前感谢:)在S

我有一行的关键字是用逗号分隔的(关键字1,关键字2,关键字3),如图所示。当用户登录时,您知道他需要关于(关键字1、关键字3)的信息。现在,我有另一个表,它有一堆与不同关键字相关的信息,这个表有一行叫做(关键字),它指示这些信息是否适合哪个关键字。如何根据关键字为用户呈现所需的信息

换句话说,如果用户需要关于(关键字3,关键字1)的信息,我如何转到(信息)表并在行(关键字)中查找包含单词(关键字1)或单词(关键字3)的所有信息

对不起,如果这是复杂的(我的解释),但我尽力解释它

提前感谢:)

在SQL查询中使用MySQL,如下所示:

 FROM TABLE t
WHERE FIND_IN_SET(t.keywords, 'keyword1, keyword3') > 0
SELECT * FROM `information` WHERE MATCH(`keyword`) AGAINST('keyword1 keyword3' IN BOOLEAN MODE)
$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;

你的意思是像查询一样??查看数据库设计的第一条规则:每行存储一个值


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

您考虑过更改数据模型吗

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

更好的解决方案是创建一个UserKeywords表:

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

通过这种方式,您可以根据信息表和用户表联接此表。

请规范化您的表,并对单个字段中以逗号分隔的值非常怀疑。更灵活的设置是:

用户
id
名字

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

用户关键字
用户id
关键字\u id

信息
id
资料

信息\u关键字
信息\u id
关键字\u 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>
选择information.data
来自用户
在user\u关键字上加入user\u关键字。user\u id=users.id
加入信息上的信息关键字关键字关键字id=用户关键字关键字关键字关键字id
加入有关信息的信息\u关键字。信息\u id=信息.id
其中users.id=

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

 FROM TABLE t
WHERE FIND_IN_SET(t.keywords, 'keyword1, keyword3') > 0
SELECT * FROM `information` WHERE MATCH(`keyword`) AGAINST('keyword1 keyword3' IN BOOLEAN MODE)
$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;
在这种情况下,如果与其中一个匹配,那么您的匹配应该返回

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

 FROM TABLE t
WHERE FIND_IN_SET(t.keywords, 'keyword1, keyword3') > 0
SELECT * FROM `information` WHERE MATCH(`keyword`) AGAINST('keyword1 keyword3' IN BOOLEAN MODE)
$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;
无论采用哪种方法,您都应该首先将数据库转换为关系设置,除非您别无选择—就像您使用的是未编码的第三方软件包,而且转换需要花费很长时间


另外,其中的%是部分匹配的示例。如果您需要更多解释,请在执行关键字类型查询时告诉我们。

(希望使用sjoerd解释的每行一个方法,我非常喜欢MySql不常使用的REGEXP功能。与like类似,它可以对单元格中的所有字符进行部分搜索,以获得类似的数据,而无需搜索查询的各个部分所需的所有特殊字符。可以将其想象为Google for MySql

例如:


从表中选择*值REGEXP'foo'

是否会找到所有包含关键字1或关键字3的行(我的意思是,它们不必同时包含两个关键字作为地址,只要它们至少有一个关键字,就可以了)这是否适用于此条件?以及(t.keywords)是什么请参阅?@user220755:是的,只要您的表中存在一个关键字,就会返回记录。t.keywords代表什么(我知道用什么替换它:)谢谢!@user220755:
t.
是一个表别名引用-我包含它是为了演示针对您的情况引用列的位置。最后一个问题:是否有方法知道它找到了哪一个?例如,是否有方法知道返回的信息仅与关键字3相关?或与关键字1或两者相关((我真的很感谢你的帮助)LIKE对于这个操作来说太简单了谢谢你的建议,我会尽我所能尽快更改数据库结构谢谢你的建议,我会尽我所能尽快更改数据库结构谢谢你的建议,我会尽我所能尽快更改数据库结构