Плюсы и минусы подключения более одной базы данных в одном скрипте

предположим, у пользователя есть две базы данных, размещенные на одном хосте, и мне нужно подключиться к ним обоим, чтобы я мог использовать любую таблицу в любое время без добавления кода подключения несколько раз.

я реализовал это в 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 ответов


нет необходимости открывать соединение 2 только для использования таблиц из 2 баз данных на одном сервере. Вам просто нужно использовать базу данных.табличные обозначения. Это означает, что вы даже можете объединять таблицы из разных баз данных в одном запросе

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 можно использовать таблицы бд1.


вы пробовали это?

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

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

вы можете сделать это, следуя объектно-ориентированного подхода

прежде всего создайте соединение с двумя базами данных:

$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.


зачем вам два подключения? Плюсы / преимущества двух баз данных в основном связаны с производительностью. Но если вы на одной машине на самом деле единственное преимущество, которое у вас есть, было бы более чистое разделение. Поэтому для таблицы лучше использовать один БД с двумя разными префиксами. Таким образом, вы отделяете разные данные по префиксу, а не по БД.


Я не думаю, что проблема в том, как подключиться к 2 DBs одновременно, поскольку вы успешно это сделали (или знаете, как это сделать ). Я понял это из твоего вопроса. Поэтому я не буду показывать как это делать. Смотрите другие ответы, если нужно.

но для решения ваших проблем напрямую:

  1. будет ли это плохой практикой ? Как правило, вы должны избегать 2 одновременных дескрипторов подключения DB как можно больше. Если вам нужно только получить данные из одной БД и использовать их чтобы сделать что-то с другой стороны, лучше всего поместить данные из DB1 в соответствующие переменные PHP, закрыть соединение; затем сделать второе соединение. Это было бы дешевле, чем держать соединения 2 DB открытыми одновременно. Однако, если вы делаете что-то вроде вставки в db1.таблица выберите из db2.таблица, а также нужно зафиксировать или откат в зависимости от успеха или неудачи некоторых запросов, затем AFAIK, вам нужно держать оба соединения открытыми, пока ваши процессы не закончатся. Ты видишь, всегда есть компромиссы. Так вы решаете основанный на потребности вашего применения и несете цену.

в качестве практического примера этого сценария я однажды работал над проектом, где мне нужно было выбрать table1, вставить в table2, если вставка завершится успешно, я удалю все строки из table1, если удаление не удастся, я откатываю операцию вставки, потому что данные не могут жить в двух таблицах одновременно.

конечно, мой собственный случай включал только один DB, поэтому не нужно второй связи. Но если предположить, что две таблицы были на разных DBs, то это может быть похоже на вашу ситуацию.

  1. будет ли он потреблять больше объектов ? Никаких других объектов, кроме указанных в 1 выше, а именно дескрипторов подключения к БД в соответствии с вашим вопросом.

  2. должны ли мы принудительно требовать закрыть первый в любом случае ? Еще раз, в зависимости от ваших потребностей приложения.


вместо соединение использовать mysqli_connect.

mysqli обеспечивает функциональность для connect несколько баз данных одновременно.


1) Можно ли подключиться к нескольким базам данных в одном скрипте ?

Да, мы можем создать несколько идентификаторов ссылок MySQL в одном скрипте.

2) это не должно быть похоже на закрытие одного соединения с mysql_close и открытие нового,скорее, оба соединения должны открываться одновременно, и пользователь может использовать любую таблицу из любой базы данных ?

использовать постоянные подключения к базе данных, такие как постоянные соединения

3) Если это возможно,что может быть недостатком ? Будет ли создано два объекта, и это создаст проблему ?

Я не думаю, что это создает какие-либо проблемы, кроме увеличения некоторой нагрузки на сервер.


вы можете использовать такой

$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);

лучший способ использовать несколько баз данных-использовать функции 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 баз данных


Q: какие минусы есть для подключения к другой базе данных без закрытия предыдущей базы данных?

A: при подключении к серверу баз данных физически назначаются ресурсы для взаимодействия с вами, если две базы данных находятся на одном сервере, вы бы излишне использовать ресурсы, которые могут быть использованы для решения других подключений или других действий. Поэтому вы будете правы, закрывая соединения, которые не нужно продолжать использовать.

Q: Является ли это подходящей практикой для этого ? Каков наилучший способ сделать это, не открывая это соединение в каждом скрипте несколько раз ? Я хочу, чтобы это было сделано в основном php, так как я уже знаю это в codeigniter.

односторонние сеансы, но вы не можете хранить соединения базы данных в сеансах. Читайте в PHP.net это предупреждение: "некоторые типы данных не могут быть сериализованы, хранящиеся в сессии. Он включает переменные ресурса или объекты с круговым ссылки (т. е. объекты, которые передают ссылку на себя другому объекту)."Соединения MySQL являются одним из таких ресурсов.

вы должны повторно запустить на каждой странице.

- Это не так плохо, как кажется если вы можете рассчитывать на объединение подключений через постоянные соединения(). При подключении функция сначала попытается найти (постоянную) ссылку, которая уже открыта с тем же хостом, именем пользователя и паролем. Если один найден, идентификатор для него будет возвращается вместо открытия нового соединения. Соединение с SQL server не будет закрыто после завершения выполнения сценария. Вместо этого, ссылка останется открытой для последующего использования (mysql_close() не будет закрывать ссылки, установленные mysql_pconnect()).

ссылки:

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

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

не могу пройти mysqli подключение в сессии в php


используйте PDO, поддерживаемый версией php 5, вместо mysql connect


вот простой класс, который выбирает нужную базу данных автоматически, когда это необходимо.

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() );

$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);

если у пользователя mysql есть разрешение на две базы данных , вы можете присоединиться к двум таблицам из двух баз данных и т. д.:

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