Maison  >  Questions et réponses  >  le corps du texte

Comment créer une requête inter-bases de données en PHP ?

Dans notre dernier épisode (Comment créer des requêtes entre bases de données dans MySQL), j'ai appris à créer des requêtes entre bases de données dans MySQL. Cela a très bien fonctionné, mais lorsque notre héros a essayé d'utiliser ces nouvelles connaissances en PHP, il a constaté que son meilleur ami avait échoué.

J'ai regardé les PHP mysql_select_db . Cela semble signifier que si je souhaite utiliser MySQL avec PHP, j'ai quelques options :

  1. Utilisez mysql_select_db mais une seule base de données peut être utilisée à la fois. Il s'agit de notre configuration actuelle, avoir la base de données comme identifiant d'espace de noms ne semble pas fonctionner (cela fonctionne bien dans le shell MySQL, donc je sais que ce n'est pas un problème avec la configuration de notre serveur MySQL).

  2. N’utilisez pas mysql_select_db。从我看到的一些示例来看,这似乎意味着我必须为我所做的每个查询指定数据库。这是有道理的,因为我没有使用 mysql_select_db. D'après certains exemples que j'ai vus, cela semble signifier que je dois spécifier la base de données pour chaque requête que je fais. Cela a du sens puisque je n'utilise pas

    pour indiquer à PHP à quelle base de données je souhaite accéder. C'est également triste car je ne veux pas parcourir tout le code et ajouter à chaque requête le nom de la base de données.

Y a-t-il quelque chose de mieux que ça ? Existe-t-il un moyen pour moi de faire une requête MySQL inter-bases de données en PHP sans avoir à faire quelque chose de fou comme (2) ?

ClarificationSELECTforeign_db.login.username,firstname,lastname fromforeign_db.login,user where... : Aucune des réponses proposées ne me permet réellement de faire des requêtes inter-bases de données. Au lieu de cela, ils me permettent d’accéder séparément à deux bases de données différentes. Je veux une solution qui me permette de faire quelque chose comme

au lieu de simplement faire différentes requêtes dans différentes bases de données. Pour ce que ça vaut, (2) ne fonctionne pas pour moi. 🎜
P粉197639753P粉197639753383 Il y a quelques jours649

répondre à tous(2)je répondrai

  • P粉077701708

    P粉0777017082023-10-23 11:15:52

    Après avoir lu vos instructions, j'ai l'impression que vous souhaitez réellement interroger une table qui réside dans deux instances de serveur MySQL distinctes. Au moins, votre texte de clarification :

    Il est recommandé d'exécuter une requête en étant connecté en tant que deux utilisateurs (qui peuvent ou non résider sur la même instance de serveur MySQL).

    Dans votre question, vous dites que vous souhaitez interroger les données de deux bases de données différentes, mais il est important de réaliser qu'une instance MySQL peut avoir de très nombreuses bases de données. Pour plusieurs bases de données gérées par la même instance mysql, la solution proposée dans la question à laquelle vous avez lié est simple : il suffit de préfixer le nom de la base de données avant le nom de la table, en séparant les noms de la base de données et de la table par un point : .<表名>.

    Mais, comme je l'ai souligné, cela ne fonctionne que si :

    1. Toutes les bases de données auxquelles vous accédez dans une requête résident sur le même serveur, c'est-à-dire gérées par la même instance MySQL
    2. L'utilisateur connecté à la base de données dispose des autorisations appropriées pour accéder aux deux tables.

    Scénario 1 : Base de données sur le même hôte : accordez les autorisations appropriées et qualifiez les noms de tables

    Donc, si les tables résident réellement sur la même instance MySQL, il n'est pas nécessaire d'effectuer une deuxième connexion ou connexion - accordez simplement à l'utilisateur de la base de données que vous utilisez pour vous connecter à la base de données les autorisations appropriées pour obtenir toutes les tables dont vous avez besoin dans Select from . Vous pouvez le faire en utilisant la syntaxe GRANT, documentée ici : http://dev.mysql.com/doc/refman/5.1/en/grant.html

    Par exemple, GRANT SELECT ON sakila.film TO 'test'@'%' 将允许用户 test@%film 选择数据sakila 数据库中的 表。完成此操作后,用户可以使用 sakila.film(所谓的限定表名)引用该表,或者如果当前数据库设置为 sakila,只需如下所示电影

    Scénario 2 : Base de données gérée par différentes instances MySQL : Moteur FÉDÉRÉ

    Si la table à laquelle vous souhaitez accéder est effectivement gérée par deux instances MySQL différentes, il existe une astuce qui peut fonctionner ou non selon votre configuration. À partir de MySQL 5.0, MySQL prend en charge le moteur de stockage FEDERATED. Cela vous permet de créer une table qui n'est pas réellement une table, mais un judas dans la table sur le serveur distant. Le moteur est documenté ici : http://dev.mysql.com/doc/refman/5.1/en/federated-storage-engine.html

    Par exemple, si vous savez que la base de données misc sur l'hôte distant contient cette table :

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

    Vous pouvez créer un "pointeur" local vers la table distante en utilisant :

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

    Malheureusement, le moteur FEDERATED n'est pas toujours disponible, vous devez donc d'abord vérifier si vous pouvez l'utiliser. Mais en supposant que ce soit le cas, vous pouvez simplement utiliser la table locale t dans votre requête, comme n'importe quelle autre table, et MySQL communiquera avec le serveur distant et effectuera les opérations appropriées sur la table physique à l'autre extrémité.

    Attention : les tables FÉDÉRÉES présentent de multiples problèmes d'optimisation. Vous devez comprendre si et dans quelle mesure celles-ci s’appliquent à vous. Par exemple, dans de nombreux cas, l'application de WHERE à une table union peut entraîner l'extraction de l'intégralité du contenu de la table sur le réseau vers un serveur local, où le filtrage réel est appliqué. Un autre problème est la création de table : vous devez être très sûr que les définitions de la table union et de la table qu'elle pointe correspondent exactement, à l'exception de la clause ENGINE (et CONNECTION). Par exemple, si vous disposez de jeux de caractères différents, les données peuvent être complètement tronquées après avoir été transmises sur le réseau.

    Si vous souhaitez utiliser des FEDERATED tables, veuillez lire cet article http://oreilly.com/pub/a/databases/2006/08/10/mysql-federated-tables.html pour décider si cela convient à votre cas d'utilisation spécifique.

    Si vous pensez en avoir vraiment besoin, j'ai un utilitaire pour créer une table d'union ici : http://forge.mysql.com/tools/tool.php?id=54

    Scénario 3 : Impossible d'utiliser FEDERATED mais la table se trouve sur une autre instance MySQL

    Enfin, si vous avez des tables sur différentes instances MySQL mais que, pour une raison quelconque, vous ne pouvez pas utiliser le moteur de tables fédérées, j'ai bien peur que vous n'ayez pas de chance. Vous exécutez simplement une requête sur deux instances MySQL, recevez les résultats et effectuez des opérations intelligentes en PHP. En fonction de vos besoins spécifiques, cela pourrait être une solution parfaitement viable

    Je suppose que vous devez décider vous-même quelle partie de ma réponse résout le mieux votre problème et ajouter un commentaire au cas où vous auriez besoin de plus d'aide. Tia Loren.

    répondre
    0
  • P粉481366803

    P粉4813668032023-10-23 10:00:37

    Vous aurez besoin que la base de données s'exécute sur le même hôte.

    Si tel est le cas, vous devriez pouvoir utiliser mysql_select_db sur votre base de données préférée/par défaut et spécifier manuellement la base de données externe.

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

    Si votre base de données fonctionne sur un autre hôte, vous ne pourrez pas vous joindre directement. Mais alors vous pouvez faire 2 requêtes.

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

    répondre
    0
  • Annulerrépondre