跨服务器的Mysql查询,不使用联合表

时间:2016-04-20 15:03:23

标签: php mysql database

我将我的数据库中的一些表格移动到另一台服务器并且不想使用 联合表有很多原因(性能是主要原因)。所以我必须在我的PHP类中创建2个不同的连接 并在不同服务器的表之间连接的代码中重写我的查询。

例如,我有两个表:位于不同服务器中的用户和企业。

当它在同一台服务器上时,查询是:

select name from Enterprise E 
inner join Users U on E.cod = U.cod
where E.cod = $my_code and U.codUsers in ($users);

所以我改为:

$rst= select group_concat(U.cod) from Users as U 
where U.codUsers in ($users)

select name from Enterprise E
where E.cod = $mycode and E.cod in ($rst);

我的问题是,当我有这种类型的查询时,我怎样才能做到这一点:

select e.name, e.datebegin, e.dateend from Enterprise E
leftjoin ( select h.callQuantity, h.history from thirdtable 
       inner join Users u on e.cod = u.cod
       where u.codHistory in (1,2,3)
           group by u.cod)

我的问题很明确?对不起我的英文

2 个答案:

答案 0 :(得分:10)

首先,联合表是更好的解决方案(它们是针对您尝试手动完成的那种方式而制作的)。但你不想要它们,所以这是下一个最好的事情:

对于比第一个示例更复杂的事情,您应该通过插入表格内容而不是表格来手动模拟远程表格。

我会以这种方式改写你的第一个例子,因为你的第二个例子搞砸了,我甚至不知道你想要在那里表达什么。

使用1台服务器时,您有以下代码:

select name from Enterprise E 
inner join Users U on E.cod = U.cod
where E.cod = $my_code and U.codUsers in ($users);

您现在可以将表替换为表的实际数据:

select name from Enterprise E 
inner join 
   (      select 1 as cod, 4 as codUsers, 20 as codHistory
    union select 2 as cod, 8 as codUsers, 500 as codHistory
    union select 3 as cod, 29 as codUsers, 100 as codHistory
   ) as U
on E.cod = U.cod
where E.cod = $my_code and U.codUsers in ($users);

要做到这一点,你必须将表数据构建为字符串(我在这里使用pdo):

foreach($db->query('select * from Users U where U.codUsers in ($users)') as $row) {
    if($data !== '') { $data .= 'union '; }
    $data .= 'select ' . $row['cod'] . ' as cod, ' 
             . $row['codUsers'] . ' as codUsers, ' 
             . $row['codHistory'] . ' as codHistory '; 
}

当然,您必须使其适合您的Users-table的布局(并且不要忘记一些'用于字符串列),并且您可以省略您不需要的列。

您现在可以将该字符串放在您拥有Users-table之前的任何位置,并将您的代码编写为在1台服务器上,因此您的第一个代码看起来像

select name from Enterprise E 
inner join ($data) as U on E.cod = U.cod
where E.cod = $my_code and U.codUsers in ($users);

和你的第二个代码(虽然我提醒你它已经破了,但不会在1台服务器上运行)看起来像

select e.name, e.datebegin, e.dateend from Enterprise E
leftjoin ( select h.callQuantity, h.history from thirdtable 
       inner join ($data) as u on e.cod = u.cod
       where u.codHistory in (1,2,3)
           group by u.cod)

你应该确保只有少量用户进入你的$ data-string,然后这将正常工作。否则,您确实需要联合表。

答案 1 :(得分:1)

计划A:

从一台计算机上获取可能所需的数据;将结果集放入关联数组中。

同样适用于第二台机器。 (第三......)

使用两个阵列进行游戏。

B计划(与您的第一个案例类似):

从一台计算机上获取可能所需的数据;将结果集放入关联数组中。

建立IN (...);将其添加到第二台计算机的查询中。

从第二台机器取货。

(等)

使用结果集。

计划B可以进行优化'如果您知道哪台机器具有最小的结果集,并从中开始。

PHP具有丰富的数组函数,使得许多操作变得容易。