Làm thế nào để bạn kết nối với nhiều cơ sở dữ liệu MySQL trên một trang web?


179

Tôi có thông tin trải rộng trên một vài cơ sở dữ liệu và muốn đưa tất cả thông tin lên một trang web bằng PHP. Tôi đã tự hỏi làm thế nào tôi có thể kết nối với nhiều cơ sở dữ liệu trên một trang web PHP.

Tôi biết cách kết nối với một cơ sở dữ liệu bằng cách sử dụng:

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

Tuy nhiên, tôi có thể chỉ sử dụng nhiều lệnh "mysql_connect" để mở các cơ sở dữ liệu khác không và làm thế nào PHP biết cơ sở dữ liệu nào tôi muốn lấy thông tin nếu tôi có nhiều cơ sở dữ liệu được kết nối.

Câu trả lời:


335

Cảnh báo: các mysql_xx hàm bị phản đối kể từ php 5.5 và bị xóa kể từ php 7.0 (xem http://php.net/manual/intro.mysql.php ), sử dụng các mysqli_xxhàm hoặc xem câu trả lời bên dưới từ @Troelskn


Bạn có thể thực hiện nhiều cuộc gọi đến mysql_connect(), nhưng nếu các tham số giống nhau, bạn cần chuyển đúng cho tham số ' $new_link' (thứ tư), nếu không thì cùng một kết nối được sử dụng lại. Ví dụ:

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

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

Sau đó, để truy vấn cơ sở dữ liệu 1 vượt qua định danh liên kết đầu tiên:

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

và cho cơ sở dữ liệu 2 vượt qua lần thứ hai:

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

Nếu bạn không vượt qua một định danh liên kết thì kết nối cuối cùng được tạo sẽ được sử dụng (trong trường hợp này là kết nối được đại diện bởi $dbh2), vd:

mysql_query('select * from tablename');

Sự lựa chọn khác

Nếu người dùng MySQL có quyền truy cập vào cả hai cơ sở dữ liệu và chúng nằm trên cùng một máy chủ (tức là cả hai DB đều có thể truy cập được từ cùng một kết nối), bạn có thể:

  • Giữ một kết nối mở và gọi mysql_select_db()để trao đổi giữa khi cần thiết. Tôi không chắc đây là một giải pháp sạch và cuối cùng bạn có thể truy vấn cơ sở dữ liệu sai.
  • Chỉ định tên cơ sở dữ liệu khi bạn tham chiếu các bảng trong các truy vấn của mình (ví dụ SELECT * FROM database2.tablename). Đây có thể là một nỗi đau để thực hiện.

Ngoài ra, vui lòng đọc câu trả lời của troelskn vì đó là cách tiếp cận tốt hơn nếu bạn có thể sử dụng PDO thay vì các tiện ích mở rộng cũ hơn.


2
+1 Giải pháp này hiệu quả với tôi. Sau hai ngày gỡ lỗi tại sao các mẫu WordPress tùy chỉnh của tôi bị mất quyền truy cập vào đối tượng $ WP_Query sau khi gọi đến kết nối cơ sở dữ liệu thứ hai ...
Eddie B

Có thể đặt một trong số chúng là mặc định không và chỉ cần thêm $dbh2cái thứ hai khi cần? Phải thay đổi tất cả các truy vấn để phương pháp này hoạt động có thể sẽ mất nhiều ngày chỉ để tìm thấy tất cả chúng ...
ThomasK

@ThomasK, bạn có thể bọc mysql_query trong một hàm với một tham số mặc định, db_query($query,$db='db1')sau đó cập nhật hàng loạt tất cả các truy vấn cũ của bạn để db_query($query)theo sau là tùy chỉnh cập nhật các truy vấn không mặc định của bạn thànhdb_query($query,'db2')
joshuahedlund

Sử dụng phương pháp của bạn, kết nối nào sẽ được sử dụng nếu tôi xác định hai kết nối nhưng không chỉ định kết nối nào sẽ sử dụng tại truy vấn?
Peter

1
@Peter: theo php.net/manual/en/feft.mysql-query.php :If the link identifier is not specified, the last link opened by mysql_connect() is assumed.
Tom Haigh

97

Nếu bạn sử dụng PHP5 (Và bạn nên, vì PHP4 đã không được dùng nữa), bạn nên sử dụng PDO , vì điều này đang dần trở thành tiêu chuẩn mới. Một (rất) lợi ích quan trọng của PDO, là nó hỗ trợ các tham số ràng buộc, giúp mã an toàn hơn nhiều.

Bạn sẽ kết nối thông qua PDO, như thế này:

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

(Tất nhiên thay thế tên dữ liệu, tên người dùng và mật khẩu ở trên)

Sau đó, bạn có thể truy vấn cơ sở dữ liệu như thế này:

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

Hoặc, nếu bạn có các biến:

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

Nếu bạn cần nhiều kết nối mở cùng một lúc, bạn chỉ cần tạo nhiều phiên bản 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
Tại sao câu trả lời này không đứng đầu?! Đây là cách chính xác để đi về nó.
MP Aditya

10
@aditya menon theo tôi, cách đúng đắn để làm điều gì đó thường không phải là câu trả lời đúng cho câu hỏi trong tầm tay. Asker đã không sử dụng PDO trong câu hỏi của mình mà là các hàm mysql gốc của php, vì vậy tôi tin rằng câu trả lời thích hợp nhất sẽ tuân theo mã người hỏi.
Jonathan dos Santos

2
@adityamenon thuộc thẩm quyền của ai? Hãy nhớ rằng người dùng luôn luôn đúng ... PDO là cách tốt nhất, nhưng cả hai cách đều là cách đúng để giải quyết vấn đề của người dùng. Xin lưu ý sự khác biệt giữa đúng và tốt nhất. Có ... tôi chán nên tôi phải tuyên bố.
JustinKaz

$ Db1 và $ db2 có đại diện cho nhiều kết nối mysql không? Nếu vậy, điều đó không tốt. Có cách nào để chứa nhiều cơ sở dữ liệu chỉ với một kết nối không?
datan.io

@kavoir Tại sao bạn muốn điều đó? Nếu cần, bạn có thể thay đổi cơ sở dữ liệu trên kết nối hiện tại use DATABASENAME, nhưng tôi không thấy vấn đề?
troelskn

9

Tôi chỉ làm cho cuộc sống của tôi đơn giản:

CREATE VIEW another_table AS SELECT * FROM another_database.another_table;

hy vọng nó hữu ích ... chúc mừng ...


1
Đây là giải pháp đơn giản nhất nếu bạn không có các bảng có cùng tên trong cả hai cơ sở dữ liệu. Bạn làm điều đó một lần và sau đó bạn không phải lo lắng về nhiều cơ sở dữ liệu nữa.
Erel Segal-Halevi

@ ErelSegal-Halevi miễn là bạn chỉ cần truy cập chỉ đọc vào dữ liệu từ db khác, phải không?
Butussy Butkus

6

Thay vì mysql_connect, hãy sử dụng mysqli_connect .

mysqli cung cấp chức năng kết nối nhiều cơ sở dữ liệu cùng một lúc.

$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 = 'DB_hostname của bạn'; $ username = 'DB_Username của bạn'; $ password = 'DB_password của bạn'; $ db_name1 = 'DB_Name 1' của bạn; $ db_name2 = 'DB_Name 2' của bạn;
kaushik

Nó chỉ sai khi điều này sẽ không hoạt động vớimysql_connect
Nico Haase

4

Hãy thử mã dưới đây:

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

Bạn có thể tìm nạp dữ liệu của truy vấn trên từ cả hai cơ sở dữ liệu như bên dưới

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

Hai truy vấn đã cho sẽ hoạt động theo cùng một cách mà không cần gọi mysql_select_dbdù chỉ một lần - đồng thời, gọi nó hai lần mà không có gì khác ở giữa là vô ích
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);

