mysql查询策略查找关键字匹配

时间:2015-01-27 16:48:42

标签: mysql sql

对不起,如果问题是愚蠢的。但是我以正确的方式做到这一点确实存在问题。

我有第一张表,announcements,我有Title, Description用户添加一些公告。

还有另一张表,我们有

1 id, email, keyword1,keyword2,keyword4,keyword5,其中用户最多可添加5个关键字,当此类关键字出现在任何新添加的公告中时,我需要向此表中提到的电子邮件发送电子邮件。所以问题是,解决这个问题的最快和最优解决方案是什么?

现在添加公告时,我会将所有项目都放在第二个表格中,然后针对每个项目循环并使用赞%keyword1%语句进行查询,这需要很长时间。例如,当我有20,000个条目时,它将花费太多。

那么最好的方法是什么?也许一个查询将列出

title,keyword,email ??

4 个答案:

答案 0 :(得分:1)

以相反的方式做。不要将关键字与您的公告相匹配,而是将公告与用户+关键字匹配。

添加新公告时,请使用新查询构建一个特殊字符串,该字符串将直接匹配users表中的关键字。例如,假设您添加的公告是:

New product! (this is title)
We have added new product, check it out!

现在接受你公告中的所有话:

New product We have added check it out

并构建一个查询WHERE子句:

keyword1 IN ("New","product","We","have","added","check","it", "out") OR 
keyword1 IN ("New","product","We","have","added","check","it", "out") OR 
keyword2 IN ("New","product","We","have","added","check","it", "out") OR 
keyword3 IN ("New","product","We","have","added","check","it", "out") OR 
keyword4 IN ("New","product","We","have","added","check","it", "out") OR 
keyword5 IN ("New","product","We","have","added","check","it", "out") 

最后像这样制作整个查询:

SELECT * FROM users
WHERE 
   keyword1 IN ("New","product","We","have","added","check","it", "out") OR 
   keyword2 IN ("New","product","We","have","added","check","it", "out") OR 
   keyword3 IN ("New","product","We","have","added","check","it", "out") OR 
   keyword4 IN ("New","product","We","have","added","check","it", "out") OR 
   keyword5 IN ("New","product","We","have","added","check","it", "out") 

确保您的keyword1,2,3,4,5列上有INDEX。此查询非常快,只会返回与新添加的公告相匹配的用户。

确保整个查询字符串不超过最大数据包大小(通常大小为8MB)

答案 1 :(得分:0)

使用类似操作的查询搜索速度很慢,但有很多技术可供您使用: -

  1. Apache solr
  2. Egothor
  3. Nutch的
  4. Lucene的
  5. Oxyus等
  6. 这些工具可以提供最佳性能。

    否则您也可以使用查询优化: -

    用户喜欢“快速搜索”,并且为了实用性,我认为这最适合字符串中的任何位置 - 因此LIKE'%first_name%'条件。

    我不打算将字段和字段分开。为快速搜索条款。 (对于全重搜索表单,我为每个字段提供单独的输入,用户可以搜索。)但快速搜索是一个简单的UI。

    我不区分大小写。如果它不是数据库的默认值,则可以在匹配之前对字符串使用lower()函数。

    输入'Robin':

    select * from members 
    where fullname like '%Robin%' or email like '%Robin%'
    

    或者,就像我在FireBird中强制不区分大小写一样:

    select * from members 
    where lower(fullname) like '%robin%' or lower(email) like '%robin%'
    

    这将匹配所有名称组合,即

    1. Robin Xyx
      1. robin abc
      2. abc robin
      3. ac.robin@gmail.com等
    2. 如果你愿意,你可以将first和lastname字段分开。我的设计更喜欢将它们保持在一起,因为我主要只是使用fullname来显示目的和放大。不要在意区别。

答案 2 :(得分:0)

由于关键字排列在表格中,因此更加困难。我建议考虑将这些放在另一张桌子上,我相信它会帮助你查询。

我认为这样的事情会成功

select * from users u
inner join announcement a on instr(a.description, u.keyword1) > 0

union

select * from users u
inner join announcement a on instr(a.description, u.keyword2) > 0

union

select * from users u
inner join announcement a on instr(a.description, u.keyword3) > 0

您必须为每个关键字添加联盟。这是我为它准备的SQL fiddle

答案 3 :(得分:0)

我不会使用包含5列的表作为关键字,我会使用类似的东西:

table announcement: announcement_id, title, description
table user: user_id, email
table keyword: keyword_id, keywordvalue
table user_keyword: user_id, keyword_id

然后,运行查询以查找与用户相关的所有关键字会更容易。