【问题标题】:Searching product for description and keywords in separate table在单独的表格中搜索产品的描述和关键字
【发布时间】:2021-04-07 19:29:16
【问题描述】:

我有两张MySQL表,一张保存产品,一张保存关键字;

    CREATE TABLE IF NOT EXISTS `products` (
      `id` int(6) unsigned NOT NULL,
      `title` varchar(200) NOT NULL,
      `description` varchar(200) NOT NULL,
      PRIMARY KEY (`id`)
    ) DEFAULT CHARSET=utf8;

    INSERT INTO `products` (`id`, `title`, `description`) 
    VALUES
      ('1', 'Product 1', 'Vacuum cleaner'),
      ('2', 'Product 2', 'Refrigerator'),
      ('3', 'Product 3', 'Mixer'),
      ('4', 'Product 4', 'Stereo');

    CREATE TABLE IF NOT EXISTS `keywords` (
      `keyid` int(6) unsigned NOT NULL,
      `productid` int(6) unsigned NOT NULL,
      `keyword` varchar(200) NOT NULL,
      PRIMARY KEY (`keyid`)
    ) DEFAULT CHARSET=utf8;

    INSERT INTO `keywords` (`keyid`, `productid`, `keyword`) 
    VALUES
      ('1', '1', 'white matte'),
      ('2', '1', '100W'),
      ('3', '3', 'shiny black'),
      ('4', '3', '15W'),
      ('5', '4', '350W');

ID Title Description
1 Product 1 Vacuum cleaner
2 Product 2 Refrigerator
3 Product 3 Mixer
ProductID Keyword
1 White matte
1 100W
3 Shiny black
3 25W

有些产品会有关键字,有些则没有。

现在我想以搜索标题、描述和所有关键字的方式查询产品。

例如,我想搜索“白色 100W”,以便在这种情况下找到产品 1。

我将所有搜索词放在一个数组中,然后进行这样的查询:

SELECT p.id
     , p.title 
      FROM products AS p 
  LEFT 
  JOIN keywords AS k 
    ON k.productID = p.ID 
 WHERE
     (p.title LIKE '%white%' 
    OR p.description LIKE '%white%' 
    OR k.keyword LIKE '%cleaner%') 
   AND 
     (p.title LIKE '%100W%' 
    OR p.description LIKE '%100W%' 
    OR k.keyword LIKE '%100W%') 
 GROUP 
    BY p.ID

更新:这是一个 SQLfiddle http://sqlfiddle.com/#!9/8114e9/2 它返回零行,因为在连接中只考虑了第一个关键字。我希望它浏览所有关键字(实际上通常是 20-30)。

解决这个问题最有效的方法是什么?我尝试查看 GROUP_CONCAT(所有关键字) AS 关键字和 HAVING 关键字 LIKE ... 但是当没有关键字或我只是搜索部分描述时,这不起作用。

我也研究了一个UNION,基本上是在做

SELECT ... FROM products WHERE title LIKE ... OR description LIKE ...
UNION
SELECT ... FROM keywords WHERE keyword LIKE ...

但这似乎效率低得多,执行时间长。 这里最有效的解决方案是什么?

【问题讨论】:

  • 对不起,我添加了一个 SQL 小提琴
  • 如果你去掉 OR 是不是基本上过滤了WHERE p.title LIKE '%white%' AND p.title LIKE '%100W%'?而且由于您没有包含其中任何一个的 title 值,因此它不会返回任何内容。如果将AND 替换为另一个ORthis is what happen

标签: mysql


【解决方案1】:

开头带有通配符的LIKE 不能使用任何索引。所以对于product,无论如何你都会进行全表扫描。因此,您使用析取析取的解决方案就足够了。

对于keywords,您可以将EXISTS 与相关子查询一起使用。 keywords (productid)keywords (productid, keyword) 上的索引可能有助于限制对真正属于该产品的关键字的 LIKE 进行昂贵的扫描。

SELECT p.id,
       p.title
       FROM products p
       WHERE <disjunction for p.title>
              OR
              <disjunction for p.description>
               OR EXISTS (SELECT *
                                 FROM keywords k
                                 WHERE k.productid = p.id
                                       AND (<disjunction for k.keyword>);

但可能想要完全重构并尝试改用full-text indexessearch functions

【讨论】:

    猜你喜欢
    • 2015-03-23
    • 2015-03-07
    • 2020-07-02
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 2022-09-23
    • 2011-03-27
    • 2019-07-29
    相关资源
    最近更新 更多