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


179

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

Я знаю, як підключитися до єдиної бази даних за допомогою:

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

Однак чи можу я просто використовувати кілька команд "mysql_connect" для відкриття інших баз даних, і як би PHP дізнався, з якої бази даних я хочу отримати інформацію, якщо у мене підключено кілька баз даних.

Відповіді:


335

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


Ви можете робити кілька дзвінків mysql_connect(), але якщо параметри однакові, вам потрібно передати істину для параметра ' $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.
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
Чому ця відповідь не вгорі ?! Це правильний шлях для цього.
депутат Адітія

10
@aditya menon, на мою думку, правильний спосіб зробити щось часто - це не правильна відповідь на питання. запитувач не використовував PDO у своєму питанні, але функцію php native 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, якщо вам потрібен лише доступ лише для читання до даних з інших db, правда?
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
$ username = 'Ваше ім'я DB_Hostname'; $ username = 'Ваше ім'я DB_Username'; $ password = 'Ваше DB_password'; $ db_name1 = 'Ваша DB_Name 1'; $ db_name2 = 'Ваша 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");

Звичайно, ви можете зафіксувати це у заяві про спробу лову.


Для тих, хто хотів би спробувати вище підхід, подивіться на до цього 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 таким чином допоможе вам.


Удосконаліть свій синтаксис (це не смс) та відформатуйте свій код за допомогою інструментів (наприклад, Ctrl + K).
fedorqui 'ТАК перестаньте шкодити'

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)


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/>----------------------------------------";

        }     

    }
    ?>

Більш детально ви можете відвідати github.com/sapankumarmohanty/CountRecordsAtMigrationFinalSync
htngapi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.