2

我想构建我的第一个真正的搜索功能。我已经在谷歌上搜索了一段时间,但无法真正下定决心并理解所有内容。

我的数据库存在三个 InnoDB 表:

  • 产品:包含产品信息。列:(proID主要,自动增量),content(最多包含几百个单词),titleauthoryear,以及一堆与搜索查询无关的其他列。行:100 到 2000。
  • 类别:包含类别信息:列:(catID主要,自动增量)catName,. 行数:5-30
  • Productscategories:以上两者之间的联系。每个产品可以与多个类别相关。列:(pcID主要,自动增量)catID,,,proID。行数:产品数量的 1-5 倍。

我的搜索功能提供以下内容。它们不必填写。如果填写了多个,最终查询将使用 AND 查询将它们连接起来:

  • 术语:搜索内容和标题字段。搜索随机词,可以添加多个词,但搜索每个词是分开的。最有可能与数据库匹配 1 次就足够了(OR-query)
  • 年份:搜索产品的年份列。
  • 类别:可从类别列表中选择。多种可能。该表单返回所选类别的 catID。与数据库匹配 1 次就足够了(或查询)
  • 作者:author产品-栏目搜索

As you may have noticed, when a category is selected, the tables products and productcategories are joined together for the search query. 两者之间还有一个外键集。

为了澄清关系,一个应该如何解释的例子(不要搜索年份!):

搜索WHERE (products.content = term 1 OR products.content = term 2 OR products.title = term 1 OR products.title = term 2 ......) AND (products.author = author) AND (productscategories.catID = catID1 OR productscategories.catID= catID2 ......)

另请注意,我创建了一个分页系统,每个“页面”上只显示 10 个结果。

我遇到的问题如下:我希望优化这个搜索查询,但不知道哪种方式最好。

我发现谷歌搜索的大多数情况下都使用LIKE %%mysqli-query。但是有些人使用MATCH...AGAINST. 我似乎真的很喜欢最后一个,因为我读到它可以根据相关性进行排序,并且因为它似乎使查询更容易创建(1 匹配术语值而不是大量LIKE %%组合 with OR)。不过,似乎我只会在 Term-searchfield 上使用它。但是对于MATCH...AGAINST我将需要一个 MyIsam 表(对吗?),其中我不能使用外键来防止数据库中的错误。

MATCH...AGAINST示例(没有年份字段,类别字段并且不加入产品和产品类别):

SELECT *,MATCH (content,title) AGAINST ('search terms' IN BOOLEAN MODE) AS relevance 
FROM products WHERE (MATCH (content,title) AGAINST ('search terms' IN BOOLEAN MODE)) AND
author='author' SORT BY relevance LIMIT 10

%LIKE%示例(没有年份字段,类别字段,不加入产品和产品类别),遗憾的是没有相关性排序:

SELECT * FROM products WHERE
(content LIKE '%term1%' OR content LIKE '%term2' OR title LIKE '%term1%' OR title LIKE '%term2%')
AND (author='author') SORT BY title LIMIT 10

CASE如果一个术语出现在标题或内容中,我可以通过使用并添加“点”来进行相关性排序?或者这会使查询对于性能来说过于繁重?

那么进行这种查询的最佳方法是什么?使用 Innodb 和LIKE,或切换到 MyIsam 并使用MATCH...AGAINST进行排序?

4

1 回答 1

5

您不必切换到 MyIsam。Mysql 5.6 及更高版本支持全文索引。

我通常推荐使用全文索引。在您的列标题、作者、年份上创建全文索引

然后您可以同时对所有 3 个进行全文查询,并应用 IN BOOLEAN MODE 来真正缩小搜索范围。这当然是您必须自己决定的事情,但全文中的选项更多。

但是,如果您正在运行在范围、日期或简单字符串之间产生的查询。然后标准索引更好,但对于在不同列中进行 tekst 搜索,全文索引是要走的路!

阅读:http ://dev.mysql.com/doc/refman/5.6/en/fulltext-search.html

于 2013-10-20T13:05:05.317 回答