如何在单个网页上连接到多个MySQL数据库?


179

我的信息分散在几个数据库中,并希望使用PHP将所有信息放到一个网页上。我想知道如何在单个PHP网页上连接到多个数据库。

我知道如何使用以下方法连接到单个数据库:

$dbh = mysql_connect($hostname, $username, $password) 
        or die("Unable to connect to MySQL");

但是,我可以使用多个“ mysql_connect”命令打开其他数据库吗?如果我确实连接了多个数据库,PHP将如何知道我要从哪个数据库中提取信息?

Answers:


335

警告: mysql_xx自php 5.5起不推荐使用功能,自php 7.0起不推荐使用功能(请参阅http://php.net/manual/intro.mysql.php),请使用mysqli_xx功能或从@Troelskn查看以下答案


您可以多次调用mysql_connect(),但是如果参数相同,则需要为' $new_link'(第四个)参数传递true ,否则将重复使用相同的连接。例如:

$dbh1 = mysql_connect($hostname, $username, $password); 
$dbh2 = mysql_connect($hostname, $username, $password, true); 

mysql_select_db('database1', $dbh1);
mysql_select_db('database2', $dbh2);

然后要查询数据库1,传递第一个链接标识符:

mysql_query('select * from tablename', $dbh1);

对于数据库2,通过第二个:

mysql_query('select * from tablename', $dbh2);

如果未传递链接标识符,那么将使用最后创建的连接(在这种情况下为表示的连接$dbh2),例如:

mysql_query('select * from tablename');

其他选择

如果MySQL用户可以访问两个数据库,并且它们在同一主机上(即,两个DB可以从同一连接访问),则可以:

  • 保持一个连接处于打开状态,并mysql_select_db()在必要时进行呼叫以进行交换。我不确定这是否是干净的解决方案,您最终可能会查询错误的数据库。
  • 在查询中引用表时,请指定数据库名称(例如SELECT * FROM database2.tablename)。实施起来可能很痛苦。

另外,请阅读troelskn的答案,因为如果您能够使用PDO而不是较旧的扩展名,那么这是一种更好的方法。


2
+1这个解决方案对我有用。经过两天的调试,为什么我的自定义WordPress模板在调用第二个数据库连接后为何无法访问$ WP_Query对象……
Eddie

是否可以将其中之一设置为默认之一,而$dbh2仅在需要时才添加第二个?仅需查找所有查询,就必须更改所有查询才能使用此方法……
ThomasK,2012年

@ThomasK,您可以将mysql_query包装在具有默认参数的函数中,例如,db_query($query,$db='db1')然后大规模更新所有旧查询,db_query($query)然后自定义将非默认查询更新为db_query($query,'db2')
joshuahedlund 2012年

使用您的方法,如果我定义了两个连接但未指定在查询中使用哪个连接,将使用哪个连接?
彼得

1
@Peter:根据php.net/manual/en/function.mysql-query.php:–If the link identifier is not specified, the last link opened by mysql_connect() is assumed.
Tom Haigh

97

如果使用PHP5(并且应该弃用PHP4),则应该使用PDO,因为这正逐渐成为新的标准。PDO的一个(非常)重要的好处是,它支持绑定参数,这使代码更加安全。

您将通过PDO进行连接,如下所示:

try {
  $db = new PDO('mysql:dbname=databasename;host=127.0.0.1', 'username', 'password');
} catch (PDOException $ex) {
  echo 'Connection failed: ' . $ex->getMessage();
}

(当然,请替换上面的数据库名称,用户名和密码)

然后,您可以像这样查询数据库:

$result = $db->query("select * from tablename");
foreach ($result as $row) {
  echo $row['foo'] . "\n";
}

或者,如果您有变量:

$stmt = $db->prepare("select * from tablename where id = :id");
$stmt->execute(array(':id' => 42));
$row = $stmt->fetch();

如果您需要一次打开多个连接,则可以简单地创建多个PDO实例:

try {
  $db1 = new PDO('mysql:dbname=databas1;host=127.0.0.1', 'username', 'password');
  $db2 = new PDO('mysql:dbname=databas2;host=127.0.0.1', 'username', 'password');
} catch (PDOException $ex) {
  echo 'Connection failed: ' . $ex->getMessage();
}

5
为什么这个答案不在顶部?这是正确的解决方法。
Aditya MP

10
在我看来,@ aditya menon常常认为正确的做事方法不是对当前问题的正确答案。Asker在他的问题中没有使用PDO,而是使用php本地mysql函数,因此我认为最合适的答案将遵循asker代码。
乔纳森·多斯·桑托斯

2
@adityamenon由谁管理?记住用户永远是对的... PDO是最好的方法,但是两种方法都是解决用户问题的正确方法。请注意正确与最佳之间的区别。是的...我很无聊,所以我不得不发表声明。
贾斯汀·卡兹(JustinKaz)2012年

$ db1和$ db2代表多个mysql连接吗?如果是这样,那不是很好。有没有办法通过一个连接容纳多个数据库?
datasn.io

@kavoir为什么要这样?如果需要,您可以使用来更改当前连接上的数据库use DATABASENAME,但是我没有意义吗?
troelskn 2014年

9

我只是让我的生活变得简单:

CREATE VIEW another_table AS SELECT * FROM another_database.another_table;

希望对您有帮助...干杯...


1
如果两个数据库中都没有同名的表,这是最简单的解决方案。您只需执行一次,然后就不必再担心多个数据库。
Erel Segal-Halevi

@ ErelSegal-Halevi,只要您仅需要对其他数据库的数据进行只读访问,对吗?
Buttle Butkus

6

代替mysql_connect,使用mysqli_connect

mysqli提供了一次连接多个数据库的功能。

$Db1 = new mysqli($hostname,$username,$password,$db_name1); 
// this is connection 1 for DB 1

$Db2 = new mysqli($hostname,$username,$password,$db_name2); 
// this is connection 2 for DB 2

1
$ hostname ='您的DB_Hostname'; $ username ='您的DB_Username'; $ password ='您的DB_password'; $ db_name1 ='您的DB_Name 1'; $ db_name2 ='您的DB_Name 2';
kaushik

这根本mysql_connect
无法解决

4

试试下面的代码:

    $conn = mysql_connect("hostname","username","password");
    mysql_select_db("db1",$conn);
    mysql_select_db("db2",$conn);

    $query1 = "SELECT * FROM db1.table";
    $query2 = "SELECT * FROM db2.table";

您可以从两个数据库中获取上述查询的数据,如下所示

$rs = mysql_query($query1);
while($row = mysql_fetch_assoc($rs)) {
    $data1[] = $row;
}

$rs = mysql_query($query2);
while($row = mysql_fetch_assoc($rs)) {
    $data2[] = $row;
}

print_r($data1);
print_r($data2);

给定两个查询将相同的方式工作,而无需调用mysql_select_db甚至有一次-也叫了两次中间无别的也没用
尼科·哈泽

4
$dbh1 = mysql_connect($hostname, $username, $password);  
$dbh2 = mysql_connect($hostname, $username, $password, true); 

mysql_select_db('database1', $dbh1); 
mysql_select_db('database2',$dbh2); 

mysql_query('select * from tablename', $dbh1);
mysql_query('select * from tablename', $dbh2);

这是我使用的最明显的解决方案,但请记住,如果两个数据库的用户名/密码在同一主机中完全相同,则此解决方案将始终使用第一个连接。因此,请不要混淆在这种情况下这是行不通的。您需要做的是,为2个数据库创建2个不同的用户,它将正常工作。


3

除非您确实需要一个以上的PDO对象实例,否则请考虑以下事项:

$con = new PDO('mysql:host=localhost', $username, $password, 
      array(PDO::ATTR_PERSISTENT => true));

注意dbname=构造参数中没有。

通过终端或其他工具连接到MySQL时,不需要数据库名称。您可以USE dbname通过PDO::exec()方法使用语句在数据库之间切换。

$con->exec("USE someDatabase");
$con->exec("USE anotherDatabase");

当然,您可能希望将其包装在catch try语句中。


对于那些愿意尝试上述方法的人,请在stackoverflow.com/a/14933070/1623579
TheFrost 2013年

我喜欢这个解决方案!我可以在没有持久设置的情况下进行操作,但是PDO的实例化是一个很好的解决方案。您将获得默认连接,而无需连接到特定数据库。
Chuck Burgess 2015年

2

您也许可以使用MySQLi语法,这将使您更好地处理它。

定义数据库连接,然后每当要查询数据库之一时,指定正确的连接。

例如:

$Db1 = new mysqli('$DB_HOST','USERNAME','PASSWORD'); // 1st database connection 
$Db2 = new mysqli('$DB_HOST','USERNAME','PASSWORD'); // 2nd database connection

然后要在同一页面上查询它们,请使用类似以下内容:

$query = $Db1->query("select * from tablename")
$query2 = $Db2->query("select * from tablename")
die("$Db1->error");

以这种方式更改为MySQLi将为您提供帮助。


请改进您的语法(这不是短信),并使用工具(例如Ctrl + K)格式化代码。
fedorqui'SO停止伤害

2

您实际上并不需要select_db。您可以同时将查询发送到两个数据库。首先,给予补助金DB1从选择DB2GRANT select ON DB2.* TO DB1@localhost;。然后,FLUSH PRIVILEGES;。最后,您可以执行“多数据库查询”之类的操作SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2(不要忘记您需要使用“ root”权限才能使用Grant命令)


1

如果您使用的是mysqli并具有两个db_connection文件。像第一个是

define('HOST','localhost');
define('USER','user');
define('PASS','passs');
define('**DB1**','database_name1');

$connMitra = new mysqli(HOST, USER, PASS, **DB1**);

第二个是

    define('HOST','localhost');
    define('USER','user');
    define('PASS','passs');
    define(**'DB2**','database_name1');

    $connMitra = new mysqli(HOST, USER, PASS, **DB2**);

因此,只需更改mysqli中参数传递的名称,例如DB1和DB2。如果您在mysqli中传递相同的参数,假设两个文件中都有DB1,则第二个数据库将不再连接。因此请记住,当您使用两个或多个连接时,请在mysqli函数中传递不同的参数名称


-1
<?php
    // Sapan Mohanty
    // Skype:sapan.mohannty
    //***********************************
    $oldData = mysql_connect('localhost', 'DBUSER', 'DBPASS');
    echo mysql_error();
    $NewData = mysql_connect('localhost', 'DBUSER', 'DBPASS');
    echo mysql_error();
    mysql_select_db('OLDDBNAME', $oldData );
    mysql_select_db('NEWDBNAME', $NewData );
    $getAllTablesName    = "SELECT table_name FROM information_schema.tables WHERE table_type = 'base table'";
    $getAllTablesNameExe = mysql_query($getAllTablesName);
    //echo mysql_error();
    while ($dataTableName = mysql_fetch_object($getAllTablesNameExe)) {

        $oldDataCount       = mysql_query('select count(*) as noOfRecord from ' . $dataTableName->table_name, $oldData);
        $oldDataCountResult = mysql_fetch_object($oldDataCount);


        $newDataCount       = mysql_query('select count(*) as noOfRecord from ' . $dataTableName->table_name, $NewData);
        $newDataCountResult = mysql_fetch_object($newDataCount);

        if ( $oldDataCountResult->noOfRecord != $newDataCountResult->noOfRecord ) {
            echo "<br/><b>" . $dataTableName->table_name . "</b>";
            echo " | Old: " . $oldDataCountResult->noOfRecord;
            echo " | New: " . $newDataCountResult->noOfRecord;

            if ($oldDataCountResult->noOfRecord < $newDataCountResult->noOfRecord) {
                echo " | <font color='green'>*</font>";

            } else {
                echo " | <font color='red'>*</font>";
            }

            echo "<br/>----------------------------------------";

        }     

    }
    ?>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.