Как вы подключаетесь к нескольким базам данных MySQL на одной веб-странице?

179

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

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

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

Однако можно ли использовать несколько команд «mysql_connect» для открытия других баз данных и как PHP узнает, из какой базы данных я хочу получить информацию, если у меня есть несколько подключенных баз данных.

JoshFinnie
источник

Ответы:

335

Предупреждение: mysql_xx функции устарели начиная с php 5.5 и удалены начиная с php 7.0 (см. Http://php.net/manual/intro.mysql.php ), используйте mysqli_xxфункции или посмотрите ответ ниже от @Troelskn


Вы можете сделать несколько вызовов mysql_connect(), но если параметры одинаковы, вам нужно передать true для параметра ' $new_link' (четвертый), в противном случае одно и то же соединение используется повторно. Например:

$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 имеет доступ к обеим базам данных, и они находятся на одном и том же хосте (то есть обе базы данных доступны через одно и то же соединение), вы можете:

  • Держите одно соединение открытым и при необходимости звоните mysql_select_db()для обмена. Я не уверен, что это чистое решение, и вы могли бы в конечном итоге запросить неправильную базу данных.
  • Укажите имя базы данных, когда вы ссылаетесь на таблицы в своих запросах (например SELECT * FROM database2.tablename). Это, вероятно, будет проблемой для реализации.

Также, пожалуйста, прочитайте ответ troelskn, потому что это лучший подход, если вы можете использовать PDO, а не старые расширения.

Том Хей
источник
2
+1 Это решение сработало для меня. После двух дней отладки, почему мои пользовательские шаблоны WordPress теряли доступ к объекту $ WP_Query после вызова второго соединения с базой данных ...
Эдди Б,
Можно ли установить один из них по умолчанию, и просто нужно добавить $dbh2для второго только при необходимости? Необходимость изменить все запросы для этого подхода к работе, вероятно, займет несколько дней, просто чтобы найти их все ...
ThomasK
@ThomasK, вы можете обернуть mysql_query в функцию с параметром по умолчанию, скажем, db_query($query,$db='db1')а затем массово обновить все ваши старые запросы, чтобы db_query($query)затем выполнить пользовательское обновление ваших нестандартных запросов доdb_query($query,'db2')
joshuahedlund
Используя ваш метод, какое соединение будет использоваться, если я определю два соединения, но не укажу, какое соединение использовать в запросе?
Питер
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.
Том Хей
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();
}
troelskn
источник
5
Почему этот ответ не наверху ?! Это правильный путь.
Адитья депутат
10
@aditya menon, по моему мнению, правильный способ сделать что-то часто не является правильным ответом на поставленный вопрос. Аскер использовал не PDO в своем вопросе, а собственные функции php mysql, поэтому я считаю, что наиболее подходящий ответ будет следовать за кодом Аскера.
Джонатан душ Сантуш
2
@adityamenon под чьим руководством? Помните, что пользователь всегда прав ... PDO - лучший способ, но оба способа являются правильным способом решения проблемы пользователей. Обратите внимание на разницу между правильным и лучшим. Да ... Мне скучно, поэтому я должен был сделать заявление.
JustinKaz
Представляют ли $ db1 и $ db2 несколько подключений mysql? Если так, то это не хорошо. Есть ли способ разместить несколько баз данных только с одним подключением?
datasn.io
@kavoir Зачем тебе это? Если нужно, вы можете изменить базу данных на текущем соединении use DATABASENAME, но я не вижу смысла?
troelskn
9

Я просто сделал мою жизнь простой:

CREATE VIEW another_table AS SELECT * FROM another_database.another_table;

надеюсь, что это полезно ... ура ...

Ихсан Кусаси
источник
1
Это самое простое решение, если у вас нет таблиц с одинаковыми именами в обеих базах данных. Вы делаете это один раз, и тогда вам больше не нужно беспокоиться о нескольких базах данных.
Эрель Сегал-Халеви
@ ErelSegal-Halevi, если вам нужен только доступ только для чтения к данным из другой базы данных, верно?
Баттл Буткус
6

Вместо mysql_connect используйте mysqli_connect .

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

$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 = 'Your DB_Hostname'; $ username = 'Your DB_Username'; $ password = 'Ваш DB_password'; $ db_name1 = 'Ваше DB_Name 1'; $ db_name2 = 'Your DB_Name 2';
Каушик
Это просто неправильно, что это не сработает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.

Майкл Рэтклифф
источник
Для тех, кто хотел бы попробовать вышеупомянутый подход, посмотрите перед этим stackoverflow.com/a/14933070/1623579
TheFrost
Я люблю это решение! Я могу обойтись без постоянной настройки, но создание экземпляра PDO - отличное решение. Вы получаете соединение по умолчанию без подключения к конкретной базе данных.
Чак Берджесс
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 поможет вам.

user3857891
источник
Пожалуйста, улучшите ваш синтаксис (это не смс) и отформатируйте ваш код с помощью инструментов (например, Ctrl + K).
Федорки 'ТАК прекрати вредить'
2

Вам на самом деле не нужно select_db. Вы можете отправить запрос в две базы данных одновременно. Во- первых, дать грант , DB1чтобы выбрать из DB2путем GRANT select ON DB2.* TO DB1@localhost;. Тогда FLUSH PRIVILEGES;. Наконец, вы можете выполнять «запросы к нескольким базам данных», как SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2и т. Д. (Не забывайте, что вам нужен доступ «root» для использования команды grant)

Nagibaba
источник
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**);

ТАК просто измените имя параметра pass в 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/>----------------------------------------";

        }     

    }
    ?>
оборота Сапан Моханты
источник
Для получения более подробной информации вы можете посетить github.com/sapankumarmohanty/CountRecordsAtMigrationFinalSync
htngapi