如何在PHP中建構跨資料庫查詢?
P粉197639753
P粉197639753 2023-10-22 11:40:00
0
2
644

在我們的上一集(如何在 MySQL 中建立跨資料庫查詢)中,我學習如何在 MySQL 中建立跨資料庫查詢。這很有效,但是當我們的英雄嘗試在 PHP 中使用這些新發現的知識時,他發現他最好的朋友失敗了。

我查看了 PHP 的 mysql_select_db 。這似乎意味著,如果我想將 MySQL 與 PHP 一起使用,我有幾個選擇:

  1. 使用 mysql_select_db 但每次只能使用一個資料庫。這是我們目前的設置,將資料庫作為命名空間標識符似乎不起作用(它在 MySQL shell 中工作正常,所以我知道這不是我們的 MySQL 伺服器設定的問題)。

  2. 不要使用 mysql_select_db。從我看到的一些範例來看,這似乎意味著我必須為我所做的每個查詢指定資料庫。這是有道理的,因為我沒有使用 mysql_select_db 來告訴 PHP 我想要存取哪個資料庫。這也讓人難過,因為我不想遍歷所有程式碼並在每個查詢之前添加資料庫名稱。

還有比這更好的嗎?有沒有辦法讓我在 PHP 中進行跨資料庫 MySQL 查詢,而不必像 (2) 這樣瘋狂的事情?

澄清:所提出的答案其實都沒有讓我進行跨資料庫查詢。相反,它們允許我分別訪問兩個不同的資料庫。我想要一個解決方案,允許我執行類似SELECTforeign_db.login.username,firstname,lastname fromforeign_db.login,user where... 的操作,而不僅僅是對不同的資料庫進行不同的查詢。就其價值而言,(2) 對我來說不起作用。

P粉197639753
P粉197639753

全部回覆(2)
P粉077701708

閱讀您的說明後,我的印像是您實際上想要查詢駐留在兩個單獨的 MySQL 伺服器實例中的表。至少,您的澄清文字:

建議您希望在以兩個使用者身分登入時執行一個查詢(可能駐留在也可能不駐留在同一個 mysql 伺服器實例上)。

在您的問題中,您說您想要從兩個不同的資料庫查詢數據,但重要的是要認識到一個 MySQL 實例可以有很多很多資料庫。對於由相同mysql 實例管理的多個資料庫,您連結到的問題中提出的解決方案很簡單:只需在表名前添加資料庫名稱前綴,用點分隔資料庫和表名稱:..

但是,就像我指出的那樣,這只在以下情況下有效:

  1. 您在一個查詢中存取的所有資料庫都駐留在同一台伺服器上 - 即由同一個 MySQL 實例管理
  2. 連接到資料庫的使用者俱有存取這兩個表的正確權限。

場景1:同一主機上的資料庫:授予適當的權限並限定表格名稱

因此,如果這些表實際上駐留在同一個mysql 實例上,則無需第二次登入或連接- 只需授予您用於連接到資料庫的資料庫使用者適當的權限,即可從您需要的所有表格中進行選擇。您可以使用 GRANT 語法來做到這一點,請記錄如下:http://dev.mysql.com/doc/refman/5.1/en/grant.html

例如,GRANT SELECT ON sakila.film TO 'test'@'%' 將允許使用者test@%film 選擇資料sakila 資料庫中的 表。完成此操作後,使用者可以使用 sakila.film(所謂的限定表名)引用該表,或者如果當前資料庫設定為 sakila,只需如下所示電影

場景2:由不同MySQL實例管理的資料庫:FEDERATED引擎

如果您要存取的表實際上由兩個不同的 MySQL 實例管理,則有一個技巧可能有效,也可能無效,具體取決於您的配置。從MySQL 5.0開始,mysql支援FEDERATED儲存引擎。這使您可以創建一個實際上不是表的表,而是遠端伺服器上表的窺視孔。引擎記錄在此:http://dev. mysql.com/doc/refman/5.1/en/federated-storage-engine.html

例如,如果您知道遠端主機上的 misc 資料庫中有此表:

CREATE TABLE t (
    id int not null primary key
,   name varchar(10) not null unique
)

您可以使用下列命令建立指向該遠端表的本機「指標」:

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 將與遠端伺服器通訊並對另一端的實體表執行適當的操作。

警告:FEDERATED 表存在多個最佳化問題。您應該了解這些是否以及在多大程度上適用於您。例如,在許多情況下,將 WHERE 套用至聯合表可能會導致整個表內容透過網路拉至本機伺服器,在本機伺服器上套用實際的篩選。另一個問題是表創建:您必須非常確定聯合表及其指向的表的定義完全匹配,除了 ENGINE 子句(和 CONNECTION)。例如,如果您有不同的字元集,則資料在通過網路傳輸後可能會完全亂碼。

如果您想使用FEDERATED表,請閱讀這篇文章http://oreilly.com/pub/a/databases/2006/08/10/mysql-federated-tables. html 來決定它是否適合您特定用例。

如果您認為確實需要它,我有一個實用程式可以在此處建立聯合表:http://forge.mysql.com/tools/tool.php?id=54

場景3:無法使用FEDERATED,但表格位於不同的MySQL實例上

#

最後,如果您在不同的 MySQL 實例上有表,但由於某種原因無法使用聯合表引擎,那麼恐怕您就不走運了。您只需對兩個 MySQL 實例執行查詢、接收結果並在 PHP 中執行一些智慧操作。根據您的具體要求,這可能是完全可行的解決方案

我想您需要自己決定我的答案的哪一部分最能解決您的問題,並添加評論以防您需要更多幫助。蒂亞羅蘭。

P粉481366803

您將需要資料庫在同一台主機上運行。

如果是這樣,您應該能夠在您最喜歡的/預設資料庫上使用 mysql_select_db 並手動指定外部資料庫。

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

如果您的資料庫運行在不同的主機上,您將無法直接加入。但隨後您可以進行 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);
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!