连接来自不同数据库的两个表

Posted

技术标签:

【中文标题】连接来自不同数据库的两个表【英文标题】:Joining two tables from different databases 【发布时间】:2013-04-22 14:10:48 【问题描述】:

我知道有很多关于此的帖子,但我无法使其适用于我的代码。

正如标题所示,我想将来自两个不同数据库的两个表连接在一起。

这是我的代码:

 $dbh1 = mysql_connect("$host", "$username", "$password")or die("cannot connect"); 
    $dbh2 = mysql_connect("$host2", "$username2", "$password2", true)or die("cannot connect"); 
    mysql_select_db("$db_name", $dbh1)or die("cannot select DB");
    mysql_select_db("$db_name2", $dbh2)or die("cannot select DB");

//first table  
//$sql = mysql_query("SELECT InterestedEntityId, Score FROM users.`user_interests` WHERE UserId= //$userID ORDER BY Score DESC", $dbh1);

//second table
//$sql = mysql_query("SELECT entities.`Name` FROM tags.`entities` WHERE Id = InterestedEntityId", $dbh2);

我想一次性获取 select 语句中提到的 3 个字段(即 InterestedEntityId、Score、entities.Name

关于如何在一个 sql 查询中连接这两个表的任何想法。我尝试使用内部连接并添加表名(如this 线程建议的那样),但查询没有返回任何内容。

有什么想法吗?

【问题讨论】:

您需要有权限才能使用您的用户访问这两个数据库,并在表名之前添加数据库名称。 当然可以。我的那部分代码出现在我的原始脚本中:) 【参考方案1】:

这样的事情应该可以工作。

SELECT t1.InterestedEntityId, t1.Score, t2.Name
  FROM DB1.users.`user_interests` t1
  JOIN DB2.tags.`entities` t2 ON t2.UserId = t1.Id

注意:使用 PDO 因为 mysql_* 已被弃用且不够安全。

【讨论】:

【参考方案2】:

模型差不多是:

SELECT dbName1.TableName1.ColumnName1, dbName2.TableName2.ColumnName2 FROM dbName1.TableName1 JOIN dbName2.TableName2 ON dbName1.TableName1.ColumnName1 = dbName2.TableName2.ColumnName2

【讨论】:

【参考方案3】:

Please, don't use mysql_* functions in new code。它们不再维护and are officially deprecated。看到red box?改为了解prepared statements,并使用PDO 或MySQLi - this article 将帮助您决定哪个。如果你选择 PDO,here is a good tutorial。


虽然理论上可以在同一台服务器上连接来自两个不同数据库的表,但您尝试执行的操作可能无法正常工作,因为您似乎正在访问两个不同的服务器。

为了获得您想要的结果集,您需要手动组合它们。

例如(使用 PDO):

$dsn1 = "mysql:host=$host;dbname=$db_name";
$dsn2 = "mysql:host=$host2;dbname=$db_name2";

try 
    // Create the connections
    $db1 = new PDO($dsn1, $username, $password);
    $db1->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db1->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $db1->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

    $db2 = new PDO($dsn2, $username2, $password2);
    $db2->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db2->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $db2->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

    // Get the initial recordset
    $sql1 = "
        SELECT InterestedEntityId, Score
        FROM `user_interests`
        WHERE UserId = :userId
        ORDER BY Score DESC
    ";
    $stmt1 = $db1->prepare($sql1);
    $stmt1->bindParam('userId', $userID, PDO::PARAM_INT);
    $stmt1->execute();

    // Prepare the statement for the second database
    $sql2 = "
        SELECT Name
        FROM entities
        WHERE Id = :entityId
    ";
    $entityId = 0;
    $stmt2 = $db2->prepare($sql2);
    $stmt2->bindParam('id', $entityId, PDO::PARAM_INT);

    // Loop the first result set
    $result = array();
    foreach ($stmt1 as $row1) 
        // Fetch the related data from the second DB
        $entityId = $row1['InterestedEntityId'];
        $stmt2->execute();
        $row2 = $stmt2->fetch();

        // Construct the final result row and store it
        $result[] = array(
            'InterestedEntityId' => $row1['InterestedEntityId'],
            'Score' => $row1['Score'],
            'Name' => $row2['Name']
        );
    
 catch(PDOException $e) 
    die($e->getMessage());


// The result set you want should now be available
var_dump($result);

【讨论】:

我想到了这一点,但这样做需要我获取名称,然后附加该表的每一行。这很浪费,更不用说花费太多时间了。 @Shane 如果您正在处理两个不同的数据库服务器,那么实际上没有其他方法。如果$host$host2 的值始终相同,那么您可以查看一个连接 - 但在这种情况下您不需要这两个连接。如果您按照代码建议处理两个不同的服务器,请检查我的编辑。 @Shane 有比这更快的方法(例如,您的脚本读取一个表,将内容保存在 CSV 中,然后使用 LOAD TABLE... 将该 CSV 放入另一个数据库),但仍然不快。 @Kickstart 确实,实际上最好的方法是确保所有需要的数据都在一个数据库中可用,所以它只是一个简单的@987654334 @。我猜是因为 OP 在问这个问题根本不可能 - 但也许我假设我不应该...... @DaveRandom - 我同意。当数据在不同的数据库服务器上拆分时,您会遇到一个大问题。几乎破坏了关系数据库的整个想法。但是,如果数据位于 2 个单独的服务器上,则可以将其复制过来进行连接,那么 LOAD TABLE... 是一种效率较低的方法。我是否会费心去做这件事在很大程度上取决于这需要的频率,以及每台服务器上涉及的数据量。也可能是使用联合数据库的想法 - dev.mysql.com/doc/refman/5.1/en/federated-storage-engine.html

以上是关于连接来自不同数据库的两个表的主要内容,如果未能解决你的问题,请参考以下文章

如何连接来自两个不同数据库(ms.access 和 mysql)的三个表?

连接来自不同数据库的同名表的结果

连接来自两个不同表的两列

我们可以对两个不同的数据库表使用连接吗?

MariaDB 根据列值连接来自不同数据库的表

连接来自两个不同数据库的 3 个表?