Я немного новичок в разработке бизнес-аналитики / хранилищах данных, но столкнулся со старой дилеммой «Медленно меняющиеся размеры». Я много читал о типах и теории, но мало что нашел с точки зрения того, что я считаю наиболее распространенными запросами SELECT для этих реализаций.
Я сделаю свой пример простым. Допустим, у вас есть четыре причины продажи: восток, запад, север и юг. У вас есть группа продавцов, которые совершают ежедневные продажи и (возможно, раз в год) переназначают новый регион.
Таким образом, у вас будут необработанные данные, подобные следующим:
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 (например, регион) непосредственно в «денормализованную» таблицу фактов - и, когда размерность изменяется, возможно, задним числом обновлять регионы «записи фактов» за неделю или две?