Đây là giải pháp rõ ràng nhất mà tôi sử dụng nhưng chỉ cần nhớ, nếu tên người dùng / mật khẩu cho cả hai cơ sở dữ liệu giống hệt nhau trong cùng một máy chủ, giải pháp này sẽ luôn được sử dụng kết nối đầu tiên. Vì vậy, đừng nhầm lẫn rằng điều này không hoạt động trong trường hợp như vậy. Những gì bạn cần làm là, tạo 2 người dùng khác nhau cho 2 cơ sở dữ liệu và nó sẽ hoạt động.


3

Trừ khi bạn thực sự cần phải có nhiều hơn một đối tượng PDO đang chơi, hãy xem xét các điều sau:

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

Lưu ý sự vắng mặt của dbname=các đối số xây dựng.

Khi bạn kết nối với MySQL thông qua một thiết bị đầu cuối hoặc công cụ khác, tên cơ sở dữ liệu không cần thiết cho dơi. Bạn có thể chuyển đổi giữa các cơ sở dữ liệu bằng cách sử dụng USE dbnamecâu lệnh thông qua PDO::exec()phương thức.

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

Tất nhiên bạn có thể muốn gói nó trong một tuyên bố thử bắt.


Đối với những người, những người sẽ thử cách tiếp cận trên, hãy xem trước stackoverflow.com/a/14933070/1623579
TheFrost

