跨多个表的MySQL关键字搜索

时间:2010-07-16 22:06:52

标签: mysql database search keyword multiple-tables

我在音乐库应用程序中使用的MySQL数据库中有三个表:

Genre表包含列:

  • id
  • title(字符串)

Album表包含列:

  • id
  • genre_idGenre.id的外键)
  • title(字符串)
  • artist(字符串)

并且Track表包含列:

  • id
  • album_idAlbum.id的外键)
  • title(字符串)

每个Album可以包含任意数量的Tracks,每个Track只有一个Album,每个Album只有一个Genre。< / p>


我想实现一个关键字搜索,允许用户输入任意数量的关键字并找到所有Tracks

  • 有匹配的title
  • 位于Album,匹配titleartist
  • 或位于AlbumGenretitle匹配。

结果应按相关性排序。如果每个领域都有相关性排名,那就太好了。例如,title的{​​{1}}可能比Track的{​​{1}}更重要。

此外,解决方案应使用某种形式的部分搜索。搜索title应首先将所有Genrerubber Tracks匹配,然后将titleRubber匹配{{1}匹配}(Tracks =通配符),然后转到title,依此类推。但是,我并没有这么详细说明。我只是在寻找一个更通用的解决方案,我可以调整以满足我的特定需求。

我还应该提一下,我正在使用LAMP堆栈,Linux,Apache,MySQL和PHP。


实施此关键字搜索的最佳方式是什么?


更新: 我一直在尝试通过全文搜索来实现这一点,并提出了以下SQL语句。

*rubber*

3 个答案:

答案 0 :(得分:4)

我会使用Apache Solr。使用Data Import Handler定义将所有表连接在一起的SQL查询,根据连接数据的结果创建全文索引。


名为args to MATCH()的列必须是您为索引定义的列,其顺序与您在索引中定义的顺序相同。但是你不能在MySQL中的多个表中定义任何索引(全文或其他)。

所以你不能这样做:

WHERE MATCH (g.title, a.title, a.artist, t.title) AGAINST ('beatles')

无论您使用的是布尔模式还是自然语言模式,都无关紧要。

你需要这样做:

WHERE MATCH (g.title) AGAINST ('beatles')
   OR MATCH (a.title, a.artist) AGAINST ('beatles')
   OR MATCH (t.title) AGAINST ('beatles')

您可能也对我的演示Practical Full-Text Search in MySQL感兴趣。

答案 1 :(得分:1)

在您要搜索的四列上定义全文索引,然后执行:

SELECT * FROM genre AS g
  LEFT JOIN album AS a ON g.id = a.genre_id
  LEFT JOIN tracks AS t ON a.id = t.album_id
  WHERE MATCH (g.title,  a.title, a.artist, t.title) AGAINST ('searchstring');

重新排序将按相关性排序。 有关全文搜索的更多详细信息,请参见此处: http://dev.mysql.com/doc/refman/5.0/en/fulltext-natural-language.html

答案 2 :(得分:0)

我会使用像Sphinx这样的东西,你可以从你的查询中创建一个索引然后查询它。 有点难以理解,但结果比mysql AGAINST好10倍,以后你就不会有速度问题了。