在单个脚本中连接多个数据库的优缺点

时间:2015-03-17 05:33:36

标签: php mysql sql database database-connection

假设用户在单个主机上托管了两个数据库,我需要连接到这两个数据库,以便我可以随时使用任何表而无需多次添加连接代码。

我在CodeIgniter中实现了这一点,在database.php文件中添加了两个数据库的授权详细信息,并在脚本中加载了$this->load->database('dbname');所需的数据库。

现在,对于核心PHP,我们可以这样做:

mysql_connect ('host','user','password','port','dbname'); // connection with one database.   

它与我的第一个数据库连接。

现在,我想连接第二个数据库:

1)我没有关闭上面的连接并用

与第二个连接
mysql_connect ('host','user','password','port','dbname1');.

2)这样做是不好的做法?它会消耗更多的物体吗?我们是否应该被要求先关闭第一个?

14 个答案:

答案 0 :(得分:14)

仅使用同一服务器上的2个数据库中的表打开2连接是不必要的。您只需要使用database.table表示法。这样做意味着您甚至可以在同一查询中连接来自不同数据库的表

SELECT t1.col1, t1.col2, t2.col2, t2.col2
FROM db1.table1 AS t1 JOIN db2.table1 AS t2 ON t1.col1 = t2.col3

因此,如果您最初已连接到db1,则可以使用db2表,如果连接到db2,则可以使用db2表。

答案 1 :(得分:7)

你试过这个吗?

$mysqli1 = new mysqli("example.com", "user", "password", "database1");

$mysqli2 = new mysqli("example.com", "user", "password", "database2");

答案 2 :(得分:5)

您可以通过遵循面向对象的方法

来实现

首先创建与两个数据库的连接:

$Db1 = new mysqli('localhost','root','','database1'); // this is object of database 1
$Db2 = new mysqli('localhost','root','','database2'); // this is object of database 2

$query1 = 'select * from `table_name_of_database1`';  // Query to be run on DB1
$query2 = 'select * from `table_name_of_database2`';   // Query to be run on DB2

$result1 = $Db1->query($query1); // Executing query on database1 by using $Db1
$result2 = $Db2->query($query2); // Executing query on database2 by using $Db2

echo "<pre>";

/* Print result of $query1 */

if ($result1->num_rows > 0) {
    while($row = $result1->fetch_assoc()) {
        print_r($row);
    }
} else {
    echo "0 results";
}


/*========================================================*/


/* Print result of $query2 */

if ($result2->num_rows > 0) {
    while($row = $result2->fetch_assoc()) {
         print_r($row);
    }
} else {
    echo "0 results";
}

结论:如果您想使用database1使用$Db1对象,并且想要使用database2,请使用$DB2

答案 3 :(得分:5)

为什么需要两个连接?两个数据库的优点/优点实际上主要是性能问题。但如果你在同一台机器上实际上唯一的优势就是更清洁的分离。因此,最好使用一个带有两个不同前缀的DB作为表。 因此,您可以通过前缀而不是DB来分隔不同的数据。

答案 4 :(得分:4)

我不认为如何连接到2个DB同时是问题,因为您已成功完成(或知道如何操作)。我可以从你的问题中收集到。所以我不知道如何做到这一点。如果需要,请参阅其他答案。

但要直接解决您的问题:

  1. 这样做会不好吗?通常,您应尽可能避免同时使用2个DB连接句柄。如果您只需要从一个数据库获取数据并使用它们在另一个数据库上执行某些操作,那么最好的办法是将DB1中的数据放入适当的PHP变量中,关闭连接;然后进行第二次连接。这比同时打开2个DB连接要便宜。但是,如果您正在执行类似INSERT INTO db1.table SELECT FROM db2.table并且还需要根据某些查询的成功或失败提交或回滚,那么AFAIK,您需要保持两个连接都处于打开状态,直到您的进程结束。你看,总是有权衡。因此,您根据申请的需要决定并承担费用。
  2. 作为这个场景的一个实际例子,我曾经在一个项目中工作,我需要SELECT一个table1,INSERT INTO一个table2,如果INSERT成功,我删除table1中的所有行,如果DELETE失败,我回滚INSERT操作因为数据不能同时存在于两个表中。

    当然,我自己的案例只涉及一个DB,所以不需要第二个连接。但假设两个表位于不同的DB上,那么这可能与您的情况类似。

    1. 会消耗更多物品吗?除了上面1中指出的对象之外,没有其他对象,即DB连接根据您的问题处理。

    2. 我们是否应该强制要求首先关闭第一个?再一次,取决于您的应用需求。

答案 5 :(得分:3)

而不是 mysql_connect 使用 mysqli_connect

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

答案 6 :(得分:2)

  

1)是否可以在一个脚本中连接多个数据库?

是的,我们可以在同一个脚本中创建多个MySQL链接标识符。

  

2)应该不要关闭与mysql_close的一个连接并打开一个新连接,而是两个连接应该一次打开,用户可以使用任何数据库中的任何表吗?

使用持久数据库连接,例如mysql_pconnect

  

3)如果有可能,这有什么不利之处?是否会创建两个对象,这会产生问题吗?

我认为除了增加服务器上的负载外,它不会产生任何问题。

答案 7 :(得分:2)

你可以这样使用

$db1 = mysql_connect($hostname, $username, $password); 
$db2 = mysql_connect($hostname, $username, $password, true); 

mysql_select_db('abc', $db1);
mysql_select_db('def', $db2);

对于数据库1

mysql_query('select * from table1', $db1);

对于数据库2

mysql_query('select * from table2', $db2);

