【发布时间】:2013-10-20 11:20:26
【问题描述】:
我想构建我的第一个真正的搜索功能。我已经在谷歌上搜索了一段时间,但无法真正下定决心并理解所有内容。
我的数据库存在三个 InnoDB 表:
- 产品:包含产品信息。列:
proID(主要,自动递增)、content(最多包含几百个字)、title、author、year,以及一堆与搜索无关的其他列询问。行数: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 %% 结合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 进行排序?
【问题讨论】:
-
在查询中运行“解释”时会说什么?