Выбор иерархической конфигурации - PullRequest
0 голосов
/ 11 января 2012

Редактировать: извините за путаницу. Только что получил одобрение от моего босса, чтобы опубликовать эту часть схемы. У меня было бы больше деталей в исходном сообщении, если бы мне разрешили опубликовать изображение.

У меня есть схема конфигурации, которая выглядит следующим образом:

http://img717.imageshack.us/img717/7297/heirarchy.png

Каждый из уровней содержится в уровне ниже его (т. Е. У партнера есть несколько программ), и каждый уровень конфигурации имеет общие ключи конфигурации с другими типами уровней конфигурации (т. Е. - часовой пояс по умолчанию может быть установлен у партнера уровень, а затем будет переопределен на уровне программы, портфолио или устройства).

То, что это позволяет нам сделать, - это установить тип объекта по умолчанию, а затем переопределить его с помощью более конкретных таксономий. Например:

Скажем, у меня есть партнерский объект, который является компанией. Скажем, что имя_Интерфейса_конфигурации 1 - часовой пояс по умолчанию. Я поместил partner_configuration, который говорит, что чаще всего этот партнер будет находиться на восточном побережье (время по Нью-Йорку).

Теперь у меня есть несколько программ, которые поддерживает этот партнер. Скажите, что конкретная программа основана за пределами Калифорнии. Я поместил program_configuration, который говорит, что устройства в этой программе имеют время Сакраменто.

Теперь давайте пропустим портфолио и скажем, что кто-то, подписавшийся на эту программу из Калифорнии, переезжает в Денвер, но все еще остается его клиентом. Мы установили конфигурацию Устройства, которая говорит, что они сейчас в Маунтин-Вью.

Иерархия выглядит так:

Level     |Timezone (hierarchy_configuration_key 1)
---------------------------------------------------
Partner   |NYC
Program   |Sacramento
Portfolio |null (defaults to most granular above it, so Sacramento)
Device    |Denver

Теперь я хочу выбрать мои конфигурации, сгруппированные по иерархии_конфигурации_key_id:

Я могу использовать внутренние объединения для обхода уровней, но я хочу, чтобы выборка давала мне такой результат (сгруппированный по иерархии_конфигурации_key_id) для первичного ключа устройства (device_id):

device_id |portfolio_id |program_id |partner_id |device_config |portfolio_config |program_config| partner_config
---------------------------------------------------------------------------------------------------------------------
1         |2            |1          |35         |Denver        |null             |Sacramento    | NYC

Также приемлемым будет выбор, который только что дал мне наиболее подходящее значение конфигурации, т. Е .:

device_id |portfolio_id |program_id |partner_id |config_value
-------------------------------------------------------------
1         |2            |1          |35         |Denver      

Заранее спасибо. Дайте мне знать, если вам нужно больше разъяснений.

Ответы [ 2 ]

0 голосов
/ 17 января 2013

Это решение основано на вашей схеме: @ param1 - имя_иерархии_конфигурации_ключ, а @ param2 - желаемый идентификатор_устройства. Он использует метод, похожий на метод Демса, хотя он был получен независимо, за исключением моего заимствования COALESCE.

SELECT *,
IF(dv_key IS NOT NULL,'device',IF(pf_key IS NOT NULL,'portfolio',IF(pg_key IS NOT NULL,'program',IF(pt_key IS NOT NULL,'partner',NULL)))) AS hierarchy_level,
COALESCE(dv_key,pf_key,pg_key,pt_key) AS key_id,
COALESCE(dv_value,pf_value,pg_value,pt_value) AS value
FROM
(SELECT sim_id,
dv.device_id, pt.partner_id, pg.program_id, pf.portfolio_id,
dvc.hierarchy_configuration_key_id AS dv_key, dvc.configuration_value AS dv_value,
pfc.hierarchy_configuration_key_id AS pf_key, pfc.configuration_value AS pf_value,
pgc.hierarchy_configuration_key_id AS pg_key, pgc.configuration_value AS pg_value,
ptc.hierarchy_configuration_key_id AS pt_key, ptc.configuration_value AS pt_value
FROM device dv
LEFT JOIN portfolio pf USING(portfolio_id)
LEFT JOIN program pg USING(program_id)
LEFT JOIN partner pt USING(partner_id)
LEFT JOIN device_configuration dvc ON dv.device_id=dvc.device_id AND dvc.hierarchy_configuration_key_id=@param2 AND dvc.active='true'
LEFT JOIN portfolio_configuration pfc ON pf.portfolio_id=pfc.portfolio_id AND pfc.hierarchy_configuration_key_id=@param2 AND pfc.active='true'
LEFT JOIN program_configuration pgc ON pg.program_id=pgc.program_id AND pgc.hierarchy_configuration_key_id=@param2 AND pgc.active='true'
LEFT JOIN partner_configuration ptc ON pt.partner_id=ptc.partner_id AND ptc.hierarchy_configuration_key_id=@param2 AND ptc.active='true'
WHERE dv.device_id = @param1) hierchy;
0 голосов
/ 11 января 2012

Я думаю, что единственная часть, которая здесь не работает, указана в комментарии @ EugenRieck ...
- Which field tells the Miata it is a Child of Mazda?

Я бы немного изменил структуру ...

ENTITY_TABLE

entity_id | parent_entity_id | entity_name
     1            NULL         Vehicle
     2             1           Car
     3             2           Mazda
     4             3           Miata
     5             1           Cycle
     6             5           Unicycle
     7             6           Broken Unicycle


PROPERTY_TABLE

entity_id | property_type | value
     1          Wheels        4
     2          Wheels        NULL
     3          Wheels        NULL
     4          Wheels        NULL
     5          Wheels        2
     6          Wheels        1
     7          Wheels        0

     (And repeated for other property types as appropriate)


-- Every entity must have the same properties as the parents
-- (otherwise you have to find the topmost parent first to know what properties exist)

-- An entity may only have 1 parent

-- The topmost parent must have a NULL parent_id

-- The bottommost parent must be no more than 3 joins away from the topmost parent

Тогда у тебя может быть что-то вроде этого ...

SELECT
  entity1.id,
  property1.property_type,
  entity1.name,
  entity2.name,
  entity3.name,
  entity4.name,
  property1.value,
  property2.value,
  property3.value,
  property4.value,
  COALESCE(property1.value, property2.value, property3.value, property4.value) AS inherited_value
FROM
  entity               AS entity1
LEFT JOIN
  entity               AS entity2
    ON entity2.id = entity1.parent_id
LEFT JOIN
  entity               AS entity3
    ON entity3.id = entity2.parent_id
LEFT JOIN
  entity               AS entity4
    ON entity4.id = entity3.parent_id
INNER JOIN
  property             AS property1
    ON property1.entity_id = entity1.id
LEFT JOIN
  property             AS property2
    ON  property2.entity_id     = entity2.id
    AND property2.property_type = property1.property_type
LEFT JOIN
  property             AS property3
    ON  property3.entity_id     = entity3.id
    AND property3.property_type = property1.property_type
LEFT JOIN
  property             AS property4
    ON  property4.entity_id     = entity4.id
    AND property4.property_type = property1.property_type
WHERE
    entity1.id              = @entity_id
AND property1.property_type = @property_type
...