2017-08-28 5 views
1

Quelque chose m'embête vraiment et je ne suis pas sûr de l'approche "correcte". Si je fais une sélection pour obtenir des contacts de ma base de données, il y a un nombre décent de jointures impliquées.MySQL 1: N Mappage de données

Il ressemblera à quelque chose comme ça (autour de colonnes 60-70): société

SELECT * 
FROM contacts 
LEFT JOIN company 
LEFT JOIN person 
LEFT JOIN address 
LEFT JOIN person_communication 
LEFT JOIN company_communication 
LEFT JOIN categories 
LEFT JOIN notes 

et par personne sont 1: 1 cardinalité donc son droit d'en avant. Mais "adresse", "communication" et "catégories" sont cardinalité 1: n. Donc, en fonction de la quantité de lignes dans les tables 1: n, je vais avoir beaucoup de "doubles" lignes (je ne sais pas quel est le terme réel pour cela, les lignes ne sont pas doubles, je sais que l'adresse ou numéro de téléphone, etc. est différent). Pour moi-même en tant que contact, un contact assez rempli, je récupère 85 lignes.

Comment travaillez-vous avec ça? Dans mon application PHP j'ai toujours écrit "Data-Mapper" où la clé de tableau était le "contact.ID aka primaire" et ensuite vérifié si elle existe et ensuite poussé les données supplémentaires en elle. De plus PHP n'est pas vraiment typé strict ce qui le rend facile.

Maintenant j'apprends GO (golang) et je pensais vis qui Loooong mappage de sélection et de données il suffit d'écrire sélectionne pour tous les 1: n .... ouais non, pas suffisamment de connexions pour charger une table complète des contacts. Je sais que je peux augmenter les connexions, mais l'erreur semble impliquer que ce serait la mauvaise façon. J'utilise le pilote suivant: https://github.com/go-sql-driver/mysql

J'ai aussi essayé GROUP_CONCAT mais j'ai ensuite eu des problèmes pour l'analyser.

Est-ce que je dois refaire ma cartographie ou existe-t-il une solution intéressante? Je l'ai trouvé assez sale aux points tho?

+0

Je ne sais pas ce qui serait correct ou non, mais vous pouvez essayer le 1-> plusieurs comme une requête séparée dans une foreach, et amasser les résultats de cela dans les résultats de votre première requête. – aynber

+0

Trop de jointures. Si vos tables deviennent vraiment grandes, elles peuvent devenir très lentes. – vladatr

+0

@vladatr Ouais je sais, donc vous dites que je devrais résoudre le problème avec le "à de nombreuses connexions" alias le soulever ou construire une file d'attente? – Tiega

Répondre

1

La solution est simple: vous devez exécuter plus d'une requête!

La cause de toutes les lignes "en double" est que vous générez un résultat appelé Cartesian product. Vous essayez de vous joindre à plusieurs tables avec des relations 1: n, mais chacune d'entre elles n'a aucune relation avec l'autre, donc aucune condition de jointure ne les restreint les unes par rapport aux autres.

Par conséquent, vous obtenez un résultat avec toutes les combinaisons de toutes les relations 1: n. Si vous avez 3 correspondances dans address, 5 correspondances dans communication, et 5 correspondances dans categories, vous obtiendrez 3x5x5 = 75 lignes.

Vous devez donc exécuter une requête SQL distincte pour chacune de vos relations 1: n. N'ayez pas peur - MySQL peut gérer quelques requêtes. Vous en avez besoin.

+0

Ok, je comprends votre point et comprends parfaitement cela. Comment puis-je créer une requête de recherche pour le numéro de téléphone alors? Est-ce que je crée une vue pour trouver l'ID primaire et continue comme dit? – Tiega

+1

Vous pouvez faire une sous-requête, ou deux requêtes distinctes. –