【发布时间】:2011-10-19 15:22:59
【问题描述】:
我正在使用 MySQL 和 PHP 在现有表结构上创建搜索。
可以输入多个搜索关键字,用户可以选择匹配 ALL 或 ANY。 any 形式并不太难,但我正在为 AND 形式编写一个有效的解决方案。
以下是AND形式,所以必须找到所有的搜索关键字。
我必须使用(搜索)的 2 个表具有如下结构:
表 1 - item_id(非唯一) - 文字
表2 - item_id(唯一) - text_a - text_b - text_c
(真正的解决方案还有第三个表,但其结构与表 1 相同。表 2 将有大约 20 个可搜索列)
Table1 中的每个 item_id 可以有多行不同的文本。
假设只有 2 个搜索关键字(在现实生活中可能更多),那么两者都必须存在于: - 都在单行/列中 或者: - 在可能不同表的 2 个不同列中。 或者: - 在具有相同 item_id 的 2 个不同行中(如果在 Table1 的不同行中找到两个关键字)
我所能想到的只是非常密集的子查询,但这会导致服务器停机或响应时间很长。
由于我使用的是 PHP,我可以使用中间查询并存储结果以供以后的最终查询使用。
大家有什么好的建议吗?
编辑:那里需要真实的例子,所以就在这里。
考虑以下 2 个包含数据的表:
表 1
+---------+-----------+-----------+-----------+-----------+
| item_id | t1_text_a | t1_text_b | t1_text_c | t1_text_d |
+---------+-----------+-----------+-----------+-----------+
| 1 | aaa bbb | NULL | ccc | ddd |
| 2 | aaa ccc | ddd | fff | ggg |
| 3 | bbb | NULL | NULL | NULL |
+---------+-----------+-----------+-----------+-----------+
表2
+---------+----------+---------+
| item_id | sequence | t2_text |
+---------+----------+---------+
| 1 | 1 | kkk lll |
| 2 | 1 | kkk |
| 2 | 2 | lll |
| 3 | 1 | mmm |
+---------+----------+---------+
PS 在真实数据库中(我无法更改,因此全文索引或更改表定义不是一个选项)Table1 有大约 20 个可搜索列,并且有 2 个表,如 Table2。这不应该对解决方案产生影响,尽管这是从性能角度考虑的问题。
搜索示例:
关键词:aaa bbb
应该返回:
- item_id=1。这两个关键字都可以在 t1_text_a 列中找到。
关键字:ccc ddd
应该返回:
- item_id=1。 “ccc”在 t1_text_c 中找到,“ddd”在 t1_text_d 中找到。
- item_id=2。在 t1_text_a 中找到“ccc”,在 t1_text_b 中找到“ddd”。
关键字:kkk lll
应该返回:
- item_id=1。在 t2_text 列的 Table2 的单行中找到这两个关键字。
- item_id=2。两个关键字都在表 2 中找到,但在具有相同 item_id 的单独行中。
关键词:bbb mmm
应该返回:
- item_id=3。 “bbb”在 table1.t1_text_a 中找到,“mmm”在 table2.t2_text 中找到。
我目前的进步
实际上,我现在已经放弃尝试在大部分 SQL 中捕捉到这一点。
我所做的是为每个表创建一个查询,检索与至少 1 个搜索关键字匹配的任何行。如果只有 1 个搜索关键字,则查询使用 LIKE,否则使用 REGEXP 'keyword1|keyword2'。
这些行被放入一个 PHP 数组中,其中 item_id 作为索引,所有字符串(可搜索的列)的串联作为值。完成检索所有可能的行后,我在数组中搜索与串联字段中的所有关键字匹配的行。
很可能不是最佳解决方案,如果搜索将返回许多至少有 1 个匹配的候选行,它的扩展性也不会很好。
【问题讨论】:
-
别害羞...展示你的尝试