คุณเชื่อมต่อกับฐานข้อมูล 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 หลังจากการโทรไปยังการเชื่อมต่อฐานข้อมูลที่สอง ...
Eddie B

เป็นไปได้หรือไม่ที่จะตั้งให้หนึ่งรายการเป็นค่าเริ่มต้นและต้องเพิ่ม$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();
}

(แน่นอนแทนที่ databasename ชื่อผู้ใช้และรหัสผ่านด้านบน)

จากนั้นคุณสามารถสืบค้นฐานข้อมูลเช่นนี้:

$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
ทำไมไม่มีคำตอบนี้อยู่ด้านบน! นี่เป็นวิธีที่ถูกต้องที่จะไปเกี่ยวกับมัน
Aditya MP

10
@aditya menon ในความคิดของฉันวิธีที่ถูกต้องในการทำบางสิ่งบางอย่างไม่ใช่คำตอบที่ถูกต้องสำหรับคำถามที่อยู่ในมือ Asker ไม่ได้ใช้ PDO ในคำถามของเขา แต่ฟังก์ชั่น mysql พื้นเมือง php ดังนั้นฉันเชื่อว่าคำตอบที่เหมาะสมที่สุดจะเป็นไปตามรหัสของผู้ถาม
Jonathan dos Santos

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
นี่เป็นวิธีที่ง่ายที่สุดถ้าคุณไม่มีตารางที่มีชื่อเดียวกันในฐานข้อมูลทั้งสอง คุณทำครั้งเดียวแล้วคุณไม่ต้องกังวลเกี่ยวกับฐานข้อมูลหลาย ๆ อีกต่อไป
Erel Segal-Halevi

@ ErelSegal-Halevi ตราบใดที่คุณต้องการเข้าถึงแบบอ่านอย่างเดียวเท่านั้นจากฐานข้อมูลอื่นใช่ไหม?
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
$ hostname = 'Your DB_Hostname'; $ username = 'DB_Username ของคุณ'; $ password = 'Your DB_password'; $ db_name1 = 'คุณ DB_Name 1'; $ db_name2 = 'DB_Name ของคุณ 2';
kaushik

มันผิดที่จะไม่ทำงานกับmysql_connect
Nico Haase

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 เป็นวิธีแก้ปัญหาที่ยอดเยี่ยม คุณได้รับการเชื่อมต่อเริ่มต้นโดยไม่ต้องเชื่อมต่อกับฐานข้อมูลเฉพาะ
Chuck Burgess

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 ด้วยวิธีนี้จะช่วยคุณ


โปรดปรับปรุงไวยากรณ์ของคุณ (นี่ไม่ใช่ SMS) และจัดรูปแบบโค้ดของคุณด้วยเครื่องมือ (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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.