2009-12-18 10 views
1

J'espère que vous pouvez m'aider avec la résolution de cette tâche que nous avons.dynamique table pivotante sql

à l'origine nous avons ces tables:

hwtype 
id name 
1 router 
2 switch 

hwelement 
id idhwtype name 
1 1   RTR1 
2 1   RTR2 
3 2   SWT1 

hwattributes 
id idhwtype name 
1 1  speed 
2 1  IP 
3 2  ports 

hwtypeattributes 
id idhwelement idhwattribute value 
1 1    1    100mb 
2 1    2    172.16.3.23 
3 2    1    10mb 
4 2    2    172.16.3.26 
5 3    3    8 

ce que nous avons besoin est maintenant une fonction qui présente les données de cette façon (de hwtype selon)

pour hwtype.name = routeur

element speed IP 
RTR1  100mb 172.16.3.23 
RTR2  10mb 172.16.3.26 

L'idée est de rendre les tables capables d'inclure de nouveaux types d'éléments, éléments et attributs sans avoir à modifier le codage des tables.

Je cherchais des exemples mais malheureusement j'avais trouvé de bons agrégats sur des valeurs que je n'avais pas pris en compte.

merci d'avance pour votre aide

+4

Lorsque vous posez des questions sur SQL, assurez-vous de marquer avec la marque de SGBDR que vous utilisez. Par exemple. 'sql-server',' oracle', 'mysql', etc. Cela compte pour la réponse. –

+1

Vous n'êtes pas la première personne à rêver d'un système qui ne nécessite aucune modification de la base de données en utilisant l'architecture Entity-Value. Malheureusement, vous ne serez probablement pas le dernier à maudire cette décision non plus :(S'il n'est pas trop tard pour changer l'architecture, vous devriez le considérer. –

Répondre

0

Vous utilisez le EAV. Antimodèle Cela brise toutes sortes de règles de conception de bases de données relationnelles et, comme vous l'avez découvert, obtenir des données est très difficile. Il y a beaucoup d'autres faiblesses de cette conception, relatées ailleurs.

Lisez l'article "Bad CaRMa" pour découvrir comment un système EAV a détruit une entreprise.

Voici ce que vous devez faire pour obtenir le routeur attributs de votre base de données:

SELECT e.name AS "element", 
     speedval.value AS "speed", 
     ipval.value AS "IP", 
     portsval.value AS "Ports" 
FROM hwtype t 
JOIN hwelement e ON (e.idhwtype = t.id) 
JOIN hwattributes speed ON (speed.idhwtype = t.id AND speed.name = 'speed') 
LEFT OUTER JOIN hwtypeattributes speedval 
    ON (speedval.idhwattribute = speed.id AND speedval.idhwelement = e.id) 
JOIN hwattributes ip ON (ip.idhwtype = t.id AND ip.name = 'ip') 
LEFT OUTER JOIN hwtypeattributes ipval 
    ON (ipval.idhwattribute = ip.id AND ipval.idhwelement = e.id) 
JOIN hwattributes ports ON (ports.idhwtype = t.id AND ports.name = 'ports') 
LEFT OUTER JOIN hwtypeattributes portsval 
    ON (portsval.idhwattribute = ports.id AND portsval.idhwelement = e.id) 
WHERE t.name = 'router'; 

Notez que vous avez besoin d'une paire supplémentaire de jointures pour chaque attribut si vous insistez sur aller chercher tous les attributs d'un élément donné sur une seule ligne. Cela devient rapidement prohibitif pour l'optimiseur SQL.

Il est beaucoup plus facile de récupérer les attributs sur plusieurs lignes, et le tri dans le code d'application:

SELECT e.name AS "element", a.name, v.value 
FROM hwtype t 
JOIN hwelement e ON (e.idhwtype = t.id) 
JOIN hwattributes a ON (a.idhwtype = t.id) 
JOIN hwtypeattributes v ON (v.idhwattribute = a.id AND v.idhwelement = e.id) 
WHERE t.name = 'router';