2010-06-18 11 views
0

Notre projet a ~ 40 tables avec des relations complexes.Un collègue croit en l'utilisation de requêtes de jointure longues qui m'oblige à connaître les tables en dehors de mon module mais je ne pense pas aux tables directement liées à mon module. fonctions (écrites par les responsables d'autres modules) lorsque j'ai besoin de données provenant d'eux. Permettez-moi de clarifier:Est-ce que les JOIN complexes impliquent des problèmes de couplage et de maintenance?

Je suis responsable du module ContactVendor qui permet aux clients de contacter le fournisseur et de démarrer une conversation sur un produit spécifique. Le module Produits possède ses propres tables complexes et des relations avec des fonctions qui encapsulent les détails (par exemple, i18n, activation, disponibilité des produits, etc ...). Maintenant, je dois montrer le titre du produit de certains produits liés à une conversation entre le vendeur et les clients. Je peux soit écrire une longue requête qui récupère l'information du produit avec des trucs de conversation en un coup (ce qui m'oblige à en apprendre davantage sur les tables de produits) OU je peux passer le product_id pertinent à la fonction get_product_info (int).

Première approche est évidemment exigeante et introduit de nombreuses mauvaises pratiques et des choses que je considère normalement comme un défaut dans la programmation. Le problème avec la seconde approche semble être les innombrables mini requêtes que ces fonctions d'accès provoquent et la perte de performance est une préoccupation lorsqu'une boucle essaie d'extraire des titres de produits pour 100 produits en utilisant des fonctions qui effectuent chacune une requête séparée. Je suis donc coincé entre "ne codez pas l'implémentation, le code à l'interface" et la performance. Quelle est la bonne façon de faire les choses?

MISE À JOUR: Je suis particulièrement préoccupé par les futures modifications possibles de ces tables en dehors de mon module. Et si le module Produits décidait de changer sa façon de faire? ou pour une raison quelconque, modifier le schéma? Cela signifie que d'autres modules se casseraient ou fonctionneraient mal jusqu'à ce que le changement leur soit intégré. Le problème habituel de l'effet d'entraînement.

Répondre

0

Je peux voir les deux côtés de la question. Cependant, étant donné que vous dites qu'il y a seulement environ 40 tables, il me semble que la complexité d'interagir avec, disons, 30 autres tables en dehors de votre domaine d'expertise est minime. Je voterais pour écrire les requêtes qui font les jointures complexes. Après tout, autre que de connaître les colonnes exactes dans la table, ce qui devrait être facile, tout ce que vous devez vraiment savoir, ce sont des relations spéciales ou des significations spéciales que ces tables utilisent.

Mais l'autre élément qui pourrait me convaincre est quelles sont les exigences de performance? Si le système est actuellement assez rapide et que les tailles de matériel et de table sont telles qu'il sera toujours assez rapide en utilisant des requêtes séparées pour chaque table, allez-y et faites-le en utilisant la 2ème approche si cela facilite la vie de tout le monde. Mais d'autre part, si quelqu'un s'est jamais plaint de la vitesse, ou si les tables sont susceptibles de croître sans limite dans le futur, ou si votre nombre d'utilisateurs est susceptible d'augmenter, faites-le en utilisant la méthode qui a le meilleur espoir d'être plus rapide.

RÉPONSE À COMMENTAIRES: Pas nécessairement. Supposons que le module de produit a ajouté 5 nouvelles colonnes. Soit vous ne les utilisiez pas déjà, et donc ne vous y joignez pas ou ne les récupérez pas, et vous ne serez pas affecté quelle que soit la méthode choisie, ou vous en aurez besoin et devrez écrire un nouveau code pour savoir comment les traiter. Quoi qu'il en soit, les changements de votre côté seraient les mêmes quelle que soit la méthode choisie. Dites le module Produit renommé ou supprimé 3 colonnes. Ensuite, votre côté devrait changer la façon dont il a géré les valeurs retournées, indépendamment de la façon dont l'interface a été écrite. Je vois ce que vous obtenez, mais la ligne de fond, à mon humble avis, est que si vous utilisez les champs impliqués dans le changement, vous devez faire des changements de code. Si les champs ne sont pas utilisés par vous, ce n'est pas le cas. L '"effet d'entraînement" que vous mentionnez ne devrait pas exister si vous ne récupérez que les colonnes que vous voulez, au lieu d'utiliser les requêtes select * from tbl.

+0

Je vois, mais que se passe-t-il si le module Produit a décidé de modifier son schéma? l'effet d'entraînement qui en résulterait ne détruirait-il pas beaucoup de modules? Si, d'autre part, tous les autres modules accèdent aux produits en utilisant l'interface fournie par le module Product, alors rien ne se passera mal (j'espère! ;-)) –

+0

@ ashkan.kh: Ma réponse était trop longue, donc je l'ai ajouté ci-dessus dans la réponse. – MJB

0

Que diriez-vous de travailler avec des vues ici?Au lieu d'appeler la fonction get_product_info, faites en sorte que chaque responsable de module fournisse des vues à ce module, telles que product_info_view, puis utilisez cette vue avec votre requête. Comme ceci, vous n'avez pas à vous soucier des internes (tables) d'une telle vue mais vous obtiendrez toujours l'avantage de performance, car le moteur de base de données simplifiera la requête finale contenant votre code et la vue.

+0

Les vues semblent être la bonne façon de procéder. Mais je suis plutôt intéressé de savoir comment ces choses sont faites dans les produits professionnels. Je suppose que cette facette fondamentale du développement aurait déjà dû être bien étudiée par des experts sur le terrain. –

0

La manière correcte de faire ce genre de choses (Persistance/Source de données/ORM) est très bien décrite par Martin Fowler dans son livre étonnant: Patterns of Enterprise Application Architecture. Le livre est une lecture incontournable pour tout le monde dans le développement de l'entreprise.