Таблицы размеров нагрузки - методологии - PullRequest
3 голосов
/ 10 июня 2010

Недавно я работал над проектом, в котором необходимо заполнить таблицы DIM из таблиц EDW.

Таблицы EDW относятся к типу II, который поддерживает исторические данные.Когда приходит загрузка Dim Table, для которого источником может быть несколько таблиц EDW или будет одна таблица с многоуровневым поворотом (по атрибутам).

Значение: будет 10 записей - по одной для каждого атрибута, который долженповорачиваться на domain_code, чтобы сделать одну строку в Dim.Из этих 10 записей будут некоторые атрибуты с тем же domain_code, но с другим sub_domain_code, который требует дальнейшего поворота для кода субдомена.

Пример:

, если я получил код домена: 01,02,03 => которые представляют собой прямую точку в коде домена. У меня также будет код домена: 10 с кодом / версией субдомена как 2006,2007,2008,2009

Это означает, что мне нужно разбить исходную таблицу с указанными выше атрибутами надва => один для кода домена и другой для domain_code + version.

пока все хорошо.

Когда дело доходит до загрузки таблицы затемнения:

В соответствии со спецификациями дизайна для Dimensions (изначально написанных третьей стороной), они хотят:

для каждого отдельного изменения вEDW (атрибут), он должен собрать все связанные записи (для этого NK) означает новую с другими значениями атрибута, которые являются текущими => обработать их, чтобы создать новую тусклую запись и вставить ее.

Это означает, что еслиодин фрагмент содержит 100 обновленных записей (по одной на каждый NK), он должен собрать 100 + (100 * 9) записей для вставки / обновления таблицы затемнения.Насколько хорош этот подход.

Другой способ, который я попытался сделать, это просто выполнить поиск в dim-таблице, чтобы этот NK получил значение последних записей (атрибуты, которые не изменились), вставил его и обновил текущий.

Каков будет лучший подход - собирать записи на стороне источника для одного изменения атрибута или просматривать недавнюю запись таблицы dim и обрабатывать ее.

Если это не имеет смысла, хотелось бы уточнитьэто далее.

Спасибо

Вот модель таблиц

альтернативный текст http://img96.imageshack.us/img96/1203/modelzp.jpg

1 Ответ

1 голос
/ 18 июня 2010

Посмотрите на этот пример .

Это должно быть относительно просто.

Поворачивает базовые данные в соответствии с вашими правилами.

Определяет время изменения денормализованной "строки"

Создает треугольное соединение для определения начала и конца каждого периода (то, что я называю снимком)

Затем он присоединяет эти окна к базовым данным, чтобы определить, какое состояние данных было в то время (в этот момент сводка фактически завершена)

Я думаю, что вам, возможно, придется взглянуть на механизм управления окнами - он возвращает правильные данные, но мне не нравится, как мне выглядит логика перекрытия окон - она ​​не совсем маленькая, верно - я беспокоюсь о граничные условия.

-- SO3014289

CREATE TABLE #src (
    key1 varchar(4) NOT NULL
    ,key2 varchar(3) NOT NULL
    ,key3 varchar(3) NOT NULL
    ,AttribCode int NOT NULL
    ,AttribSubCode varchar(2)
    ,Value varchar(10) NOT NULL
    ,[Start] date NOT NULL
    ,[End] date NOT NULL
)

INSERT INTO #src VALUES
('9750', 'C04', '789', 1, NULL, 'AAA', '1/1/2000', '12/31/9999')
,('9750', 'C04', '789', 2, NULL, 'BBB', '1/1/2000', '12/31/9999')
,('9750', 'C04', '789', 3, 'V1', 'XXXX', '1/1/2000', '12/31/9999')
,('9750', 'C04', '789', 3, 'V2', 'YYYY', '1/1/2000', '1/2/2000')
,('9750', 'C04', '789', 3, 'V2', 'YYYYY', '1/2/2000', '12/31/9999')

;WITH basedata AS (
    SELECT key1 + '-' + key2 + '-' + key3 AS NK
    ,CASE WHEN AttribCode = 1 THEN Value ELSE NULL END AS COL1
    ,CASE WHEN AttribCode = 2 THEN Value ELSE NULL END AS COL2
    ,CASE WHEN AttribCode = 3 AND AttribSubCode = 'V1' THEN Value ELSE NULL END AS COL3
    ,CASE WHEN AttribCode = 3 AND AttribSubCode = 'V2' THEN Value ELSE NULL END AS COL4
    ,[Start]
    ,[End]
    FROM #src
)
,ChangeTimes AS (
    SELECT NK, [Start] AS Dt
    FROM basedata
    UNION 
    SELECT NK, [End] AS Dt
    FROM basedata
)
,Snapshots as (
    SELECT s.NK, s.Dt AS [Start], MIN(e.Dt) AS [End]
    FROM ChangeTimes AS s
    INNER JOIN ChangeTimes AS e
        ON e.NK = s.NK
        AND e.Dt > s.Dt
    GROUP BY s.NK, s.Dt
)
SELECT Snapshots.NK
    ,MAX(COL1) AS COL1
    ,MAX(COL2) AS COL2
    ,MAX(COL3) AS COL3
    ,MAX(COL4) AS COL4
    ,Snapshots.[Start]
    ,Snapshots.[End]
FROM Snapshots
INNER JOIN basedata
    ON basedata.NK = Snapshots.NK
    AND NOT (basedata.[End] <= Snapshots.[Start] OR basedata.[Start] >= Snapshots.[End])
GROUP BY Snapshots.NK
    ,Snapshots.[Start]
    ,Snapshots.[End]
...