2009-01-03 16 views
73

Ok, voici mon dilemme J'ai une base de données configurée avec environ 5 tables ayant toutes exactement la même structure de données. Les données sont séparées de cette manière à des fins de localisation et pour diviser un total d'environ 4,5 millions d'enregistrements.MySQL - Sélection de données à partir de plusieurs tables ayant toutes la même structure mais des données différentes

Une majorité de fois qu'une seule table est nécessaire et tout va bien. Cependant, des données sont parfois nécessaires à partir de deux ou plusieurs tables et doivent être triées par une colonne définie par l'utilisateur. C'est là que j'ai des problèmes.

colonnes de données:

id, band_name, song_name, album_name, genre 

MySQL statment:

SELECT * from us_music, de_music where `genre` = 'punk' 

MySQL recrache cette erreur:

#1052 - Column 'genre' in where clause is ambiguous 

De toute évidence, je fais ce mal. Quelqu'un veut-il éclaircir cela pour moi?

Répondre

167

Je pense que vous êtes à la recherche de la clause UNION, à la

(SELECT * from us_music where `genre` = 'punk') 
UNION 
(SELECT * from de_music where `genre` = 'punk') 
+0

merci, fonctionne exactement comment j'ai besoin :) – Jayrox

+0

Great Idea !. Un vote. – Sagotharan

+0

@ mihai-limban - désolé de vous déranger, mais existe-t-il un moyen de reconnaître à partir du jeu de résultats que "quel résultat est venu de quelle table". Beacuse, si nous avons besoin de mettre à jour/supprimer un enregistrement de ce jeu de résultats, il n'y a aucun moyen de le savoir. –

18

On dirait que vous seriez avec happer une seule table. Les cinq ayant le même schéma, et ayant parfois besoin d'être présentés comme s'ils provenaient d'une même table, mettent tout cela dans une même table.

Ajoutez une nouvelle colonne qui peut être utilisée pour distinguer les cinq langues (je suppose que c'est le langage qui est différent parmi les tables puisque vous avez dit que c'était pour la localisation). Ne vous inquiétez pas d'avoir 4,5 millions d'enregistrements. Toute base de données réelle peut gérer cette taille sans problème. Ajoutez les index corrects et vous n'aurez aucun problème à les traiter comme une seule table.

+0

À l'origine, j'avais toutes mes données dans une seule table, mais il a commencé à presque explorer pendant 5-10 secondes après environ 3,5 millions d'enregistrements. J'ai trouvé que la séparation fonctionnait mieux pour moi parce que c'était beaucoup plus rapide. J'ai un nouveau webhost maintenant, donc ça peut être mieux, mais ça me semble trop compliqué de le combiner – Jayrox

+23

On dirait que vous devez ajouter des index aux tables. –

+2

Encore une fois, je voudrais pouvoir upvote les commentaires ... – staticsan

4

Tout des réponses ci-dessus sont valables, ou une autre façon est d'élargir le nom de la table pour inclure le nom de base de données ainsi - par exemple:

SELECT * from us_music, de_music where `us_music.genre` = 'punk' AND `de_music.genre` = 'punk' 
+0

qui vous donne un ensemble de résultats très mal définis: toutes les paires possibles de us_ et de_ punk. –

3

La colonne est ambiguë, car elle apparaît dans les deux tableaux que vous Il faudrait spécifier le champ where (ou sort) complètement tel que us_music.genre ou de_music.genre mais vous spécifieriez généralement deux tables si vous alliez les joindre ensemble d'une manière ou d'une autre. La structure que vous traitez est parfois appelée table partitionnée, bien que cela soit généralement fait pour séparer l'ensemble de données en fichiers distincts, plutôt que de simplement diviser l'ensemble de données arbitrairement. Si vous êtes responsable de la structure de la base de données et qu'il n'y a pas de bonne raison de partitionner les données, je construis une grande table avec un champ "origine" supplémentaire qui contient un code de pays mais vous le faites probablement pour des raisons de performances légitimes . Utilisez une union pour joindre les tables qui vous intéressent http://dev.mysql.com/doc/refman/5.0/en/union.html ou en utilisant le moteur de base de données Merge http://dev.mysql.com/doc/refman/5.1/en/merge-storage-engine.html.

3

Votre tentative originale d'étendre les deux tables crée une jointure implicite. Ceci est désapprouvé par les programmeurs SQL les plus expérimentés car il sépare les tables pour les combiner avec la condition de comment.

Le UNION est une bonne solution pour les tables telles quelles, mais il ne devrait pas y avoir de raison pour qu'elles ne puissent pas être placées dans une table avec une indexation correcte. J'ai vu l'ajout de l'index correct à une grande table augmenter la vitesse de requête de trois ordres de grandeur.

3

L'instruction union entraîne une perte de temps dans les données volumineuses.Il est bon d'effectuer la sélection en 2 étapes:

  1. sélectionnez l'ID
  2. puis sélectionnez la table principale avec elle