我想构建我的第一个真正的搜索功能。我已经在谷歌上搜索了一段时间,但无法真正下定决心并理解所有内容。
我的数据库存在三个 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 %%
组合 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
进行排序?