Wie stellen Sie eine Verbindung zu mehreren MySQL-Datenbanken auf einer einzigen Webseite her?

179

Ich habe Informationen auf einige Datenbanken verteilt und möchte alle Informationen mit PHP auf eine Webseite stellen. Ich habe mich gefragt, wie ich auf einer einzigen PHP-Webseite eine Verbindung zu mehreren Datenbanken herstellen kann.

Ich weiß, wie man eine Verbindung zu einer einzelnen Datenbank herstellt, indem man:

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

Kann ich jedoch einfach mehrere "mysql_connect" -Befehle verwenden, um die anderen Datenbanken zu öffnen, und wie würde PHP wissen, aus welcher Datenbank die Informationen abgerufen werden sollen, wenn mehrere Datenbanken verbunden sind.

JoshFinnie
quelle

Antworten:

335

Warnung: mysql_xx Funktionen sind seit PHP 5.5 veraltet und seit PHP 7.0 entfernt (siehe http://php.net/manual/intro.mysql.php ). Verwenden Sie mysqli_xxFunktionen oder lesen Sie die Antwort unten von @Troelskn


Sie können mehrere Aufrufe durchführen mysql_connect(), aber wenn die Parameter identisch sind, müssen Sie true für den $new_linkParameter ' ' (vierter) übergeben, andernfalls wird dieselbe Verbindung wiederverwendet. Beispielsweise:

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

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

Um die Datenbank 1 abzufragen, übergeben Sie die erste Link-ID:

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

und für Datenbank 2 übergeben Sie die zweite:

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

Wenn Sie keine Link-ID übergeben, wird die zuletzt erstellte Verbindung verwendet (in diesem Fall die durch $dbh2), z.

mysql_query('select * from tablename');

Andere Optionen

Wenn der MySQL-Benutzer Zugriff auf beide Datenbanken hat und sich auf demselben Host befindet (dh auf beide DBs kann über dieselbe Verbindung zugegriffen werden), können Sie:

  • Lassen Sie eine Verbindung offen und rufen Sie mysql_select_db()an, um bei Bedarf zwischen ihnen zu wechseln. Ich bin nicht sicher, ob dies eine saubere Lösung ist, und Sie könnten am Ende die falsche Datenbank abfragen.
  • Geben Sie den Datenbanknamen an, wenn Sie auf Tabellen in Ihren Abfragen verweisen (z SELECT * FROM database2.tablename. B. ). Dies ist wahrscheinlich ein Problem bei der Implementierung.

Lesen Sie auch die Antwort von troelskn, da dies ein besserer Ansatz ist, wenn Sie PDO anstelle der älteren Erweiterungen verwenden können.

Tom Haigh
quelle
2
+1 Diese Lösung hat bei mir funktioniert. Nach zwei Tagen des Debuggens, warum meine benutzerdefinierten WordPress-Vorlagen nach einem Aufruf der zweiten Datenbankverbindung den Zugriff auf das $ WP_Query-Objekt verloren ...
Eddie B
Ist es möglich, einen von ihnen als Standard festzulegen und $dbh2den zweiten nur bei Bedarf hinzuzufügen ? Alle Abfragen für diesen Arbeitsansatz ändern zu müssen, würde wahrscheinlich Tage dauern, nur alle zu finden ...
ThomasK
@ThomasK, Sie könnten mysql_query in eine Funktion mit einem Standardparameter einschließen db_query($query,$db='db1')und dann alle Ihre alten Abfragen massenweise aktualisieren, db_query($query)gefolgt von einer benutzerdefinierten Aktualisierung Ihrer nicht standardmäßigen Abfragen aufdb_query($query,'db2')
joshuahedlund
Welche Verbindung wird mit Ihrer Methode verwendet, wenn ich zwei Verbindungen definiere, aber nicht angeben, welche Verbindung bei der Abfrage verwendet werden soll?
Peter
1
@ Peter: laut 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

Wenn Sie PHP5 verwenden (und Sie sollten dies tun, da PHP4 veraltet ist), sollten Sie PDO verwenden , da dies langsam zum neuen Standard wird. Ein (sehr) wichtiger Vorteil von PDO ist, dass es gebundene Parameter unterstützt, was für viel sichereren Code sorgt.

Sie würden eine Verbindung über PDO herstellen, wie folgt:

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

(Natürlich ersetzen Sie den Datenbanknamen, den Benutzernamen und das Passwort oben)

Sie können die Datenbank dann folgendermaßen abfragen:

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

Oder wenn Sie Variablen haben:

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

Wenn mehrere Verbindungen gleichzeitig geöffnet sein müssen, können Sie einfach mehrere Instanzen von PDO erstellen:

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
quelle
5
Warum ist diese Antwort nicht oben?! Dies ist der richtige Weg.
Aditya MP
10
@aditya menon Meiner Meinung nach ist der richtige Weg, etwas oft zu tun, nicht die richtige Antwort auf die vorliegende Frage. Der Asker verwendete in seiner Frage kein PDO, sondern native PHP-MySQL-Funktionen. Daher glaube ich, dass die beste Antwort dem Asker-Code folgen würde.
Jonathan dos Santos
2
@adityamenon unter wessen Autorität? Denken Sie daran, dass der Benutzer immer Recht hat ... PDO ist der beste Weg, aber beide Wege sind der richtige Weg, um das Benutzerproblem zu lösen. Bitte beachten Sie den Unterschied zwischen richtig und am besten. Ja ... mir ist langweilig, also musste ich eine Erklärung abgeben.
JustinKaz
Stellen $ db1 und $ db2 mehrere MySQL-Verbindungen dar? Wenn ja, ist das nicht gut. Gibt es eine Möglichkeit, mehrere Datenbanken mit nur einer Verbindung unterzubringen?
Datasn.io
@kavoir Warum willst du das? Bei Bedarf können Sie die Datenbank für die aktuelle Verbindung mit ändern use DATABASENAME, aber ich verstehe den Punkt nicht?
Troelskn
9

Ich habe mein Leben einfach gemacht:

CREATE VIEW another_table AS SELECT * FROM another_database.another_table;

hoffe es ist hilfreich ... Prost ...

Ihsan Kusasi
quelle
1
Dies ist die einfachste Lösung, wenn Sie nicht in beiden Datenbanken Tabellen mit demselben Namen haben. Sie tun es einmal und müssen sich dann nicht mehr um mehrere Datenbanken kümmern.
Erel Segal-Halevi
@ ErelSegal-Halevi solange du nur schreibgeschützten Zugriff auf die Daten der anderen Datenbank benötigst, oder?
Buttle Butkus
6

Verwenden Sie anstelle von mysql_connect mysqli_connect .

mysqli bietet eine Funktion zum gleichzeitigen Verbinden mehrerer Datenbanken.

$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
kaushik
quelle
1
$ hostname = 'Ihr DB_Hostname'; $ username = 'Ihr DB_Username'; $ password = 'Ihr DB-Passwort'; $ db_name1 = 'Ihr DB-Name 1'; $ db_name2 = 'Ihr DB_Name 2';
Kaushik
Es ist einfach falsch, dass dies nicht funktionieren würdemysql_connect
Nico Haase
4

Versuchen Sie den folgenden Code:

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

Sie können Daten der obigen Abfrage wie folgt aus beiden Datenbanken abrufen

$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);
Paks
quelle
Die gegebenen zwei Abfragen würden auf die gleiche Weise funktionieren, ohne mysql_select_dbauch nur einmal anzurufen - auch zweimal anzurufen, ohne dass irgendetwas anderes in der Mitte ist, ist nutzlos
Nico Haase
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);

