PHP nasıl bir çapraz veritabanı sorgu oluşturmak mı?

9 Cevap php

Bizim son bölüm (How I constructed a cross database query in MySQL) Ben MySQL veritabanı çapraz sorgu oluşturmak için nasıl öğrendi. Bu harika çalıştı ama bizim kahraman PHP bu keşfedilen bilgiyi kullanmaya çalıştım o onun en iyi arkadaşı onu bekliyor FAIL bulundu.

Ben PHP için mysql_select_db bir göz attım. Bu PHP ile MySQL kullanmak istiyorsanız, ben birkaç seçenek olduğunu ima görünüyor:

  1. mysql_select_db kullanmak ancak bir seferde sadece tek bir db kullanarak sıkışmış. Bu bizim mevcut kurulum ve bir ad tanımlayıcı olarak bir veritabanı koyarak (yani bizim MySQL sunucu kurulumu ile ilgili bir sorun değil, biliyorum MySQL çalışıyor kabuk) çalışmak için görünmüyor.

  2. Kullanmayınız mysql_select_db. Gördüğüm bazı örnekler dışında, bu ben yapmak her sorgu için db belirtmek zorunda anlamına görünüyor. I mysql_select_db Ben erişmek istediklerini db PHP anlatmak için kullanılan bu yana bu mantıklı. Ben bütün kod geçmesi ve her sorgu için bir db adını başa eklemek istemiyorum çünkü bu da üzüyor.

Bu daha iyi bir şey var mı? Me (2) gibi çılgın bir şey kalmadan PHP bir çapraz db MySQL sorgusu yapmak için bir yolu var mı?

CLARIFICATION: Önerilen cevapların hiçbiri aslında beni çapraz db sorgu yapalım. Bunun yerine, onlar bana ayrı ayrı iki farklı DBS erişmenizi sağlar. Bana SELECT foreign_db.login.username, firstname, lastname from foreign_db.login, user where ... sadece farklı veritabanları için farklı sorgular yapmak değil gibi bir şey yapmak için izin veren bir çözüm istiyorum. Bu değer ne için, (2) benim için çalışmıyor.

9 Cevap

Sen aynı host üzerinde çalıştırmak için veritabanları gerekir.

Eğer öyleyse, en sevdiğiniz / default db mysql_select_db kullanmak ve el yabancı bir veritabanı belirtmek gerekir.

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

Veritabanları farklı bir ana bilgisayarda çalıştırırsanız, doğrudan katılmak mümkün olmayacaktır. Ama daha sonra 2 sorguları yapabilirsiniz.

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

: Bir çözelti olabilir,

  • mysql_select_db "varsayılan" seçmek için kullanın (i.e. most used) veritabanı
  • ve sadece "ikinci" (yani en az kullanılan) veritabanı ile çalışmak zorunda sorguları DB adını belirtin.

Eğer diğerinden daha fazla kullanılan bu bir DB var ama eğer bu sadece uygun bir çözümdür ...


Out of curiosity : did you try establishing several connections to your DB server -- i.e. one for each database ?

Sen mümkün olabilir:

Ardından, ilk tarafından döndürülen bağlantı tanımlayıcı ile çalışmak, veya ikinci, sorguları çalıştırmak istediğiniz DB hangi bağlı, mysql_connect çağırıyoruz.


