希望这不是太主观,但是:
我有一个问题,我需要根据ID查询来自四个不同表的数据。此数据具有类似但不相同的字段,需要为每个表显示。基本上,如果我有表A,B,C和D,那么对于id N,我可能需要按以下顺序显示行:
A1
B1
B2
B3
C1
D1
D2
D3
D4
但是,由于B和D中的一些要求我加入许多表,并且我有成千上万的记录,所以我不想为每个id发送四个复杂的查询。我正在预先构建我的数据 - 创建一个临时表,其中包含每个最终的A,B,C,D数据,然后通过ID直接查询这些行。有更快的方法吗?我曾想过使用UNION但我的行并不都有相同类型的列(对于AI类型的行可能需要显示日期,而类型C的行将具有整数天偏移量,例如)。
我目前的做法:
foreach ($ids as $id) {
$a = "SELECT * FROM a JOIN xyz (...) WHERE id = ?";
$b = "SELECT * FROM b JOIN xyz (...) WHERE id = ?";
$c = "SELECT * FROM c JOIN xyz (...) WHERE id = ?";
$d = "SELECT * FROM d JOIN xyz (...) WHERE id = ?";
print query($a, $id)->fetch();
print query($b, $id)->fetchAll();
print query($c, $id)->fetch();
print query($d, $id)->fetchAll();
}
或类似的东西
答案 0 :(得分:1)
首先,我肯定不会4次查询数据库。我会尝试只查询一次DB,即使它需要讨厌的长sql代码,以减少服务器和数据库之间的往返。
就像评论中的“考虑我”和“戈登林诺夫”一样,我将使用所有表中的所有字段和UNION创建单个查询。对于某些表独有的字段,我会在查询其他表时将其设置为“null”。
例如:
select t.description as 'Description', null as 'Value'
from A t
UNION
select null as 'Description', t.value as 'Value'
from B t
您还可以返回所有表的所有字段,并为每个返回的字段添加前缀,以便您知道它来自哪个表。
例如:
select t.description as 'A_Description'
from A t
UNION
select t.value as 'B_Value'
from B t
为了简单,安全和高效,我会将整个sql代码放在一个用户定义的函数中,该函数返回一个表,您可以将其从服务器端代码解释为记录集。该函数将ID作为参数。这也可以以视图的形式实现。
为了提高效率,我会在表格用于连接的每个字段上放置索引,这会大大减少查询时间。
一般情况下,我还会尝试找出每天/小时/分钟/秒调用此函数的次数。 如果经常需要该功能提供的数据,则可能需要采用完全不同的方法 - 重新安排整个数据库。但是,如果数据是静态的或半静态的,那么缓存机制就足够了 - 以另一个DB表,服务器端静态对象甚至是客户端静态对象的形式。
由于需要考虑多种因素,因此您的问题没有简单的答案。