2010-05-11 10 views
1

J'ai deux tables sur différents serveurs, et je voudrais de l'aide pour trouver un moyen efficace de combiner et de faire correspondre les jeux de données. Voici un exemple:Une manière efficace de combiner les résultats de deux requêtes de base de données

du serveur 1, qui contient nos histoires, j'effectue une requête comme:

query = """SELECT author_id, title, text 
      FROM stories 
      ORDER BY timestamp_created DESC 
      LIMIT 10 
      """ 
results = DB.getAll(query) 

for i in range(len(results)): 
    #Build a string of author_ids, e.g. '1314,4134,2624,2342' 

Mais, je voudrais chercher quelques informations sur chaque author_id du serveur 2:

query = """SELECT id, avatar_url 
      FROM members 
      WHERE id IN (%s) 
      """ 
values = (uid_list) 
results = DB.getAll(query, values) 

Maintenant, j'ai besoin d'un moyen de combiner ces deux requêtes afin que j'ai un dict qui a l'histoire ainsi que avatar_url et member_id.

Si ces données étaient sur un seul serveur, il serait simple jointure qui ressemblerait à ceci:

SELECT * 
FROM members, stories 
WHERE members.id = stories.author_id 

Mais puisque nous enregistrons les données sur plusieurs serveurs, ce n'est pas possible.

Quel est le moyen le plus efficace de faire cela? Je comprends que la fusion doit probablement se produire dans mon code d'application ... tout exemple de code efficace qui minimise le nombre de boucles dict serait grandement apprécié!

Merci.

Répondre

2

Si la mémoire n'est pas un problème, vous pouvez utiliser un dictionnaire.

results1_dict = dict((row[0], list(row[1:])) for row in results1) 
results2_dict = dict((row[0], list(row[1:])) for row in results2) 

for key, value in results2_dict: 
    if key in results1_dict: 
     results1_dict[key].extend(value) 
    else: 
     results1_dict[key] = value 

Ce n'est pas particulièrement efficace (n), mais il est relativement simple et vous pouvez le tordre pour faire exactement ce dont vous avez besoin.

0

Vous devrez rassembler les données en quelque sorte.

  • Il y a des choses comme des liens de serveur (bien que ce soit probablement pas le terme correct dans le contexte de MySQL) qui pourrait permettre l'interrogation accross différents blocs de données. Cela ouvre un autre ensemble de problèmes (sécurité!)

  • La solution la plus simple consiste à regrouper les données dans un seul DB.

  • La dernière solution (la moins souhaitable) consiste à joindre du code comme le suggère Padmarag.

0

La seule option semble être Database Link, mais n'est malheureusement pas disponible dans MySQL.
Vous devrez faire la fusion dans votre code d'application. Mieux vaut conserver les données dans la même base de données.

+0

Salut - Je suis d'accord, je dois le faire dans mon code d'application. Je cherche le moyen le plus efficace de le faire dans mon application. Tout exemple de code serait grandement apprécié. – ensnare

+0

Si vous le faites dans votre code, vous devez comparer l'entrée à l'entrée des résultats en saisissant les données combinées dans une troisième structure de données (par exemple un dictionnaire). C'est très spécifique au domaine, vous êtes la plupart du temps seul, j'ai peur. – lexu

0

Est-il possible de configurer la réplication des tables nécessaires d'un serveur à une base de données sur l'autre? De cette façon, vous pouvez avoir toutes vos données sur un serveur.

De plus, voir le moteur de stockage FEDERATED, disponible depuis mysql 5.0.3.