2009-04-03 9 views
1

Quels sont les meilleurs moyens (plus propres, moins coûteux en ressources) de transmettre des relations un-à-plusieurs d'un serveur db à un client? Imaginez que j'ai une table auteur et une table livre. Je veux récupérer tous les auteurs dont le nom commence par "a" et tous les livres qu'ils ont écrits. Ensuite, côté client, générer un tableau d'objets "Auteur" dont le champ "Livres" est un tableau d'objets "Livres".Quelle est la meilleure façon de gérer les ensembles d'enregistrements (imbriqués)?

Deux pauvres solutions homme qui me viennent à l'esprit sont:

  1. Extrayez tous les auteurs, le cycle à travers eux sur le client et exécuter une requête supplémentaire pour obtenir tous les livres
  2. « SELECT a *. FROM auteur a, livre b WHERE a.name comme 'A%' et b.author_id = a.id "

La première solution est vraiment intensive côté base de données (si j'ai 1000 auteurs, je dois exécuter 1001 requêtes).

La seconde nécessite un travail intensif côté client, car le programme analyserait le résultat car il a les données communes à l'auteur répétées sur chaque ligne.

Une autre solution consisterait à renvoyer plusieurs jeux d'enregistrements à partir d'une procédure stockée. Je n'ai jamais manipulé plusieurs ensembles d'enregistrements et je ne suis pas sûr que toutes les classes de langues/adaptateurs les supportent.

Bien sûr, la situation peut s'aggraver si un auteur peut avoir des livres et essais et chaque livre peut avoir des pages d'échantillons et ainsi de suite.

Une idée? Merci

EDIT: J'utilise .net, donc les données de l'ado sont une option. Sont-ils soutenus mon oracle et mysql?

Répondre

0

Je pense que ce dernier est probablement plus proche d'une bonne solution que le premier. Cela dit, vous pouvez introduire une couche entre le client et la base de données - sur la machine de base de données - qui peut filtrer et traiter les lignes de la base de données dans la ou les structures de données de votre choix.

0

Cela peut dépendre du choix du SGBDR, certains d'entre eux peuvent prendre en charge certaines fonctionnalités qui permettent la fonction souhaitée, bien que la fonctionnalité ne soit pas portable vers un autre SGBDR. Par exemple, Microsoft SQL Server, à partir de SQL 2000, prend en charge SELECT FOR XML à titre d'exemple. Ceci, lorsque le schéma XML est conçu avec soin (par exemple FOR XML EXPLICIT), fera exactement ce que vous voulez faire - retourner un XML qui vous donne la hiérarchie des données. Si vous utilisez également ADO.NET et choisissez de le charger dans un DataSet à l'aide de SqlDataAdaptor, le résultat DataSet aura en fait toutes les données déjà définies dans DataTables, avec DataRelations correct mis en place entre DataTables. Cependant, il s'agit probablement d'une fonctionnalité spécifique à MS-SQL, et le fait de travailler dans un autre SGBDR peut nécessiter d'autres techniques.

+0

je suis à la recherche d'une solution portable, que je développe en .net, mais connecter à MS-SQL, Oracle et les bases de données MySQL – pistacchio

0

Nous utilisons plusieurs jeux d'enregistrements. Si vous avez une autre entité liée à l'auteur, ajoutez simplement un autre jeu d'enregistrements. Je ne suis pas sûr d'Oracle et MySQL, mais si les implémentations correspondantes de IDataReader ont NextResult() ne lance pas NotSupportedException, cela devrait fonctionner pour eux.

0

En supposant un cas typique, votre volume de données sera largement dans la table "Livres".Prenez la solution la plus simple, pour laquelle la pénalité est faible pour toute taille d'affichage que vous souhaitez infliger à un utilisateur: joignez les deux ensemble et renvoyez un seul ensemble de lignes avec une certaine quantité de redondance dans les données Colum "Auteurs". D'autres solutions nécessitent des requêtes multiples qui, dans la plupart des cas, sont à la fois plus coûteuses et plus complexes.

Mon ordre de priorité est généralement: Fournir le contenu requis pour la meilleure expérience d'interface utilisateur, structurée pour l'implémentation la plus simple (avec les avertissements normaux sur les circonstances inhabituelles dictant des conceptions inhabituelles). Ceci est probablement le meilleur moyen de découpler votre stratégie de données des changements dans la conception de votre interface utilisateur, car tout le contenu se trouve dans un ensemble de résultats facilement navigables.

2

Vos deux questions ici. L'un est la façon la plus efficace de recueillir les données, l'autre est de savoir comment traiter les données que vous recevez.

d'abord comment ramasserez:

SELECT a.* FROM Author a INNER JOIN Book b ON a.id=b.author_id WHERE left(a.name,1)='a' 

Comme est très cher, éviter si vous le pouvez. Les jointures internes sont votre moyen le moins coûteux de comparer des tables - en particulier si vous avez des index sur les clés primaires (id) et étrangères (author_id) S'il y a des auteurs sans livres (je ne serais pas un auteur je suppose), utilisez un LEFT JOIN (la même syntaxe change simplement 'inner' en 'left')

Deuxième. Si vous parlez de milliers d'enregistrements, vous pouvez penser à rassembler les données en deux tirages distincts (comme votre premier choix, je pense), sauf si vous voulez que l'utilisateur attende indéfiniment pour le chargement de la page. Par exemple: l'utilisateur choisit tous les auteurs qui commencent par a et reçoit une liste - vous pourriez même avoir un compte des articles de cet auteur.

SELECT a.Name count(b.author_id) titles 
FROM Author a INNER JOIN Book b ON a.id=b.author_id 
WHERE left(a.name,1)='a' 
GROUP BY a.Name 

Ils verraient

John Adam: 35 Titles 
Jane Acaba: 18 Titles 
Jim Allan: 3 Titles 

Ensuite, l'utilisateur clique sur l'auteur, charger la liste des livres pour cet auteur.

Jim Allan's Titles: 
    Froggy went a court'n 
    Death on the Nile 
    Life in Africa 

Si vous voulez qu'il apparaisse comme il est fait avec une traction, mais vous voulez qu'il vienne sur l'utilisation très rapide XMLHTTP ou ajax pour afficher la liste des auteurs. C'est un tout autre sujet. :)

Je dois également ajouter que les procédures stockées sont un must. La volonté ajoutera de manière significative à la portabilité de l'application ainsi qu'à la performance dans la plupart des bases de données.

HTH

Questions connexes