跨多个表的MySQL关键字搜索

Eri*_*ese 7 mysql database search multiple-tables keyword

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

Genre表有列:

  • id
  • title (串)

Album表有列:

  • id
  • genre_id(外键Genre.id)
  • title (串)
  • artist (串)

并且Track表格有列:

  • id
  • album_id(外键Album.id)
  • title (串)

每个都Album可以有任意数量Tracks,每个Track都有一个Album,每个Album都有一个Genre.


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

  • 有匹配的title,
  • 正在Album与匹配titleartist,
  • 或者是上的AlbumGenre具有匹配title.

结果应按相关性排序.如果每个领域都有相关性排名,那就太好了.举例来说,title一个Track可能比更重要titleGenre.

此外,解决方案应使用某种形式的部分搜索.一个搜索的rubber应首先匹配所有TrackstitleRubber,然后匹配Trackstitle匹配*rubber*(*=通配符),然后转移到Albums,等等.但是,我并没有这么详细说明.我只是在寻找一个更通用的解决方案,我可以调整以满足我的特定需求.

我还要提一下,我正在使用LAMP堆栈,Linux,Apache,MySQL和PHP.


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


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

CREATE TABLE `Genre` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` text NOT NULL,
  PRIMARY KEY (`id`),
  FULLTEXT KEY (`title`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

INSERT INTO `Genre` VALUES(1, 'Rock');

CREATE TABLE `Album` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `genre_id` int(11) NOT NULL,
  `title` text NOT NULL,
  `artist` text,
  PRIMARY KEY (`id`),
  FULLTEXT KEY (`title`, `artist`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

INSERT INTO `Album` VALUES(1, 1, 'Rubber Soul', 'The Beatles');

CREATE TABLE `Track` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `album_id` int(11) NOT NULL,
  `title` text NOT NULL,
  PRIMARY KEY (`id`),
  FULLTEXT KEY (`title`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

INSERT INTO `Track` VALUES(1, 1, 'Drive My Car');
INSERT INTO `Track` VALUES(2, 1, 'What Goes On');
INSERT INTO `Track` VALUES(3, 1, 'Run For Your Life');
INSERT INTO `Track` VALUES(4, 1, 'Girl');
Run Code Online (Sandbox Code Playgroud)

Bil*_*win 5

我会使用Apache Solr。使用数据导入处理程序定义将所有表连接在一起的SQL查询,并根据连接数据的结果创建全文索引。


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

所以你不能这样做:

WHERE MATCH (g.title, a.title, a.artist, t.title) AGAINST ('beatles')
Run Code Online (Sandbox Code Playgroud)

使用布尔模式还是自然语言模式都没关系。

您需要这样做:

WHERE MATCH (g.title) AGAINST ('beatles')
   OR MATCH (a.title, a.artist) AGAINST ('beatles')
   OR MATCH (t.title) AGAINST ('beatles')
Run Code Online (Sandbox Code Playgroud)

您可能也对我的演示MySQL中的实用全文搜索感兴趣。