Tôi thích giải pháp này! Tôi có thể làm mà không cần cài đặt liên tục, nhưng việc khởi tạo PDO là một giải pháp tuyệt vời. Bạn nhận được một kết nối mặc định mà không được kết nối với một cơ sở dữ liệu cụ thể.
Chuck Burgess

2

Bạn có thể sử dụng cú pháp MySQLi, cho phép bạn xử lý nó tốt hơn.

Xác định các kết nối cơ sở dữ liệu, sau đó bất cứ khi nào bạn muốn truy vấn một trong các cơ sở dữ liệu, chỉ định kết nối đúng.

Ví dụ:

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

Sau đó, để truy vấn chúng trên cùng một trang, sử dụng một cái gì đó như:

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

Thay đổi sang MySQLi theo cách này sẽ giúp bạn.


Vui lòng cải thiện cú pháp của bạn (đây không phải là tin nhắn) và định dạng mã của bạn bằng các công cụ (ví dụ: Ctrl + K).
fedorqui 'SO ngừng làm hại'

2

Bạn không thực sự cần select_db. Bạn có thể gửi một truy vấn đến hai cơ sở dữ liệu cùng một lúc. Thứ nhất, cung cấp cho một khoản trợ cấp để DB1lựa chọn từ DB2bằng GRANT select ON DB2.* TO DB1@localhost;. Sau đó , FLUSH PRIVILEGES;. Cuối cùng, bạn có thể thực hiện 'truy vấn nhiều cơ sở dữ liệu', SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2v.v. (Đừng quên rằng bạn cần quyền truy cập 'root' để sử dụng lệnh cấp)


1

nếu bạn đang sử dụng mysqli và có hai tệp db_connection. như cái đầu tiên là

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

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

cái thứ hai là

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

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

Vì vậy, chỉ cần thay đổi tên của thông số truyền trong mysqli như DB1 và ​​DB2. Nếu bạn truyền cùng một tham số trong mysqli, giả sử DB1 trong cả hai tệp thì cơ sở dữ liệu thứ hai sẽ không kết nối nữa. Vì vậy, hãy nhớ khi bạn sử dụng hai hoặc nhiều kết nối vượt qua tên tham số khác nhau trong hàm 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/>----------------------------------------";

        }     

    }
    ?>

Để biết thêm chi tiết, bạn có thể truy cập github.com/sapankumarmohanty/CountRecordsAtMigrationFinalSync
htngapi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.