As a sidenote : the "best" / "cleanest" solution would be not using mysql_* functions directly, but working with some kind of ORM framework, that would have the ability to work with several DB connections at the same time (not sure, but maybe
Doctrine can do that -- it's a real good ORM)

Lütfen açıklama okuduktan sonra, ben aslında iki ayrı MySQL sunucu örnekleri ikamet tabloları sorgulamak istediğiniz izlenimi altında değilim. En azından, açıklama metni:

Foreign_db.login, kullanıcı SELECT foreign_db.login.username, ad, soyad nerede

en az iki kullanıcı (olan veya aynı mysql sunucu örneği üzerinde ikamet olmayabilir) olarak giriş olurken, bir sorgu çalıştırmak istiyorum önerir.

Sorunuza, size iki farklı veritabanlarındaki verileri sorgulamak istedim, ama bir MySQL örneği pek çok veritabanları olabilir gerçekleştirmek için önemli olduğunu söyledi. Aynı mysql örneği tarafından yönetilen çoklu veritabanları için, sadece çalışır bağlı söz önerilen çözüm: Sadece bir nokta ile veritabanı ve tablo adları ayıran, veritabanlarının adı ile tablo adı öneki: <db-name>.<table-name> .

I işaret gibi Ama, bu sadece çalışır:

  1. Bir sorguda erişen tüm veritabanları aynı sunucu üzerinde - yani, aynı MySQL örneği tarafından yönetilmektedir
  2. veritabanına bağlı kullanıcı hem tabloları erişmek için doğru ayrıcalıklara sahip.

Scenario1: databases on same host: grant appopriate privileges and qualify table names So if the tables actually reside on the same mysql instance, there is no need for a second login or connection - simply grant the database user you use to connect to the datbase the appropriate privileges to select from all tables you need. You can do that with the GRANT syntax, documented here: http://dev.mysql.com/doc/refman/5.1/en/grant.html

For example, GRANT SELECT ON sakila.film TO 'test'@'%' will allow the user test@% to select data from the film table in the sakila database. After doing that, said user can refer to this table using sakila.film (so-called qualified table name), or if the current database is set to sakila, simply as film Scenario2: databases managed by different MySQL instances: FEDERATED engine If the tables you want to access are actually managed by two different MySQL instances, there is one trick that may or may not work, depending on your configuration. Since MySQL 5.0 mysql supports the FEDERATED storage engine. This lets you create a table that is not actually a table, but a peephole to a table on a remote server. This engine is documented here: http://dev.mysql.com/doc/refman/5.1/en/federated-storage-engine.html

Bildiğiniz Örneğin, uzak ana misc veritabanında bu tablo var:

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

Bu kullanarak bu uzak tablo yerel bir 'işaretçi' yapabilirsiniz:

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';

Ne yazık ki, FEDERATED motor her zaman mevcut değildir, bu yüzden sen bile kullanabilirsiniz eğer ilk kontrol etmelisiniz. Ama o zaman sadece sadece başka bir tablo gibi, sorgularda yerel tablo t kullanabilirsiniz ve MySQL uzak sunucu ile iletişim ve diğer tarafta fiziksel masaya uygun işlemleri, öyle varsayalım.

İhtar: FEDERE tabloları ile birkaç optimizasyon sorunları vardır. Bu sizin için geçerli olmadığını ve ne dereceye kadar öğrenmek gerekir. Örneğin, bir federasyon tabloya WHERE uygulayarak birçok durumda gerçek filtreleme appplied olacak yerel sunucu, tel üzerinden pullled olan tüm tablo içeriğini neden olabilir. Başka bir sorun tablo oluşturma ile: Eğer federe masa ve tablo tanımları o MOTOR maddesinin (ve BAĞLANTILI) hariç, exacty maç işaret ettiğini çok emin olmak zorunda. Örneğin, farklı bir karakter kümesi varsa, veri tel üzerinde seyahat sonra tamamen bozuk gelebilir.

Eğer bu makaleyi okumak yok, FEDERATED tabloları kullanmak istiyorsanız http://oreilly.com/pub/a/databases/2006/08/10/mysql-federated-tables.html karar eğer belirli kullanım durumda onun sağ.

If you think you do need it, I have a utility to create federated tables here: http://forge.mysql.com/tools/tool.php?id=54 Scenario3: can't use FEDERATED, but tables on different MySQL instances Finally, if you have tables on different MySQL instances, but cannot for some reason use the federated table engine, your a out of luck I'm afraid. You are simply going to have to execute queries to both MySQL instances, receive the results and do something intelligent with it in PHP. depending on your exact requirements, this may be a perfectly viable solution

Kendine senin sorunun, benim cevap parçası iyi temyiz için karar, ve daha fazla yardıma ihtiyacınız olursa bir yorum eklemek gerekiyor sanırım. TIA Roland.

Belki bu, istediğiniz kodu


//create links
$link1 = mysql_connect('localhost', 'mysql_user', 'mysql_password');
$link2 = mysql_connect('localhost', 'mysql_user', 'mysql_password');

//set db on every link
mysql_select_db('foo', $link1);
mysql_select_db('bar', $link2);

//do query with specified link
$result1 = mysql_query($query1,$link1);
$result2 = mysql_query($query2,$link2);

Biz sorgular arasındaki bir mysql_select_db yapmadı ve biz ya sorguda veritabanı adını kullanmak vermedi unutmayın.

Ben aşağıdaki gibi ayrı test veritabanlarında tablolar kurmak:

mysql> use test;
mysql> create table foo as select 42 as id from dual;
mysql> create database test2;
mysql> use test2;
mysql> create table bar as select 42 as id from dual;

Mac OS X üzerinde MySQL 5.1.41 ve PHP 5.3.1 ile aşağıdaki PHP komut koştu:

<?php

$link = mysql_connect('localhost', 'root', 'XXXX')
 or die('There was a problem connecting to the database.');
mysql_select_db('test');

$sql = "SELECT * FROM foo JOIN test2.bar USING (id)";
if (($result = mysql_query($sql)) === FALSE) {
  die(mysql_error());
}

while ($row = mysql_fetch_array($result)) {
  print_r($row);
}

Bu test başarılı olur. Sonuç ayrı veritabanlarında iki tablo arasında birleştirme olduğunu.

Her zaman SQL kendi veritabanı isimleri tarafından nitelikli tablo (lar) seçmek gerekir. PHP mysql API bir veritabanı sorgulama için sizi kısıtlamak değil.

Her zaman mysql_select_db() ile beyan "geçerli" veritabanı için veritabanı eleme atlayabilirsiniz gerekir.

Eğer birden fazla tablodan SELECT ing Ne zaman bir takma ad sepcify var. Yani oradan oldukça basit:

SELECT
    a.id, a.name, a.phone,
    b.service, b.provider

FROM
    `people` AS a,

LEFT JOIN
    `other_database`.`providers` AS b ON a.id = b.userid

WHERE
    a.username = 'sirlancelot'

Bu sayfada diğerleri de söylediğim gibi, veritabanı aynı ana ve örnek olmalıdır. Bu sözdizimi ile başka bir sunucudan bir veritabanı sorgu olamaz.

The less verbose option you have is provided by the MySQL Manual kendisini:

The following example accesses the author table from the db1 database and the editor table from the db2 database:

USE db1;
SELECT author_name, editor_name FROM author, db2.editor
WHERE author.editor_id = db2.editor.editor_id;

Ben sadece benim bilgisayarda bu basit bir kod denedim ve mükemmel çalışıyor:

<?php

$conn = mysql_connect('localhost', 'root', '....');
mysql_select_db('aliro');

$sql = 'select * ' .
    'from aliro_permissions a ' .
    'left join cmsmadesimple.cms_permissions b on a.id=b.permission_id ';

$res = mysql_query($sql)
    or die(mysql_error());
while($row = mysql_fetch_assoc($res)){
    print_r($row);
}

?>

(Tabii ki, sorgu kendisi sadece bir örnek, anlamsızdır.)

Yani gerçekten tam sorunun ne olduğunu göremiyorum. Bunu, size yazmak istediğiniz SQL ne tür bir örnek vermek gerekecek basittir bir sözdizimi istiyorum.