答案 8 :(得分:2)

  问:没有关闭以前的数据库,有什么可以与其他数据库连接?

答:当您连接到数据库服务器时,物理上正在分配资源以与您交互,如果两个数据库位于同一服务器上,您将不必要地使用可用于解决其他连接或其他活动的资源。因此,您将是正确的密切连接,无需继续使用。

  问:这是否适合这样做?如果不在每个脚本中多次打开此连接,最好的方法是什么?我希望这只能在核心php中完成,因为我已经在codeigniter中知道了这一点。

SESSIONS的一种方式,但您无法在会话中存储数据库连接。读入PHP.net此警告:&#34;某些类型的数据无法序列化,因此存储在会话中。它包括资源变量或具有循环引用的对象(即将对自身的引用传递给另一个对象的对象)。&#34; MySQL连接就是这样一种资源。

您必须在每次页面运行时重新连接。

如果您可以通过mysql_pconnect()依赖连接池,这并不像听起来那么糟糕。连接时,该功能将首先尝试查找已使用相同主机,用户名和密码打开的(持久)链接。如果找到一个,将返回其标识符而不是打开新连接。当脚本的执行结束时,不会关闭与SQL服务器的连接。相反,该链接将保持打开以供将来使用(mysql_close()不会关闭mysql_pconnect()建立的链接)。

参考:

  

http://php.net/manual/en/function.mysql-pconnect.php

     

http://www.php.net/manual/en/intro.session.php

     

Can't pass mysqli connection in session in php

答案 9 :(得分:2)

使用多个数据库的最佳方法是使用PDO功能

实施例

// database cobfigurations
$config= array(
    // first database
    array(
        'type'=>'mysql',                    // DB type
        'host'=>'localhost',                // DB host
        'dbname'=>'database1',      // DB name
        'user'=>'root',                 // DB username
        'pass'=>'12345',                // DB password
    ),
    // second database
    array(
        'type'=>'mysql',                    // DB type
        'host'=>'localhost',                // DB host
        'dbname'=>'database2',      // DB name
        'user'=>'root',                 // DB username
        'pass'=>'987654',               // DB password
    ),
);
// database connections
$mysql=array();
foreach($config as $con)
{
    $con=(object)$con;
    $start= new PDO($con->type.':host='.$con->host.';dbname='.$con->dbname.'', $con->user, $con->pass, array(
            // pdo setup
            PDO::ATTR_PERSISTENT            => FALSE,
            PDO::ATTR_DEFAULT_FETCH_MODE    => PDO::FETCH_OBJ,
            PDO::ATTR_ERRMODE               => PDO::ERRMODE_EXCEPTION,
            PDO::MYSQL_ATTR_INIT_COMMAND    => 'SET NAMES UTF8'
    ));

    if ($start && !empty($start) && !is_resource($start))
        $mysql[]=$start;    // connection is OK prepare objects
    else
        $mysql[]=false; // connection is NOT OK, return false
}

/**********************
 ****  HOW TO USE ****
**********************/ 

// fetch data from database 1
$data1 = $mysql[0]->query("SELECT id, title, text FROM content1")->fetchAll();
if(count($data1)>0)
{
    foreach($data1 as $i=>$result)
    {
        echo $result->id.' '.$result->title.' '.$result->text.'<br>'
    }
}

// fetch data from database 2
$data2 = $mysql[1]->query("SELECT id, title, text FROM content2")->fetchAll();
if(count($data2)>0)
{
    foreach($data2 as $i=>$result)
    {
        echo $result->id.' '.$result->title.' '.$result->text.'<br>'
    }
}

如果您之前没有使用PDO,请阅读以下简短教程:

http://www.mysqltutorial.org/php-querying-data-from-mysql-table/

实际上与mysql和mysqli连接相同,但更高级,快速和安全。

阅读本文档: http://php.net/manual/en/book.pdo.php

您可以添加2个以上的数据库

答案 10 :(得分:2)

使用php 5版本支持的PDO而不是mysql connect

答案 11 :(得分:1)

这是一个简单的类,可在需要时自动选择所需的数据库。

class Database 
{
    private $host   = 'host';
    private $user   = 'root';
    private $pass   = 'pass';
    private $dbname = '';

    private $mysqli = null;

    function __construct() 
    {
        // dbname is not defined in constructor
        $this->mysqli = new mysqli( $this->host, $this->user, $this->pass );    
    }

    function __get( $dbname ) 
    {
        // if dbname is different, and select_db() is succesfull, save current dbname
        if ( $this->dbname !== $dbname && $this->mysqli->select_db( $dbname ) ) {
            $this->dbname = $dbname;
        }

        // return connection
        return $this->mysqli;
    }
}


// examples
$db = new Database();

$result = $db->db1->query( "SELECT DATABASE()" );
print_r( $result->fetch_row() );

$result = $db->db2->query( "SELECT DATABASE()" );
print_r( $result->fetch_row() );

$result = $db->{'dbname with spaces'}->query( "SELECT DATABASE()" );
print_r( $result->fetch_row() );

答案 12 :(得分:1)

$con1 = mysql_connect($hostname, $username, $password); 
$con2 = mysql_connect($hostname, $username, $password, true); 

mysql_select_db('database1', $con1);
mysql_select_db('database2', $con2);

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

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

和数据库2传递第二个:

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

答案 13 :(得分:0)

如果mysql的用户拥有两个数据库的权限,则可以从两个数据库中连接两个表 等:

SELECT database1.table.title title1,database2.table.title title2 
FROM database1.table
INNER JOIN database2.table 
ON (database1.table.id=database2.table.id)