2010-06-17 94 views
0

我有一行有这样的关键字(关键字1,关键字2,关键字3),用逗号分隔,如图所示。当用户登录时,您知道他想要关于(keyword1,keyword3)的信息。现在,我有另一个表格,其中包含与不同关键字相关的一堆信息,该表格有一行称为(关键字)的行,表示该信息是否适合哪个关键字。如何根据关键字为用户呈现他所需的信息。换句话说,如果用户想要关于(关键词3,关键词1)的信息,我该如何去(信息)表并且找到在该行中具有该词语(关键词1)或词语(关键词3)的所有信息(关键词)?如何在MYSQL中搜索某一行中的特定单词?

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

预先感谢您:)

回答

2

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

USERS
ID

关键词
ID(或只使用名称作为主键)

...

USER_KEYWORDS
USER_ID
keyword_id

信息
ID
数据

INFORMATION_KEYWORDS
information_id
keyword_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> 
+0

谢谢你的建议,我会尽我所能在我能够尽快更改数据库结构 – user220755 2010-06-17 20:09:30

+0

我得到了不是唯一的表/别名:信息 – user220755 2010-06-17 20:40:32

+0

没关系,明白了:) – user220755 2010-06-17 20:47:19

2

使用MySQL FIND_IN_SET function在您的SQL查询,像这样:

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

会发现所有的行有关键字1或关键字3(我的意思是他们不必有两个关键字是地址,因为lon因为他们至少有一个,这很好)这是否适用于这种情况? (t.keywords)是指什么? – user220755 2010-06-17 19:06:24

+0

@ user220755:是的,只要其中一个关键字存在于您的表格中 - 该记录将被返回。 – 2010-06-17 19:07:45

+0

和t.keywords代表什么(只是让我知道用什么来代替它:))谢谢! – user220755 2010-06-17 19:08:17

1

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

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

+0

谢谢你的建议,我会尽我所能改变数据库结构我很快就可以 – user220755 2010-06-17 20:10:28

1

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

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

一个更好的解决办法是做一个表UserKeywords:

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

这样,您就可以加入这个表对信息和用户表。

+0

谢谢你的建议,我会尽我所能改变数据库结构 – user220755 2010-06-17 20:09:57

0

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; 

无论哪种方式,你这样做,你真的应该用你的数据库转换为关系建立开始,除非你别无选择 - 像你正在使用你没有编码的第三方软件包,它将需要永久转换。

另外,%在那里作为部分匹配的例子。如果您需要更多解释,请告诉我们。

0

当进行关键字类型查询时(希望通过sjoerd来解释每行代码的方法,我非常喜欢MySql中很少使用的REGEXP特性,类似于它,它可以对所有字符进行部分搜索。在没有搜索查询的各个部分所需的所有特殊字符类似的数据单元格把它看成是谷歌针对MySQL的

一个例子:

SELECT * from表where值REGEXP“富”

相关问题