Dies ist die naheliegendste Lösung, die ich verwende. Denken Sie jedoch daran, dass diese Lösung immer die erste Verbindung verwendet, wenn der Benutzername / das Kennwort für beide Datenbanken auf demselben Host genau gleich ist. Seien Sie also nicht verwirrt, dass dies in einem solchen Fall nicht funktioniert. Was Sie tun müssen, ist, 2 verschiedene Benutzer für die 2 Datenbanken zu erstellen, und es wird funktionieren.

Fauler Kerl
quelle
3

Beachten Sie Folgendes, es sei denn, Sie müssen wirklich mehr als eine Instanz eines PDO-Objekts im Spiel haben:

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

Beachten Sie das Fehlen von dbname=Argumenten in der Konstruktion.

Wenn Sie über ein Terminal oder ein anderes Tool eine Verbindung zu MySQL herstellen, wird der Datenbankname nicht sofort benötigt. Sie können zwischen Datenbanken wechseln, indem Sie die USE dbnameAnweisung über die PDO::exec()Methode verwenden.

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

Natürlich möchten Sie dies möglicherweise in eine catch try-Anweisung einschließen.

Michael Ratcliffe
quelle
Für diejenigen, die oben Ansatz versuchen würden, werfen Sie einen Blick vor diesem stackoverflow.com/a/14933070/1623579
TheFrost
Ich liebe diese Lösung! Ich kann auf die dauerhafte Einstellung verzichten, aber die Instanziierung von PDO ist eine großartige Lösung. Sie erhalten eine Standardverbindung, ohne mit einer bestimmten Datenbank verbunden zu sein.
Chuck Burgess
2

Möglicherweise können Sie die MySQLi-Syntax verwenden, um besser damit umgehen zu können.

Definieren Sie die Datenbankverbindungen. Geben Sie dann die richtige Verbindung an, wenn Sie eine der Datenbanken abfragen möchten.

Z.B:

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

Verwenden Sie dann Folgendes, um sie auf derselben Seite abzufragen:

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

Ein Wechsel zu MySQLi auf diese Weise hilft Ihnen.

user3857891
quelle
Bitte verbessern Sie Ihre Syntax (dies ist keine SMS) und formatieren Sie Ihren Code mit den Tools (z. B. Strg + K).
Fedorqui 'SO hör auf,'
2

Das brauchst du eigentlich nicht select_db. Sie können eine Abfrage gleichzeitig an zwei Datenbanken senden. Geben Sie zunächst einen Zuschuss DB1zur Auswahl DB2durch GRANT select ON DB2.* TO DB1@localhost;. Dann FLUSH PRIVILEGES;. Schließlich können Sie 'Abfragen mit mehreren Datenbanken' wie SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2usw. durchführen. (Vergessen Sie nicht, dass Sie 'root'-Zugriff benötigen, um den Befehl grant zu verwenden.)

Nagibaba
quelle
1

Wenn Sie mysqli verwenden und zwei db_connection-Dateien haben. wie der erste ist

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

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

zweite ist

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

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

Ändern Sie einfach den Namen des Parameterübergangs in mysqli wie DB1 und DB2. Wenn Sie denselben Parameter in mysqli übergeben, nehmen wir an, dass DB1 in beiden Dateien vorhanden ist, stellt die zweite Datenbank keine Verbindung mehr her. Denken Sie also daran, wenn Sie zwei oder mehr Verbindungen verwenden, übergeben Sie unterschiedliche Parameternamen in der mysqli-Funktion

Kamal Bunkar
quelle
-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/>----------------------------------------";

        }     

    }
    ?>
Sapan Mohanty
quelle
Weitere Informationen finden Sie unter github.com/sapankumarmohanty/CountRecordsAtMigrationFinalSync
htngapi