2009-12-18 5 views
1

Надеюсь, вы можете помочь мне с разрешением этой задачи у нас есть.динамический sql сводный стол

первоначально у нас есть эти таблицы:

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 

то, что нам сейчас нужно, это функция, которая представляет данные таким образом (по типу аппаратура)

для hwtype.name = маршрутизатор

element speed IP 
RTR1  100mb 172.16.3.23 
RTR2  10mb 172.16.3.26 

Идея состоит в том, чтобы таблицы могли включать новые типы элементов, элементы и атрибуты без необходимости изменять кодирование таблиц.

Я искал примеры, но, к сожалению, я нашел хорошие, которые выполняют агрегацию по значениям, которые я не рассматривал.

заранее спасибо за вашу помощь

+4

Задавая вопросы о SQL, обязательно маркировать с СУРБДОМ вы используете. Например. 'sql-server',' oracle', 'mysql' и т. д. Это важно для ответа. –

+1

Вы не первый человек, мечтающий о системе, которая не требует изменений в базе данных, используя архитектуру Entity-Value. К сожалению, вы, вероятно, не будете последним, чтобы проклинать это решение в конце концов :(Если еще не поздно изменить архитектуру, вы должны это рассмотреть. –

ответ

0

Вы используете EAV антипаттерн. Это нарушает всевозможные правила реляционной базы данных, и, как вы обнаружили, получение данных очень неудобно. Есть много других недостатков этого дизайна, которые перечислены в другом месте.

Прочитайте статью «Bad CaRMa» за отличную историю о том, как система EAV уничтожила компанию.

Вот что вы должны сделать, чтобы получить маршрутизатор атрибуты из базы данных:

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'; 

Заметим, что вам требуется дополнительная пара присоединяется для каждого атрибута если вы настаиваете на выборку всех атрибутов заданный элемент в одной строке. Это быстро становится непомерно дорогостоящим для оптимизатора SQL.

Это гораздо проще для извлечения атрибутов на нескольких строках, и разобраться в коде приложения:

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'; 
Смежные вопросы