0

Я немного новичок в разработке 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 (например, область) непосредственно в «денормализованную» таблицу фактов --- а когда размер измерения изменится, возможно, обновите регионы задним числом за неделю или две?

+0

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

+0

Это довольно распространенный пример в большинстве литературы SCD. Мой пример «реальной жизни» почти такой же. Список имен, относящихся к различным региональным офисам (США и Европа против Азии) ... в некоторых приложениях нет прямой точки данных «региона» ... или даже «точки данных отдела» ... они кодируются отдельно , ВСЕ, у вас есть имя сотрудника из приложения. «Мастерская ссылка», направляющая такого сотрудника обратно в региональный офис или отдел (маркетинг и обслуживание клиентов) ... ВРЕМЯ. Я не понимаю, как вы говорите, что модель данных ошибочна. – user45867

+0

По сути, одна ссылка, в моем примере, от дохода до Региона должна ВСЕГДА проходить через сотрудника сначала, как обстоятельство данных. Это может помочь понять, замените ли вы «регион» на «отдел». – user45867

ответ

1

Ваша концепция верна, если ваше деловое требование имеет иерархию Region-> Seller, как показано в вашем примере.

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

Используйте иерархию измерения даты, которая включает дату-> Месяц, и вы сможете избежать запроса диапазона.

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

Один миллион строк крошечные, вы не будете иметь проблем с производительностью на любых компетентных СУБД :)

+0

Да, это имеет смысл - я буду помнить эти советы. Что вы подразумеваете под иерархией измерения даты? Вы имеете в виду в таблице размеров с «эффективными» датами --- укажите месяц в таблице также во время ввода вставки/таблицы? – user45867

+0

Для дат, вы должны иметь размер, который что-то вроде: dim_date (ид, date_business_key, день, месяц, год, DAY_OF_WEEK, MONTH_NAME и т.д.) Вашего факта таблица должна содержать только внешний ключ ссылку на dim_date Таблица. Чтобы найти продажи в течение определенного месяца, запросите соединение вашего факта + dim_date, где год и месяц являются вашими требуемыми значениями. –

+0

Это имеет смысл, за исключением того, что если продавец был только на «Востоке» в течение полугода, с 1 июня по 15 июня .... тогда суммирование «общего» для восточного диапазона по-прежнему требует разделения данных на дату детализации , а не просто месяц. – user45867