mysql - 在单独的表格中搜索产品的描述和关键字
问题描述
我有两张 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 | 标题 | 描述 |
---|---|---|
1 | 产品一 | 吸尘器 |
2 | 产品 2 | 冰箱 |
3 | 产品 3 | 混合器 |
产品编号 | 关键词 |
---|---|
1 | 白色哑光 |
1 | 100W |
3 | 闪亮的黑色 |
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(all keywords) AS 关键字和 HAVING 关键字 LIKE ... 但是当没有关键字或我只是搜索部分描述时,这不起作用。
我还研究了一个UNION,基本上是在做
SELECT ... FROM products WHERE title LIKE ... OR description LIKE ...
UNION
SELECT ... FROM keywords WHERE keyword LIKE ...
但这似乎效率低得多,执行时间长。这里最有效的解决方案是什么?
解决方案
LIKE
以通配符开头的A不能使用任何索引。所以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>);
推荐阅读
- node.js - 有没有办法在 VS CODE 中完全使用 twilio 进行开发?
- wpf - WPF Datagrid 组排序
- redirect - 将 301 blogspot 重定向到新域的问题
- python - 转换(展平)多个标头 Pandas 数据帧
- openstack - 我在 ubunto 18 上尝试 intall openstack 但是当我使用这个命令时 ./stack.sh 没有工作
- android - 我试图将我的颤振应用程序与 firebase 连接起来,但我发现了这个错误
- mysql - 使用 SQL JOIN,如何将一张表的结果限制为最近的记录
- reactjs - 在对输入变量做出反应时使用状态的最佳方法是什么?
- python - Python:将字典列表转换为 JSON 对象
- r - 如何使用引用列名的循环在 r 中执行乘法?