我想对多个表执行简单搜索 并接收搜索命中和一些其他信息
我的数据库架构
(ID列是不同表的外键,条目是varchars)
让我们说table1包含(1,' abc',' def',' ghi')
和table2包含(1,' test',''''')
使用' test'进行搜索应该返回类似的东西 '测试'' ABC'' DEF'' GHI'
选项1:
加入所有表并选择正确的行
Select * from
big_Table_with_all_ID as t0
/* mysql does not support FULL JOIN. we avoid this with LEFT-JOINS on
a table containing all IDs. Not exactly the same */
left join
table1 as t1
on t0.id = t1.id
left join
table2 as t2
on t0.id = t2.id
[...]
left join
table5 as t5
on t0.id = t5.id
where t1.entry1 like '%search%' or
t1.entry2 like '%search%' or
[...]
t5.entry3 like '%search%'
这不会标记'搜索命中(可由客户完成) 应该是最糟糕的选择,因为加入了太多的数据,包括 输出中的大量信息
选项2:添加子查询
加入'过滤'表
Select * from
big_Table_with_all_ID as t0
left join
(Select id,entry1 from table1 where entry1 like '%search%') as t1
on t0.id = t1.id
left join
(Select id,entry2 from table1 where entry2 like '%search%') as t2
on t0.id = t2.id
[...]
left join
(Select id,entry3 from table5 where entry3 like '%search%') as t15
on t0.id = t15.id
left join
table1
on t0.id = table1.id;
输出:
ID|table1 |table2 |...|table1 |
1 |NULL|NULL|NULL|'test'|NULL|NULL|...|'abc'|'dfg'|'ghi'|
即使没有搜索命中,也会包含每个ID(仅限NULL值) (可以通过从option1添加where子句来解决)
选项3:UNION
UNION'过滤'表和加入其他数据
Select hit,entry1,entry2,entry3 from
(
Select * from
(
Select id,entry1 as hit from table1 where entry1 like '%search%'
UNION
Select id,entry2 as hit from table1 where entry2 like '%search%'
[...]
UNION
Select id,entry3 as hit from table5 where entry3 like '%search%'
) as tmp
group by id
) as tmp
left join
table1
on tmp.id = table1.id
where hit is not null
输出:
hit |entry1|entry2|entry3
'test'|'abc' |'def' |'ghi'
不包含不必要的信息
我应该选择哪种选择/替代方案,以获得“好”的选择。性能 和可读性?
答案 0 :(得分:0)
选项1不好,因为mysql可能会出现连接多个表的问题,我不会使用它。考虑到子查询的结果很小(只有1行)的事实,我认为选项2和3是相似的。
答案 1 :(得分:0)
我认为您想在第三种方法中使用变体:
Select t1.*, entry1, entry2, entry3
from (Select id, max(entry1) as entry1,
max(entry2) as entry2, max(entry3) as entry3
from (Select id, entry1 as hit, NULL as entry2, NULL as entry3 from table1 where entry1 like '%search%'
UNION ALL
Select id, NULL, entry2 as hit, NULL from table2 where entry2 like '%search%'
[...]
UNION ALL
Select id, NULL, NULL, entry3 as hit from table5 where entry3 like '%search%'
) as tmp
group py id
) as tmp join
table1 t1
on tmp.id = t1.id;
一些意见:
union all
而不是union
来避免不必要的重复消除。select *
与group by
一起使用。结果是不确定的。like
在开头有一个通配符),但如果合适,单独的查询可以各自利用索引。hit is not null
应该做什么。我认为join
捕获了正确的逻辑。