11

我正在建立一个网上商店。该商店允许用户通过category和几个可选的附加过滤器(例如brandcolor等)过滤产品。

目前,各种属性存储在不同的地方,但我想切换到基于标签的系统。理想情况下,我的数据库应该存储带有以下数据的标签:

  • product_id
  • tag_url_alias(独特)
  • tag_type(唯一)(类别、product_brand、product_color 等)
  • tag_value(不是唯一的)

第一个目标

我想搜索与1-5 个特定标签之间product_id的任何地方相关联的标签。标签是从对 SEO 友好的 url 中提取的。所以我将为每个标签检索一个唯一的字符串(),但我不知道. 搜索将是一个交集,所以我的搜索应该返回匹配所有提供的。tag_url_aliastag_typeproduct_idtags

第二个目标

除了显示与当前过滤器匹配的产品外,我还想显示用户可能提供的其他类别和过滤器的产品计数。

例如,我当前的搜索是匹配标签的产品:

Shoe + Black + Adidas

现在,商店的访客可能正在查看生成的产品,并想知道其他品牌必须提供哪些黑鞋。所以他们可能会去“品牌”过滤器,并选择任何其他列出的品牌。假设他们有 2 个不同的选项(实际上,这可能会有更多),导致以下搜索:

Shoe + Black + Nike > 103 results
Shoe + Black + K-swiss > 0 results

在这种情况下,如果他们在过滤器中看到品牌“K-swiss”列为可用选择,他们的搜索将返回 0 个结果。

这显然让用户感到相当失望......我更想知道将“品牌”从“阿迪达斯”切换到“k-swiss”将得到 0 结果,并且只需从过滤器中删除整个选项。

类别、颜色等也是如此。

实际上,这意味着单个页面视图不仅会返回我的主要目标中描述的过滤后的产品列表,而且可能会返回数百个相似但不同的列表。一个用于可以替换另一个过滤器值或添加到现有过滤器值的每个过滤器值。

容量

我怀疑我的数据库最终将包含:

250 到 1.000 个唯一标签

它将包含:

10.000 到 100.000 种独特的产品

当前的想法

我做了一些谷歌搜索,发现了以下文章:http ://www.pui.ch/phred/archives/2005/06/tagsystems-performance-tests.html

从那篇文章来看,运行数百个查询来实现第二个目标,将是一条非常缓慢的路线。“毒药”示例可能适合我的需要,并且对于我的第一个目标可能是可以接受的,但对于第二个目标来说它会慢得令人无法接受。

我在想我可能会运行匹配 1tag到它关联product_id的单个查询,缓存这些查询,然后计算结果的交集。但是,我是否在 MySQL 中计算这些交叉点?还是在 PHP 中?如果我使用 MySQL,是否有一种特殊的方式我应该缓存这些单独的查询,或者提供我需要的所有正确的索引?

我想也很有可能缓存其中两个tag/product_id集合之间的交叉点。交叉点的数量将受到 atag_type只能具有一个特定值这一事实的限制,但我不确定如何有效地管理这种类型的缓存。同样,我不知道我应该在 MySQL 还是 PHP 中执行此操作。如果我在 MySQL 中执行此操作,那么存储和组合此类缓存结果的最佳方式是什么?

4

2 回答 2

3

使用sphinx 搜索引擎可以为您带来神奇的效果。它非常快,甚至可以处理单词形式,这对 SEO 请求很有用。

就 sphinx 而言,制作一个文档 - “产品”,按标签索引,为查询选择适当的排名(例如 MATCH_ALL_WORDS)并使用不同的标签组合运行批处理请求以获得最佳结果。不要忘记使用像 memcahed 或任何其他缓存器。

于 2012-10-15T14:50:55.920 回答
2

我还没有对此进行测试,但是应该可以有一个查询来满足您的第二个目标,而不是触发数百个查询......下面的查询说明了这通常应该如何工作。这个想法是一次组合三个不同的请求,并按专用值分组,只收集那些有任何结果的请求。

SELECT t1.product_id, count(*) FROM tagtable t1, tagtable t2, tagtable t3 WHERE 
t1.product_id = t2.product_id AND 
t2.product_id = t3.product_id AND
t1.tag_type='yourcategoryforShoe' AND t1.tag_value='Shoe' AND
t2.tag_type='product_color' AND t2.tag_value='Black' AND
t3.tag_type='brand'
GROUP BY t3.tag_value
HAVING count(*) > 0
于 2012-10-15T14:40:26.740 回答