前回のエピソード (MySQL でクロスデータベース クエリを構築する方法) では、MySQL でクロスデータベース クエリを構築する方法を学びました。これはうまくいきましたが、主人公がこの新たに得た知識を PHP で使おうとしたとき、親友が失敗したことがわかりました。
PHP の mysql_select_db
を調べました。これは、PHP で MySQL を使用したい場合、いくつかのオプションがあることを意味しているようです:
mysql_select_db
を使用しますが、一度に使用できるデータベースは 1 つだけです。これが現在のセットアップです。データベースを名前空間識別子として使用することは機能しないようです (MySQL シェルでは正常に動作するため、MySQL サーバーのセットアップに問題がないことはわかっています)。
mysql_select_db
は使用しないでください。私が見たいくつかの例から、これは、作成するすべてのクエリに対してデータベースを指定する必要があることを意味しているようです。どのデータベースにアクセスするかを PHP に指示するために mysql_select_db
を使用していないので、これは理にかなっています。すべてのコードを調べて各クエリの前にデータベース名を付ける必要がないので、これも悲しいことです。
これより優れたものはありますか? (2) のようなおかしなことをせずに、PHP でクロスデータベース MySQL クエリを実行する方法はありますか?
説明: 提案された回答では、実際にデータベース間のクエリを実行できるものはありませんでした。代わりに、2 つの異なるデータベースに別々にアクセスできるようになります。単に異なるデータベースに対して異なるクエリを実行するのではなく、 SELECTforeign_db.login.username,firstname,lastname fromforeign_db.login,user where...
のようなことを実行できるソリューションが必要です。結局のところ、(2) は私には機能しません。
指示を読んだ後、実際には 2 つの別々の MySQL サーバー インスタンスに存在するテーブルに対してクエリを実行したいのではないかという印象を受けました。少なくとも、明確なテキスト:
2 人のユーザー (同じ mysql サーバー インスタンス上に存在する場合とそうでない場合があります) としてログインしているときにクエリを実行することをお勧めします。
質問では、2 つの異なるデータベースからデータをクエリしたいと述べていますが、MySQL インスタンスには非常に多くのデータベースを含めることができることを認識することが重要です。同じ mysql インスタンスによって管理されている複数のデータベースの場合、リンク先の質問で提案されている解決策は簡単です。テーブル名の前にデータベース名を接頭辞として付け、データベース名とテーブル名をドットで区切るだけです:
.
.しかし、私が指摘したように、これは次の場合にのみ機能します:
シナリオ 1: 同じホスト上のデータベース: 適切な権限を付与し、テーブル名を修飾する
したがって、これらのテーブルが実際に同じ mysql インスタンス上に存在する場合、2 回目のログインや接続は必要ありません。データベースへの接続に使用しているデータベース ユーザーに適切な権限を付与するだけです。必要な場合は、すべてから選択してください。テーブル。これは、ここに記載されている 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 エンジン
アクセスしているテーブルが実際に 2 つの異なる MySQL インスタンスによって管理されている場合、構成に応じて機能する場合と機能しない場合があるトリックがあります。 MySQL 5.0 以降、mysql は FEDERATED ストレージ エンジンをサポートします。これにより、実際にはテーブルではなく、リモート サーバー上のテーブルへののぞき穴であるテーブルを作成できます。エンジンはここに文書化されています:
http://dev.mysql.com/doc/refman/5.1/en/federated-storage-engine.html
たとえば、リモート ホスト上の misc データベースに次のテーブルがあることがわかっている場合:
リーリー次のコマンドを使用して、リモート テーブルへのローカル「ポインター」を作成できます。
FEDERATEDリーリー
残念ながら、エンジンは常に利用できるわけではないため、最初に使用できるかどうかを確認する必要があります。しかし、それが事実であると仮定すると、他のテーブルと同じように、クエリでローカル テーブル t を使用するだけで済み、MySQL はリモート サーバーと通信し、相手側の物理テーブルに対して適切な操作を実行します。
警告: FEDERATED テーブルには複数の最適化の問題があります。これらが自分に当てはまるかどうか、またどの程度当てはまるかを理解する必要があります。たとえば、多くの場合、ユニオン テーブルに
WHERE
を適用すると、テーブルの内容全体がネットワーク経由でローカル サーバーにプルされ、そこで実際のフィルタリングが適用されます。もう 1 つの問題はテーブルの作成です。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 インスタンスにテーブルがあるにもかかわらず、何らかの理由でフェデレーテッド テーブル エンジンを使用できない場合は、残念ながら運が悪いと思います。 2 つの MySQL インスタンスに対してクエリを実行し、結果を受け取り、PHP でいくつかのスマートな操作を実行するだけです。特定の要件によっては、これは完全に実行可能なソリューションになる可能性がありますデータベースは同じホスト上で実行する必要があります。
その場合、お気に入り/デフォルトのデータベースで mysql_select_db を使用し、外部データベースを手動で指定できるはずです。
リーリーデータベースが別のホストで実行されている場合、直接参加することはできません。ただし、2 つのクエリを実行できます。
リーリー