In unserer letzten Folge (So erstellen Sie datenbankübergreifende Abfragen in MySQL) habe ich gelernt, wie man datenbankübergreifende Abfragen in MySQL erstellt. Das funktionierte gro?artig, aber als unser Held versuchte, dieses neu gewonnene Wissen in PHP zu nutzen, stellte er fest, dass sein bester Freund versagte.
Ich habe mir PHPs angesehen mysql_select_db
. Das scheint zu bedeuten, dass ich, wenn ich MySQL mit PHP verwenden m?chte, ein paar Optionen habe:
Verwenden Sie mysql_select_db
, es kann jedoch jeweils nur eine Datenbank verwendet werden. Dies ist unser aktuelles Setup. Die Datenbank als Namespace-ID zu verwenden scheint nicht zu funktionieren (in der MySQL-Shell funktioniert es einwandfrei, daher wei? ich, dass es bei unserem MySQL-Server-Setup kein Problem darstellt).
Nicht verwenden mysql_select_db
。從我看到的一些示例來看,這似乎意味著我必須為我所做的每個查詢指定數(shù)據(jù)庫。這是有道理的,因為我沒有使用 mysql_select_db
. Aus einigen Beispielen, die ich gesehen habe, scheint dies zu bedeuten, dass ich die Datenbank für jede Abfrage angeben muss, die ich mache. Das macht Sinn, da ich
Gibt es etwas Besseres als das? Gibt es eine M?glichkeit für mich, eine datenbankübergreifende MySQL-Abfrage in PHP durchzuführen, ohne etwas Verrücktes wie (2) tun zu müssen?
KlarstellungSELECTforeign_db.login.username,firstname,lastname fromforeign_db.login,user where...
: Mit keiner der vorgeschlagenen Antworten konnte ich tats?chlich datenbankübergreifende Abfragen durchführen. Stattdessen erm?glichen sie mir den separaten Zugriff auf zwei verschiedene Datenbanken. Ich m?chte eine L?sung, die es mir erm?glicht, so etwas wie
閱讀您的說明后,我的印象是您實際上想要查詢駐留在兩個單獨的 MySQL 服務器實例中的表。至少,您的澄清文字:
建議您希望在以兩個用戶身份登錄時運行一個查詢(可能駐留在也可能不駐留在同一個 mysql 服務器實例上)。
在您的問題中,您說您想要從兩個不同的數(shù)據(jù)庫查詢數(shù)據(jù),但重要的是要認識到一個 MySQL 實例可以有很多很多數(shù)據(jù)庫。對于由同一 mysql 實例管理的多個數(shù)據(jù)庫,您鏈接到的問題中提出的解決方案很簡單:只需在表名前添加數(shù)據(jù)庫名稱前綴,用點分隔數(shù)據(jù)庫和表名稱:
.
但是,就像我指出的那樣,這只在以下情況下有效:
場景1:同一主機上的數(shù)據(jù)庫:授予適當?shù)臋?quán)限并限定表名稱
因此,如果這些表實際上駐留在同一個 mysql 實例上,則無需第二次登錄或連接 - 只需授予您用于連接到數(shù)據(jù)庫的數(shù)據(jù)庫用戶適當?shù)臋?quán)限,即可從您需要的所有表中進行選擇。您可以使用 GRANT 語法來做到這一點,記錄如下:http://dev.mysql.com/doc/refman/5.1/en/grant.html
例如,GRANT SELECT ON sakila.film TO 'test'@'%'
將允許用戶 test@%
從 film 選擇數(shù)據(jù)
表。完成此操作后,用戶可以使用 sakila.film(所謂的限定表名)引用該表,或者如果當前數(shù)據(jù)庫設置為 sakila,只需如下所示sakila
數(shù)據(jù)庫中的 電影
場景2:由不同MySQL實例管理的數(shù)據(jù)庫:FEDERATED引擎
如果您要訪問的表實際上由兩個不同的 MySQL 實例管理,則有一個技巧可能有效,也可能無效,具體取決于您的配置。從MySQL 5.0開始,mysql支持FEDERATED
存儲引擎。這使您可以創(chuàng)建一個實際上不是表的表,而是遠程服務器上表的窺視孔。該引擎記錄在此處:http://dev. mysql.com/doc/refman/5.1/en/federated-storage-engine.html
例如,如果您知道遠程主機上的 misc
數(shù)據(jù)庫中有此表:
CREATE TABLE t ( id int not null primary key , name varchar(10) not null unique )
您可以使用以下命令創(chuàng)建指向該遠程表的本地“指針”:
CREATE TABLE t ( id int not null primary key , name varchar(10) not null unique ) ENGINE = FEDERATED CONNECTION='mysql://<user>@<remote-server>:<remote-port>/misc/t';
不幸的是,FEDERATED
引擎并不總是可用,因此您必須首先檢查是否可以使用它。但假設是這樣,那么您可以在查詢中簡單地使用本地表 t,就像任何其他表一樣,MySQL 將與遠程服務器通信并對另一端的物理表執(zhí)行適當?shù)牟僮鳌?/p>
警告:FEDERATED 表存在多個優(yōu)化問題。您應該了解這些是否以及在多大程度上適用于您。例如,在許多情況下,將 WHERE
應用于聯(lián)合表可能會導致整個表內(nèi)容通過網(wǎng)絡拉至本地服務器,在本地服務器上應用實際的過濾。另一個問題是表創(chuàng)建:您必須非常確定聯(lián)合表及其指向的表的定義完全匹配,除了 ENGINE 子句(和 CONNECTION)。例如,如果您有不同的字符集,則數(shù)據(jù)在通過網(wǎng)絡傳輸后可能會完全亂碼。
如果您想使用FEDERATED
表,請閱讀這篇文章http://oreilly.com/pub/a/databases/2006/08/10/mysql-federated-tables.html 來決定它是否適合您特定用例。
如果您認為確實需要它,我有一個實用程序可以在此處創(chuàng)建聯(lián)合表:http://forge.mysql.com/tools/tool.php?id=54
場景3:無法使用FEDERATED,但表位于不同的MySQL實例上
最后,如果您在不同的 MySQL 實例上有表,但由于某種原因無法使用聯(lián)合表引擎,那么恐怕您就不走運了。您只需對兩個 MySQL 實例執(zhí)行查詢、接收結(jié)果并在 PHP 中執(zhí)行一些智能操作。根據(jù)您的具體要求,這可能是一個完全可行的解決方案
我想您需要自己決定我的答案的哪一部分最能解決您的問題,并添加評論以防您需要更多幫助。蒂亞·羅蘭。
您將需要數(shù)據(jù)庫在同一主機上運行。
如果是這樣,您應該能夠在您最喜歡的/默認數(shù)據(jù)庫上使用 mysql_select_db 并手動指定外部數(shù)據(jù)庫。
$db = mysql_connect($hots, $user, $password); mysql_select_db('my_most_used_db', $db); $q = mysql_query(" SELECT * FROM table_on_default_db a, `another_db`.`table_on_another_db` b WHERE a.id = b.fk_id ");
如果您的數(shù)據(jù)庫運行在不同的主機上,您將無法直接加入。但隨后您可以進行 2 個查詢。
$db1 = mysql_connect($host1, $user1, $password1); $db2 = mysql_connect($host2, $user2, $password2); $q1 = mysql_query(" SELECT id FROM table WHERE [..your criteria for db1 here..] ", $db1); $tmp = array(); while($val = mysql_fetch_array($q1)) $tmp[] = $val['id']; $q2 = mysql_query(" SELECT * FROM table2 WHERE fk_id in (".implode(', ', $tmp).") ", $db2);