Я немного новичок в разработке BI/хранилищах данных, но столкнулся с дилеммой старых медленно изменяющихся измерений. Я много читал о типах и теории, но нашел мало что с точки зрения того, что я рассматриваю, будет наиболее распространенными запросами SELECT для этих реализаций.Медленно меняя размеры - точная реализация SQL-запроса для получения правильных данных
Я сохраню свой пример простым. Скажем, у вас есть четыре причины продажи: Восток, Запад, Север и Юг. У вас есть группа продавцов, которые делают ежедневные продажи и (возможно, раз в год) переназначают новый регион.
Таким образом, вы будете иметь исходные данные, как следующее:
name; sales; revenue; date
John Smith; 10; 5400; 2015-02-17
У вас есть данные, как это каждый день.
Вы также можете иметь размерную таблицу, как следующее, первоначально:
name; region
John Smith; East
Nancy Ray; West
Claire Faust; North
Так директор по продажам хочет знать, ежемесячный доход от продаж на Восточном регионе за май 2015 Вы бы выполнить запрос:
SELECT region, month(date), sum(revenue)
from Fact_Table inner join Dim_Table on name = name
where region = East and date between ....
[group by region, month(date)]
Вы получаете идею. Давайте проигнорируем, что я использую естественные ключи вместо суррогатных целых ключей; Я бы явно использовал суррогатные ключи.
Теперь, очевидно, продавцы могут перемещать регионы в середине года. Или в середине месяца. Поэтому для запуска этого запроса необходимо создать тип SCD. Для меня лично тип 2 имеет наибольший смысл. Поэтому скажите, что вы это реализуете. Скажем, Джон Смит изменился из Восточного региона в Западном регионе 15 мая 2015 года Вы реализуете следующую таблицу:
name; region; start_date; end_date
John Smith; East; 2015-01-01; 2015-05-15
John Smith; West; 2015-5-15; 9999-12-31
Теперь директор по продажам задает тот же вопрос. Какова общая выручка от продаж на Восток в мае 2015 года? Или, кроме того, покажите мне итоги по регионам за месяц в течение всего года. Как бы вы структурировали запрос?
SELECT region, month(date), sum(reveneue)
from Fact_Table inner join Dim_Table
on name = name
and date between start_date and end_date
group by region, month(date)
Это даст правильные результаты? Я предполагаю, что это может быть ... мой вопрос может быть более похожим образом: теперь можно предположить, что у вас есть 1 миллион записей в таблице фактов ... будет ли это внутреннее соединение грубо неэффективным или существует более быстрый способ достичь этот результат?
Будет ли смысл писать SCD (например, область) непосредственно в «денормализованную» таблицу фактов --- а когда размер измерения изменится, возможно, обновите регионы задним числом за неделю или две?
Я не думаю, что ваш пример помогает, так как регион и продавец бы явно разные размеры. Структура, которую вы набросаете, очень затрудняет эффективное структурирование запроса для основного вопроса, который вы хотите задать, и это свидетельствует о том, что модель неверна. Как только вам понадобится сложный запрос, вы должны переоценить свою размерную структуру. –
Это довольно распространенный пример в большинстве литературы SCD. Мой пример «реальной жизни» почти такой же. Список имен, относящихся к различным региональным офисам (США и Европа против Азии) ... в некоторых приложениях нет прямой точки данных «региона» ... или даже «точки данных отдела» ... они кодируются отдельно , ВСЕ, у вас есть имя сотрудника из приложения. «Мастерская ссылка», направляющая такого сотрудника обратно в региональный офис или отдел (маркетинг и обслуживание клиентов) ... ВРЕМЯ. Я не понимаю, как вы говорите, что модель данных ошибочна. – user45867
По сути, одна ссылка, в моем примере, от дохода до Региона должна ВСЕГДА проходить через сотрудника сначала, как обстоятельство данных. Это может помочь понять, замените ли вы «регион» на «отдел». – user45867