Power BI: моделирование на экспертном уровне 9785970609064, 9781800205697

В этой книге описываются техники моделирования данных с помощью Power BI. Показано, как подключаться к данным в различны

177 21 56MB

Russian Pages 490 [491] Year 2022

Report DMCA / Copyright

DOWNLOAD FILE

Polecaj historie

Power BI: моделирование на экспертном уровне
 9785970609064, 9781800205697

Table of contents :
Содержание
От издательства
Предисловие
Об авторе
О технических редакторах
Введение
Для кого эта книга
Структура книги
Как извлечь максимум из книги
Загрузите сопроводительные файлы
Условные обозначения
Часть I. Моделирование данных в Power BI
Глава 1. Введение в моделирование данных в Power BI
Понятие слоев в Power BI Desktop
Слой подготовки данных (Power Query)
Слой модели данных
Вкладка Данные
Вкладка Модель данных
Слой визуализации данных
Вкладка Отчет
Поток данных в Power BI
Что означает моделирование данных в Power BI
Семантическая модель
Построение эффективной модели данных в Power BI
Схемы «звезда» (многомерное моделирование) и «снежинка»
Транзакционные модели против схемы «звезда»
Схема «снежинка»
Понятие денормализации
Варианты лицензирования в Power BI
Максимальный размер набора данных
Добавочная загрузка данных
Группы вычислений
Общие наборы данных
Потоки данных Power BI
Итеративный подход к моделированию данных
Сбор информации от руководства
Подготовка данных на основе бизнес-логики
Моделирование данных
Проверка логики
Демонстрация бизнес-логики в базовой визуализации
Думай как профессиональный разработчик моделей данных
Заключение
Глава 2. DAX и моделирование данных
Понимание виртуальных таблиц
Создание вычисляемой таблицы
Использование виртуальных таблиц в мерах, часть 1
Использование виртуальных таблиц в мерах, часть 2
Визуальное представление виртуальных таблиц
Создание вычисляемых таблиц в Power BI Desktop
Использование DAX Studio
Связи в виртуальных таблицах
Логика операций со временем и моделирование данных
Определение валидности дат в измерении
Вычисления на основе сравнения периодов
Создание измерения дат при помощи DAX
Пометка календаря как таблицы дат
Создание измерения времени при помощи DAX
Заключение
Часть II. Подготовка данных с помощью Power Query
Глава 3. Подготовка данных с помощью Power Query
Введение в язык формул M, используемый в Power Query
Power Query – регистрозависимый инструмент
Запросы
Выражения
Значения
Примитивные значения
Структурированные значения
Типы
Примитивные типы
Пользовательские типы
Введение в редактор Power Query
Панель Запросы
Таблицы
Настраиваемые функции
Параметры запросов
Константы
Группы
Панель Параметры запроса
Свойства
Область данных
Строка состояния
Расширенный редактор
Возможности Power Query в области моделирования данных
Качество столбца
Распределение столбцов
Профиль столбца
Параметры запросов
Настраиваемые функции
Рекурсивные функции
Заключение
Глава 4. Получение данных из различных источников
Получение данных из распространенных источников данных
Папка
CSV/Текст/TSV
Excel
Наборы данных Power BI
Потоки данных Power BI
SQL Server
SQL Server Analysis Services и Azure Analysis Services
SSAS многомерная/табличная
AAS
Канал OData
Сертификаты источников данных
Bronze
Silver
Gold/Platinum
Режимы подключения к данным
Импорт
Применение
Ограничения
DirectQuery
Применение
Ограничения
Подключение в режиме реального времени
Применение
Ограничения
Режимы хранения данных
Режимы хранения наборов данных
Заключение
Глава 5. Общие шаги по подготовке данных
Изменение типов данных
Разделение столбцов по разделителю
Объединение столбцов
Создание настраиваемого столбца
Создание столбца из примеров
Создание дубликата столбца
Фильтрация строк
Группирование данных
Добавление запросов
Объединение запросов
Создание дубликата запроса и ссылки на запрос
Замена значений
Извлечение чисел из текста
Работа с датой, временем и часовыми поясами
Заключение
Глава 6. Подготовка данных в Power Query для схемы «звезда»
Выявление измерений и фактов
Количество таблиц в источнике данных
Связи между существующими таблицами
Наименьшая требуемая гранулярность полей с датой и временем
Определение измерений и фактов
Выявление возможных измерений
Выявление возможных фактов
Создание таблиц измерений
Geography
Sales Order
Product
Currency
Customer
Sales Demographic
Date
Time
Создание измерений Date и Time – Power Query против DAX
Создание таблиц фактов
Заключение
Глава 7. Эффективные методики подготовки данных
Общие рекомендации по подготовке данных
При работе с источником OData используйте частичную загрузку данных
Не забывайте о регистрозависимости Power Query
Помните о свертывании запросов и его влиянии на обновление данных
Понятие свертывания запросов
Свертывание запросов и режимы хранения DirectQuery и Dual
Свертывание запросов и источники данных
Индикация свертывания запросов
Рекомендации по выполнению свертывания запросов
Используйте инструкцию SQL при подключении к SQL Server
Всегда, когда возможно, делегируйте подготовку данных источнику
Отключенный просмотр машинного запроса еще не означает, что свертывание запроса не выполняется
Организуйте запросы в редакторе Power Query
Преобразование типов
Преобразование типов и влияние на моделирование данных
Включение преобразования типов в шаги
Изменение типов данных за один шаг
Оптимизация размера запросов
Избавьтесь от лишних строк и столбцов
Выполните агрегирование (группировку)
Отмените загрузку запросов
Соглашение о наименованиях
Заключение
Часть III. Моделирование данных
Глава 8. Элементы моделирования данных
Моделирование данных в Power BI Desktop
Введение в таблицы
Свойства таблицы
Рекомендуемые таблицы
Вычисляемые таблицы
Введение в поля
Типы данных
Пользовательское форматирование
Столбцы
Вычисляемые столбцы
Группирование данных в столбцах и разделение их на ячейки
Свойства столбцов
Иерархии
Меры
Неявные меры
Явные меры
Текстовые меры
Использование связей
Первичные и внешние ключи
Управление составными ключами
Связь «один к одному»
Связь «один ко многим»
Связь «многие ко многим»
Распространение фильтров
Двунаправленные связи
Заключение
Глава 9. Схема «звезда» и распространенные техники при моделировании данных
Работа со связями типа «многие ко многим»
Связи «многие ко многим» с использованием таблицы-моста
Скрытие таблицы-моста
Повышенная бдительность при использовании двунаправленных связей
Работа с неактивными связями
Доступность таблицы по нескольким путям фильтра
Несколько прямых связей между двумя таблицами
Использование конфигурационных таблиц
Сегментирование
Динамическое условное форматирование с участием мер
Минусы создания вычисляемых столбцов
Организация модели данных
Скрытие второстепенных объектов
Скрытие неиспользуемых полей и таблиц
Скрытие ключевых полей
Скрытие неявных мер
Скрытие столбцов, использующихся в иерархиях, там, где это возможно
Создание таблиц мер
Рассуждения
Использование папок
Создание папки в нескольких таблицах в одно действие
Помещение меры в разные папки
Создание подпапок
Уменьшение размера модели путем отказа от автоматических таблиц с датами и временем
Заключение
Часть IV. Расширенное моделирование данных
Глава 10. Продвинутые техники моделирования данных
Использование агрегаций
Реализация агрегирования для источников, не поддерживающих DirectQuery
Реализация агрегации на уровне Date
Суммирование данных в таблице Internet Sales
Создание связей
Создание мер в агрегированной таблице
Создание контрольной меры в исходной таблице
Скрытие агрегированной таблицы
Реализация агрегации на уровне Year и Month
Использование инструмента управления агрегированием
Управление агрегированием в Power BI Desktop для источников, поддерживающих DirectQuery, и больших данных
Проверка агрегирования
Добавочное обновление
Настройка добавочного обновления в Power BI Desktop
Проверка добавочного обновления
Иерархии типа родитель-потомок
Определение глубины иерархии
Создание уровней иерархии
Ролевые измерения
Использование групп вычислений
Требования
Терминология
Группы вычислений и логика операций со временем
Тестирование групп вычислений
Проблема с форматированием строк
Функции DAX для групп вычислений
Заключение
Глава 11. Безопасность на уровне строк
Безопасность на уровне строк при моделировании данных
Чем безопасность на уровне строк не является
Терминология безопасности на уровне строк
Роли
Правила
Проверка ролей
Назначение участникам ролей в службе Power BI
Назначение участникам ролей в Power BI Report Server
Реализация безопасности на уровне строк
Распространенные подходы в организации безопасности на уровне строк
Статическая безопасность на уровне строк
Создание ролей и определение правил
Проверка ролей
Публикация отчета в службе Power BI
Назначение участникам ролей
Проверка ролей в службе Power BI
Динамическая безопасность на уровне строк
Каждый пользователь имеет доступ только к своим данным
Менеджер может видеть данные подчиненных
Получение учетных данных пользователей из стороннего источника
Заключение
Глава 12. Дополнительные опции и возможности моделирования данных
Медленно меняющиеся измерения
Медленно меняющиеся измерения типа 0 (SCD 0)
Медленно меняющиеся измерения типа 1 (SCD 1)
Медленно меняющиеся измерения типа 2 (SCD 2)
Безопасность на уровне объектов
Реализация безопасности на уровне объектов
Проверка ролей
Назначение участникам ролей в службе Power BI
Введение в потоки данных
Сценарии для использования потоков данных
Терминология потоков данных
Создание потока данных
Создание сущностей
Создание связанных сущностей из других потоков данных
Создание вычисляемых сущностей
Импорт и экспорт потоков данных
Экспорт потоков данных
Импорт потоков данных
Составные модели
Новая терминология
Построение цепочек
Длина цепочки
Заключение
Предметный указатель

Citation preview

Soheil Bakhshi

Expert Data Modeling with Power BI Get the best out of Power BI by building optimized data models for reporting and business needs

BIRMINGHAM — MUMBAI

Сохейл Бахши

Power BI: моделирование на экспертном уровне Построение оптимальных моделей данных с использованием Power BI

Москва, 2022

УДК 004.424 ББК 32.372 Б30

Бахши С. Б30 Power BI: моделирование на экспертном уровне / пер. с англ. А. Ю. Гинько. – М.: ДМК Пресс, 2022. – 490 с.: ил.  ISBN 978-5-97060-906-4 В этой книге описываются техники моделирования данных с помощью Power BI. Показано, как подключаться к данным в различных источниках, преобразовывать их с помощью Power Query и DAX, объединять посредством связей и строить модели данных с учетом разнообразных, даже самых изысканных, бизнес-требований. На примерах рассмотрена оптимизация сложных моделей данных без потери функционала. К концу книги читатель будет обладать всеми необходимыми знаниями для структурирования и обработки данных, поступающих из разных источников, и создания на их основании полноценных моделей, пригодных для построения отчетов. Книга предназначена для пользователей систем бизнес-аналитики, а также специалистов и разработчиков в области анализа данных, желающих повысить квалификацию и расширить навыки использования Power BI.

УДК  004.424 ББК  32.372

Copyright ©Packt Publishing 2021. First published in the English language under the title ‘Expert Data Modeling with Power BI - (9781800205697) Все права защищены. Любая часть этой книги не может быть воспроизведена в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.

ISBN 978-1-80020-569-7 (англ.) ISBN 978-5-97060-906-4 (рус.)

© Packt Publishing, 2021 © Перевод, оформление, издание, ДМК Пресс, 2022

Дизайн обложки разработан с использованием ресурса freepik.com

Я посвящаю эту книгу своей любимой жене Элике Мер (Elica Mehr) и нашей драгоценной дочери Авине (Avina). Без их бесконечной поддержки все это было бы невозможно. Также я обязан своим успехом родителям, которые всегда верили в меня и призывали следовать за своей мечтой

Содержание От издательства. ...................................................................................................13 Предисловие...........................................................................................................14 Об авторе. ................................................................................................................15 О технических редакторах..............................................................................16 Введение. .................................................................................................................17 Глава 1. Введение в моделирование данных в Power BI. ...............23 Понятие слоев в Power BI Desktop............................................................................24 Слой подготовки данных (Power Query)..............................................................25 Слой модели данных..............................................................................................25 Вкладка Данные..................................................................................................26 Вкладка Модель данных....................................................................................27 Слой визуализации данных..................................................................................28 Вкладка Отчет.....................................................................................................28 Поток данных в Power BI. ......................................................................................29 Что означает моделирование данных в Power BI...................................................30 Семантическая модель..........................................................................................31 Построение эффективной модели данных в Power BI......................................32 Схемы «звезда» (многомерное моделирование) и «снежинка»......................34 Транзакционные модели против схемы «звезда».........................................34 Схема «снежинка»..............................................................................................36 Понятие денормализации. ...............................................................................36 Варианты лицензирования в Power BI.....................................................................42 Максимальный размер набора данных...............................................................43 Добавочная загрузка данных................................................................................43 Группы вычислений...............................................................................................44 Общие наборы данных..........................................................................................45 Потоки данных Power BI........................................................................................45 Итеративный подход к моделированию данных...................................................45 Сбор информации от руководства.......................................................................46 Подготовка данных на основе бизнес-логики...................................................46 Моделирование данных. .......................................................................................47 Проверка логики.....................................................................................................47 Демонстрация бизнес-логики в базовой визуализации. .................................47 Думай как профессиональный разработчик моделей данных........................48 Заключение..................................................................................................................48

Глава 2. DAX и моделирование данных. ..................................................50 Понимание виртуальных таблиц. ............................................................................50

Содержание    7

Создание вычисляемой таблицы.........................................................................51 Использование виртуальных таблиц в мерах, часть 1......................................53 Использование виртуальных таблиц в мерах, часть 2......................................55 Визуальное представление виртуальных таблиц..............................................56 Создание вычисляемых таблиц в Power BI Desktop......................................56 Использование DAX Studio. ..............................................................................57 Связи в виртуальных таблицах. ...........................................................................58 Логика операций со временем и моделирование данных...................................68 Определение валидности дат в измерении........................................................68 Вычисления на основе сравнения периодов......................................................76 Создание измерения дат при помощи DAX. ......................................................84 Пометка календаря как таблицы дат. .............................................................86 Создание измерения времени при помощи DAX..............................................90 Заключение..................................................................................................................92

Глава 3. Подготовка данных с помощью Power Query......................95 Введение в язык формул M, используемый в Power Query...................................95 Power Query – регистрозависимый инструмент................................................96 Запросы....................................................................................................................97 Выражения...............................................................................................................97 Значения..................................................................................................................97 Примитивные значения....................................................................................97 Структурированные значения. ........................................................................98 Типы. ......................................................................................................................102 Примитивные типы.........................................................................................102 Пользовательские типы...................................................................................103 Введение в редактор Power Query. .........................................................................103 Панель Запросы. ...................................................................................................105 Таблицы.............................................................................................................105 Настраиваемые функции................................................................................105 Параметры запросов........................................................................................105 Константы..........................................................................................................105 Группы. ..............................................................................................................105 Панель Параметры запроса. ...............................................................................106 Свойства. ...........................................................................................................108 Область данных.....................................................................................................109 Строка состояния..................................................................................................112 Расширенный редактор.......................................................................................113 Возможности Power Query в области моделирования данных..........................114 Качество столбца..................................................................................................115 Распределение столбцов. ....................................................................................118 Профиль столбца. .................................................................................................121 Параметры запросов................................................................................................122 Настраиваемые функции.........................................................................................128 Рекурсивные функции.........................................................................................133 Заключение................................................................................................................135

8    Содержание

Глава 4. Получение данных из различных источников..................136 Получение данных из распространенных источников данных. .......................136 Папка......................................................................................................................137 CSV/Текст/TSV.......................................................................................................142 Excel........................................................................................................................148 Наборы данных Power BI.....................................................................................155 Потоки данных Power BI......................................................................................159 SQL Server...............................................................................................................160 SQL Server Analysis Services и Azure Analysis Services. ....................................162 SSAS многомерная/табличная........................................................................163 AAS......................................................................................................................165 Канал OData...........................................................................................................166 Сертификаты источников данных.........................................................................169 Bronze.....................................................................................................................169 Silver........................................................................................................................169 Gold/Platinum. .......................................................................................................170 Режимы подключения к данным............................................................................170 Импорт...................................................................................................................171 Применение......................................................................................................171 Ограничения.....................................................................................................171 DirectQuery. ...........................................................................................................171 Применение......................................................................................................172 Ограничения.....................................................................................................172 Подключение в режиме реального времени....................................................172 Применение......................................................................................................173 Ограничения.....................................................................................................173 Режимы хранения данных.......................................................................................173 Режимы хранения наборов данных.......................................................................175 Заключение................................................................................................................177

Глава 5. Общие шаги по подготовке данных.......................................178 Изменение типов данных........................................................................................179 Разделение столбцов по разделителю...................................................................186 Объединение столбцов. ...........................................................................................189 Создание настраиваемого столбца. .......................................................................190 Создание столбца из примеров..............................................................................193 Создание дубликата столбца...................................................................................195 Фильтрация строк.....................................................................................................197 Группирование данных............................................................................................201 Добавление запросов. ..............................................................................................203 Объединение запросов. ...........................................................................................206 Создание дубликата запроса и ссылки на запрос................................................208 Замена значений.......................................................................................................210 Извлечение чисел из текста. ...................................................................................212 Работа с датой, временем и часовыми поясами..................................................215 Заключение................................................................................................................218

Содержание    9

Глава 6. Подготовка данных в Power Query для схемы  «звезда»..................................................................................................................219 Выявление измерений и фактов. ...........................................................................219 Количество таблиц в источнике данных...........................................................220 Связи между существующими таблицами. ......................................................221 Наименьшая требуемая гранулярность полей с датой и временем.............222 Определение измерений и фактов....................................................................223 Выявление возможных измерений...............................................................224 Выявление возможных фактов......................................................................225 Создание таблиц измерений...................................................................................227 Geography...............................................................................................................228 Sales Order..............................................................................................................230 Product....................................................................................................................233 Currency..................................................................................................................236 Customer.................................................................................................................237 Sales Demographic.................................................................................................238 Date.........................................................................................................................241 Time. .......................................................................................................................245 Создание измерений Date и Time – Power Query против DAX.......................246 Создание таблиц фактов..........................................................................................247 Заключение................................................................................................................254

Глава 7. Эффективные методики подготовки данных....................256 Общие рекомендации по подготовке данных......................................................256 При работе с источником OData используйте частичную загрузку данных....................................................................................................................256 Не забывайте о регистрозависимости Power Query........................................259 Помните о свертывании запросов и его влиянии на обновление данных....................................................................................................................260 Понятие свертывания запросов.....................................................................260 Свертывание запросов и режимы хранения DirectQuery и Dual. .............261 Свертывание запросов и источники данных...............................................261 Индикация свертывания запросов................................................................261 Рекомендации по выполнению свертывания запросов.............................263 Организуйте запросы в редакторе Power Query..............................................267 Преобразование типов.............................................................................................268 Преобразование типов и влияние на моделирование данных. ....................269 Включение преобразования типов в шаги.......................................................275 Изменение типов данных за один шаг. ............................................................276 Оптимизация размера запросов............................................................................277 Избавьтесь от лишних строк и столбцов...........................................................277 Выполните агрегирование (группировку)........................................................278 Отмените загрузку запросов. .............................................................................279 Соглашение о наименованиях................................................................................279 Заключение................................................................................................................280

10    Содержание

Глава 8. Элементы моделирования данных.........................................282 Моделирование данных в Power BI Desktop. ........................................................282 Введение в таблицы..................................................................................................283 Свойства таблицы.................................................................................................283 Рекомендуемые таблицы. ...................................................................................286 Вычисляемые таблицы. .......................................................................................287 Введение в поля. .......................................................................................................292 Типы данных.........................................................................................................292 Пользовательское форматирование..................................................................294 Столбцы..................................................................................................................295 Вычисляемые столбцы. ...................................................................................295 Группирование данных в столбцах и разделение их на ячейки...............296 Свойства столбцов. ..........................................................................................300 Иерархии................................................................................................................304 Меры.......................................................................................................................305 Неявные меры...................................................................................................305 Явные меры.......................................................................................................308 Текстовые меры................................................................................................308 Использование связей..............................................................................................310 Первичные и внешние ключи.............................................................................311 Управление составными ключами.....................................................................311 Связь «один к одному». ...................................................................................316 Связь «один ко многим»..................................................................................316 Связь «многие ко многим». ............................................................................316 Распространение фильтров. ...............................................................................318 Двунаправленные связи......................................................................................320 Заключение................................................................................................................323

Глава 9. Схема «звезда» и распространенные техники при моделировании данных........................................................................324 Работа со связями типа «многие ко многим».......................................................324 Связи «многие ко многим» с использованием таблицы-моста. ...................327 Скрытие таблицы-моста......................................................................................333 Повышенная бдительность при использовании двунаправленных связей. ....334 Работа с неактивными связями..............................................................................337 Доступность таблицы по нескольким путям фильтра....................................337 Несколько прямых связей между двумя таблицами.......................................339 Использование конфигурационных таблиц.........................................................341 Сегментирование. ................................................................................................341 Динамическое условное форматирование с участием мер...........................342 Минусы создания вычисляемых столбцов............................................................348 Организация модели данных..................................................................................351 Скрытие второстепенных объектов. .................................................................351 Скрытие неиспользуемых полей и таблиц...................................................351 Скрытие ключевых полей...............................................................................353 Скрытие неявных мер. ....................................................................................354

Содержание    11

Скрытие столбцов, использующихся в иерархиях, там, где это возможно...........................................................................................................354 Создание таблиц мер...........................................................................................354 Рассуждения......................................................................................................356 Использование папок. .........................................................................................357 Создание папки в нескольких таблицах в одно действие..........................357 Помещение меры в разные папки.................................................................359 Создание подпапок..........................................................................................359 Уменьшение размера модели путем отказа от автоматических таблиц с датами и временем................................................................................................360 Заключение................................................................................................................362

Глава 10. Продвинутые техники моделирования данных............364 Использование агрегаций.......................................................................................364 Реализация агрегирования для источников, не поддерживающих DirectQuery. ...........................................................................................................365 Реализация агрегации на уровне Date..........................................................366 Использование инструмента управления агрегированием. .........................376 Управление агрегированием в Power BI Desktop для источников, поддерживающих DirectQuery, и больших данных.....................................378 Проверка агрегирования.................................................................................382 Добавочное обновление. .........................................................................................387 Настройка добавочного обновления в Power BI Desktop................................389 Проверка добавочного обновления...................................................................394 Иерархии типа родитель–потомок........................................................................396 Определение глубины иерархии........................................................................398 Создание уровней иерархии...............................................................................400 Ролевые измерения..................................................................................................403 Использование групп вычислений. .......................................................................406 Требования............................................................................................................407 Терминология. ......................................................................................................407 Группы вычислений и логика операций со временем....................................408 Тестирование групп вычислений.......................................................................414 Проблема с форматированием строк............................................................415 Функции DAX для групп вычислений................................................................417 Заключение................................................................................................................417

Глава 11. Безопасность на уровне строк................................................418 Безопасность на уровне строк при моделировании данных. ............................419 Чем безопасность на уровне строк не является...............................................419 Терминология безопасности на уровне строк. ................................................419 Роли....................................................................................................................420 Правила..............................................................................................................420 Проверка ролей.................................................................................................421 Назначение участникам ролей в службе Power BI...........................................423 Назначение участникам ролей в Power BI Report Server. ...............................423

12    Содержание Реализация безопасности на уровне строк...........................................................425 Распространенные подходы в организации безопасности на уровне строк. ..........................................................................................................................426 Статическая безопасность на уровне строк. ....................................................426 Создание ролей и определение правил........................................................427 Проверка ролей.................................................................................................428 Публикация отчета в службе Power BI...........................................................429 Назначение участникам ролей. .....................................................................430 Проверка ролей в службе Power BI.................................................................432 Динамическая безопасность на уровне строк. ................................................432 Каждый пользователь имеет доступ только к своим данным...................433 Менеджер может видеть данные подчиненных..........................................436 Получение учетных данных пользователей из стороннего источника..........................................................................................................442 Заключение................................................................................................................448

Глава 12. Дополнительные опции и возможности моделирования данных.................................................................................449 Медленно меняющиеся измерения.......................................................................449 Медленно меняющиеся измерения типа 0 (SCD 0).........................................451 Медленно меняющиеся измерения типа 1 (SCD 1).........................................451 Медленно меняющиеся измерения типа 2 (SCD 2).........................................451 Безопасность на уровне объектов..........................................................................455 Реализация безопасности на уровне объектов................................................455 Проверка ролей.....................................................................................................458 Назначение участникам ролей в службе Power BI...........................................460 Введение в потоки данных......................................................................................462 Сценарии для использования потоков данных...............................................462 Терминология потоков данных..........................................................................463 Создание потока данных.....................................................................................464 Создание сущностей........................................................................................467 Создание связанных сущностей из других потоков данных.....................471 Создание вычисляемых сущностей...............................................................474 Импорт и экспорт потоков данных. ..............................................................476 Составные модели. ...................................................................................................478 Новая терминология............................................................................................479 Построение цепочек........................................................................................479 Длина цепочки..................................................................................................479 Заключение................................................................................................................485

Предметный указатель. ..................................................................................486

От издательства Отзывы и пожелания Мы всегда рады отзывам наших читателей. Расскажите нам, что вы ду­маете об этой книге – что понравилось или, может быть, не понравилось. Отзывы важны для нас, чтобы выпускать книги, которые будут для вас максимально полезны. Вы можете написать отзыв на нашем сайте www.dmkpress.com, зайдя на страницу книги и  оставив комментарий в  разделе «Отзывы и  рецензии». Также можно послать письмо главному редактору по адресу dmkpress@gmail. com; при этом укажите название книги в теме письма. Если вы являетесь экспертом в какой-либо области и заинтересованы в написании новой книги, заполните форму на нашем сайте по адресу http:// dmkpress.com/authors/publish_book/ или напишите в  издательство по адресу [email protected].

Список опечаток Хотя мы приняли все возможные меры для того, чтобы обеспечить высокое качество наших текстов, ошибки все равно случаются. Если вы найдете ошибку в одной из наших книг, мы будем очень благодарны, если вы сообщите о ней главному редактору по адресу [email protected]. Сделав это, вы избавите других читателей от недопонимания и поможете нам улучшить последующие издания этой книги.

Нарушение авторских прав Пиратство в  интернете по-прежнему остается насущной проблемой. Издательства «ДМК Пресс» и Packt Publishing очень серьезно относятся к вопросам защиты авторских прав и лицензирования. Если вы столкнетесь в интернете с незаконной публикацией какой-либо из наших книг, пожалуйста, пришлите нам ссылку на интернет-ресурс, чтобы мы могли применить санкции. Ссылку на подозрительные материалы можно прислать по адресу элект­ ронной почты [email protected]. Мы высоко ценим любую помощь по защите наших авторов, благодаря которой мы можем предоставлять вам качественные материалы.

Предисловие Я очень рад, что именно Сохейл, становление которого в статусе MVP я наблюдал лично, взялся за написание книги на тему экспертного моделирования данных в Po­wer BI. Все студенты любят учиться на конкретных примерах, тогда как пробираться через дебри сухих документаций, извлекая важные сведения, им не очень-то интересно. Многие из них на этом этапе бросают обучение, так и не найдя реальных практических примеров из жизни, объясняющих стоящие перед ними задачи. В книге Сохейла освещен обширный диапазон тем от начального до экспертного уровня в Po­wer BI – инструменте, занимающем лидирующее место в иерархии продуктов для бизнес-аналитики. Po­wer BI обладает потрясающей гибкостью, и его очень легко использовать. Данная книга подойдет как для начинающих аналитиков, так и для тех, кто проектирует системы, предназначенные для обслуживания тысячей пользователей. Я бы без колебаний посоветовал книгу Сохейла любому, интересующемуся бизнес-аналитикой, вне зависимости от уровня. Он пишет о  Po­wer BI в  очень захватывающей манере, начиная повествование с элементарных строительных блоков, продолжая различными аспектами моделирования данных, включая описание схемы-звезды, управления двунаправленными связями, отношений «многие ко многим», вычисляемых таб­лиц, подготовки данных в Po­wer Query, и заканчивая сложными темами, охватывающими RLS, OLS и  составные модели данных. Кроме того, каждому студенту должен прийтись по душе сугубо практический подход, использованный в этой книге. Кристиан Уэйд (Christian Wade), руководитель группы проектов, Microsoft

Об авторе Сохейл Бахши (Soheil Bakhshi) является основателем сайта Data Vizioner и популярным практикующим консультантом по бизнес-аналитике. Сохейл обладает более чем 20-летним опытом работы с данными в области аналитики в Microsoft, включая работу с хранилищами данных и платформой Po­wer BI. Обладая сертификатами MSCE и MCSA, он также может похвастаться статусом Microsoft MVP. Своими знаниями и страстью Сохейл делится на своем сайте www.biinsight.com, а также на конференциях по Po­wer BI, проходящих по всему миру. В  стремлении к  простоте и  эффективности Сохейл Бахши принял участие в разработке нескольких полезных инструментов, включая Po­wer BI Exporter и Po­wer BI Documenter.

О технических редакторах Фелипе Вилела (Felipe Vilela) долгое время работал в  области системных разработок, после чего  более восьми лет назад переключился на бизнесаналитику и хранилища данных, в основном с использованием продуктов от MicroStrategy. Фелипе работал со многими компаниями из Бразилии и США, внедряя и настраивая продукты от MicroStrategy. Параллельно он преподавал бизнес-аналитику и хранение данных на собственных курсах, а также на официальных курсах компании MicroStrategy. Фелипе ведет блог по адресу www.vilelamstr.com, кроме того, он был одним из разработчиков мобильного приложения для конференций MicroStrategy World 2016 и 2017. Обладает более чем тридцатью сертификатами MicroStrategy, включая сертификат MCEP. Никита Барсуков (Nikita Barsukov) является опытным специалистом по обработке и  анализу данных, сосредоточенным на разработке комплексных аналитических решений. Никита родился и  вырос в  Украине, а  обучение проходил в  Финляндии и  Швеции. Свой профессиональный путь он начал в области разработки программного обеспечения, но вскоре понял, что его предназначение – это анализ данных и проектирование аналитических инструментов, позволяющих людям лучше разбираться в своих данных. В настоящее время Никита Барсуков работает в Microsoft, где в составе команды разработчиков трудится над аналитическими решениями для Po­wer Platform и Dynamics 365. Помимо работы Никита любит слушать подкасты и аудио­ книги, играть в настольные игры с друзьями, а иногда и сам с собой, бегать, пить крафтовое пиво и  читать книги. Он живет в  Копенгагене с  супругой и тремя детьми. Ана Мария (Ana Maria) является консультантом и тренером по бизнес-аналитике, а также лауреатом звания Microsoft Data Platform MVP, партнером Microsoft Po­wer BI и тренером LinkedIn Learning. Ана Мария находится в индустрии более 25 лет  – в 1990-х она разрабатывала решения для FoxPro, а  ныне работает, консультирует и  преподает в  области бизнес-аналитики. Она окончила факультет экономической информатики в Московском государственном университете управления, после чего получила степень магист­ ра в испанском Университете Алькала. Ана Мария специализируется на работе с инструментами бизнес-аналитики от Microsoft, а также c SQL Server, Excel, Azure Machine Learning, R и Po­wer BI. В качестве спикера, организатора или участника ее можно встретить на различных технических форумах и мероприятиях.

Введение Microsoft Po­wer BI является одним из наиболее популярных инструментов бизнес-аналитики на рынке программного обеспечения для настольных и облачных решений. Книга, которую вы держите в руках, может стать вашим проводником в мир моделирования данных в целом и применительно к Po­wer BI. Вы узнаете, как подключаться к данным в различных источниках, объединять их при помощи связей и строить полноценные модели данных. Из книги вы поймете, как использовать принципы моделирования данных и техники навигации для определения связей между сущностями и  создания модели данных, после чего мы перейдем к вопросам определения новых метрик и выполнения пользовательских вычислений с использованием особенностей модели. С течением глав сложность и эффективность моделей данных будет увеличиваться, и  вы научитесь использовать язык запросов DAX, а также новые техники моделирования. С помощью примеров мы покажем вам, как можно создавать новые или адаптировать существующие модели данных с  учетом разнообразных бизнес-требований. Наконец, вы освоите применение относительно свежих продвинутых возможностей для оптимизации и расширения своих моделей данных, что позволит вам решать широкий спектр задач. К концу книги вы будете обладать всеми необходимыми знаниями для структурирования и обработки данных, поступающих из разных источников, и создания на их основе полноценных моделей данных, пригодных для построения отчетов и  проведения полноценного анализа данных.

Для кого эта книга Книга предназначена для пользователей систем бизнес-аналитики, а  также специалистов и  разработчиков в  области анализа данных, желающих улучшить свое понимание техник моделирования данных с целью извлечь максимум возможного из Po­wer BI. Наличие базовых знаний в области Po­ wer BI и  понимание схемы данных «звезда» поможет вам в  освоении тем, освещающихся в этой книге.

Структура книги Глава 1 «Введение в моделирование данных в Po­wer BI». В данной главе мы кратко опишем функционал программного продукта Po­wer BI и расскажем о том, почему так важно уметь моделировать данные. Здесь мы также коснемся вопросов лицензирования Po­wer BI, напрямую влияющих на возможности моделирования данных. Кроме того, мы познакомимся с поняти-

18    Введение ем итеративного моделирования данных на примере реализации в Po­wer BI. Глава 2 «DAX и моделирование данных». В этой главе мы будем работать с языком запросов DAX не так много и глубоко, как в третьей и четвертой частях книги. Здесь мы сконцентрируемся на функционале языка, не самом очевидном для понимания, но очень важном с точки зрения моделирования данных. Начнем главу с краткого введения в DAX, после чего сразу перейдем к рассмотрению виртуальных таб­лиц и функций логики операций со временем, а также их применению в реальных сценариях. Глава 3 «Подготовка данных с помощью Po­wer Query». Здесь мы быстро пройдемся по базовому функционалу инструмента Po­wer Query и способам его применения на практике. Мы сделаем особый упор на параметры запросов и пользовательские функции, а также рассмотрим несколько примеров, помогающих понять, как эти техники позволяют повысить гибкость и надежность создаваемых моделей данных. Глава 4 «Получение данных из разных источников». В этой главе мы посмотрим на способы получения данных в Po­wer BI из наиболее распространенных источников. После этого затронем тему сертификации источников данных, которая позволяет выстроить определенные ожидания по поводу типа получаемых данных из источника. Это бывает очень полезно при оценке усилий на проектирование модели данных. Также мы рассмотрим разные режимы подключения к данным. Глава 5 «Общие шаги по подготовке данных». Здесь мы опишем на примерах наиболее распространенные действия, которые приходится выполнять при преобразовании данных, полученных из источника. В совокупности с  уже приобретенными знаниями в  более ранних главах описанные здесь шаги позволят вам в  будущем проектировать высокоэффективные модели данных. Изучив все описанные возможности, вы сможете по своему усмот­ рению выбирать способ реализации своей модели данных. Глава 6 «Подготовка данных в Po­wer Query для схемы “звезда”». В этой главе мы подробно поговорим о вариантах подготовки запросов для создания модели данных типа «звезда» с  рассмотрением реальных сценариев. Здесь мы будем активно использовать язык программирования M, встроенный в  Po­wer Query. С  учетом всех полученных ранее знаний по предварительной подготовке данных в Po­wer Query вам не должно составить труда разобраться с предложенными здесь примерами. Кроме того, вы научитесь создавать таб­ли­цы измерений и таб­ли­цы фактов, а также денормализовывать запросы при необходимости. Глава 7 «Эффективные методики подготовки данных». Здесь мы поговорим о типичных шаблонах при преобразовании данных, полученных из разных источников. Использование этих шаблонов позволит вам повысить эффективность создаваемых моделей данных, которые будет легче поддерживать. Прочитав эту главу, вы сможете избегать распространенных ошибок при проектировании моделей данных, что значительно облегчит вам жизнь в будущем. Глава 8 «Элементы моделирования данных». Эта глава будет посвящена составляющим компонентам моделей данных с точки зрения Po­wer BI, рас-

Введение    19

смотренным на примерах. Здесь мы будем активно использовать DAX, так что базовое понимание этого языка запросов будет крайне желательным. При рассмотрении примеров мы будем иметь дело с полноценной моделью данных типа «звезда». В этой главе мы также коснемся темы особых таб­лиц, использование которых может позволить обогатить модель данных за счет добавления в нее сложной бизнес-логики. Глава 9 «Схема “звезда” и распространенные техники при моделировании данных». Здесь мы поговорим о принятых нормах при проектировании моделей данных и постараемся сделать все, чтобы вы не допускали наиболее распространенных ошибок на этапе разработки модели. К примеру, проблему с типом данных в  ключевом столбце, используемом в  связи, бывает очень непросто обнаружить, тогда как предотвратить ее на этапе проектирования модели проще простого. Так что освоение распространенных техник позволит вам в конечном счете сэкономить драгоценные время и деньги. Глава 10 «Продвинутые техники моделирования данных». В  этой главе мы затронем тему особых приемов при моделировании данных, помогающих в решении поставленных бизнес-задач. Хороший специалист по моделям данных должен быть открыт всему новому. Вы в  своей практике легко можете столкнуться с описанными в этой главе или очень похожими на них бизнес-требованиями. И  здесь мы пытаемся донести до вас мысль о том, что вы всегда должны с готовностью принимать новые вызовы бизнеса и быть готовы применить все известные вам инновационные приемы для их решения. Глава 11 «Безопасность на уровне строк». Здесь мы посмотрим, как реа­ лизуется в модели данных Po­wer BI безопасность на уровне строк (row-level security – RLS). Работать с этой технологией бывает не так просто, и чтобы понять все ее тонкости, необходимо обладать глубокими знаниями в области моделирования данных и  распространения фильтров. В  данной главе мы поможем вам освоить эти концепции, что позволит вам в будущем проектировать эффективные и надежные модели. Глава 12 «Дополнительные опции и  возможности моделирования данных». В  заключительной главе книги мы подробно поговорим о таких дополнительных концепциях моделирования данных, как медленно меняющиеся измерения (Slowly Changing Dimensions – SCD), безопасность на уровне объектов (Object-Level Security (OLS), потоки данных (dataflows) и составные модели (composite model).

Как извлечь максимум из книги Вам необходимо загрузить и установить последнюю версию Po­wer BI Desktop. Все выражения проходили проверку в мартовском релизе Po­wer BI Desktop 2021 года и должны без проблем работать в более поздних версиях программы. В дополнение к Po­wer BI Desktop желательно будет установить программы DAX Studio и Tabular Editor.

20    Введение Программное/аппаратное обеспечение, используемое в книге Po­wer BI Desktop https://powerbi.microsoft.com/ en-us/downloads/

DAX Studio https://daxstudio.org/downloads/ Tabular Editor https://github.com/otykier/TabularEditor/releases/tag/2.16.0

Требования к операционной системе – Windows 8.1 / Windows Server 2012 R2 или выше; – .NET 4.6.2 или выше; – Internet Explorer 11 или выше; – память (RAM): минимум 2 Гб, рекомендовано 4 Гб и более; – видеосистема: минимум 1440×900 или 1600×900 (16:9). Более низкие разрешения экрана, такие как 1024×768 или 1280×800, не поддерживаются, поскольку в этом случае некоторые элементы управления (например, закрытие стартовой заставки) не могут быть корректно отражены; – параметры экрана: если вы настроили дисплей таким образом, чтобы масштаб текста, приложений и других элементов мог превышать значение 100 %, вы можете не увидеть некоторых диалоговых окон в Po­wer BI Desktop. Если у вас возникла такая проблема, откройте Параметры (Settings) ⇒ Система (System) ⇒ Дисплей (Display) и установите значение масштаба в 100 %; – процессор (CPU): 1 ГГц 64 бит (x64) или выше – Windows 7 или выше (рекомендуется Windows 10); – .NET Framework 4.7.1 или выше – Windows Server 2019; – Windows Server 2016; – Windows 7 или выше (рекомендуется Windows 10); – клиентские библиотеки Azure Analysis Services «AMO» версии 18.4.0.5 или выше

ПРИМЕЧАНИЕ  Начиная с  31 января 2021 года Po­wer BI Desktop прекратил поддержку Windows 7.

Для проверки примеров из некоторых глав вам понадобится наличие аккаунта службы Po­wer BI (Po­wer BI Service). Вы можете зарегистрироваться в службе и приобрести лицензию в качестве отдельного пользователя. Подробнее почитать можно по адресу https://docs.microsoft.com/en-us/Po­wer-bi/ fundamentals/service-self-service-signup-for-Po­wer-bi?WT.mc_id=5003466. Если вы используете цифровую версию книги, мы советуем вам вводить весь код вручную или скачивать его с сайта www.dmkpress.com на странице с описанием данной книги. Это позволит вам избежать возможных ошибок при копировании и вставке кода. При написании книги я предполагал, что вы знакомы с терминологией и базовыми принципами хранилищ данных и схемы «звезда». При этом в книге, когда это необходимо, приводятся термины с их кратким описанием.

Введение    21

Загрузите сопроводительные файлы Скачать файлы с дополнительной информацией для книг издательства «ДМК Пресс» можно на сайте www.dmkpress.com на странице с описанием соответствующей книги.

Условные обозначения На протяжении книги мы будем использовать следующие условные обозначения и шрифты. Код в тексте: так в тексте книги мы будем обозначать код. Пример: «Таб­ли­ца Customer­t able широкая и длинная». Термины: так будут написаны важные термины, названия папок и файлов, пути, пользовательский ввод и прочее. Блоки кода будут выделены следующим образом: Sequential Numbers = SELECTCOLUMNS( GENERATESERIES(1, 20, 1) , "ID" , [Value] )

Жирный шрифт: так будут выделяться новые термины, важные слова и текст, который вы видите на экране. Например, таким образом будут обозначаться пункты меню. Пример: «Нажмите на кнопку Создать таб­ли­цу (New table) на вкладке Моделирование (Modeling)». СОВЕТЫ ИЛИ ВАЖНЫЕ ПРИМЕЧАНИЯ  будут оформлены так.

Часть I Моделирование данных в Power BI

В этой вводной части мы обсудим общие принципы моделирования данных при помощи Po­wer BI. Мы будем предполагать, что вы уже знаете, что такое и  для чего используются Po­wer Query и  DAX, а  также понимаете базовые принципы схемы «звезда». В этой части вы узнаете, как применять виртуальные таб­ли­цы и функции логики операций со временем в DAX, кроме того, мы поговорим о принципах проектирования эффективных моделей данных на основе реальных сценариев. Содержание этой части:   глава 1 «Введение в моделирование данных в Po­wer BI»;   глава 2 «DAX и моделирование данных».

Глава

1

Введение в моделирование данных в Power BI Po­wer BI – это не просто инструмент для построения отчетов. Это полноценная платформа, предоставляющая богатейший спектр возможностей, – от подготовки исходных данных до их моделирования и визуализации. Кроме того, Po­wer BI представляет собой целую экосистему, позволяющую пользователям вносить собственный вклад в  аналитическую политику организации путем обмена наборами данных, отчетами и  дашбордами, а  также размещения в отчетах комментариев с мобильных устройств и их рассылки конкретным пользователям. Но все это возможно только при правильной настройке экосистемы Po­wer BI. Даже самый красивый в мире отчет ровным счетом ничего не будет стоить, если он показывает неправильные цифры или на его формирование уходит много времени. Пользователи никогда не будут работать с таким отчетом. Одним из важнейших факторов, влияющих на формирование эффективной экосистемы в Po­wer BI, является правильность лежащих в ее основе данных. В реальных проектах вам зачастую приходится получать данные из различных источников. Но получение данных и их внедрение в систему – это только полдела. Самое главное – объединить эти данные в  модель, позволяющую гарантировать целостность исходных сведений и их связь с бизнес-логикой. В этой главе мы познакомим вас с  таким понятием, как слои Po­wer BI, и вместе посмотрим, как данные перемещаются между слоями, что помогает при эффективном решении потенциальных проблем. После этого мы поговорим о таком важнейшем аспекте платформы Po­wer BI, как моделирование данных. Вы узнаете об ограничениях моделей данных и разных возможностях в зависимости от используемой лицензии. Наконец, мы познакомимся с понятием итеративного моделирования данных и его фазами. Основные темы, которые мы рассмотрим в этой главе:   понятие слоев в Po­wer BI Desktop;   что означает моделирование данных в Po­wer BI;   варианты лицензирования в Po­wer BI;   итеративный подход к моделированию данных.

24    Введение в моделирование данных в Power BI

Понятие слоев в Power BI Desktop Как мы уже сказали ранее, Po­wer BI – это не просто инструмент для формирования отчетов. Поскольку главным образом эта книга сконцентрирована на моделировании данных, нам бы не хотелось углубляться в детали Po­wer BI как инструмента, но некоторые основные концепции без внимания мы оставить не можем. Говоря о  моделировании данных в  Po­wer BI, мы фактически ссылаемся на программный продукт Po­wer BI Desktop. Вы можете рассматривать Po­wer BI Desktop как своеобразный аналог Visual Studio при разработке табличной модели (Tabular model) в  SQL Server Analysis Services (SSAS). Po­wer BI Desktop представляет собой бесплатный продукт от Microsoft, который можно загрузить по адресу https://powerbi.microsoft.com/en-us/ downloads/. В  этой книге мы будем подразумевать Po­wer BI Desktop, когда говорим Po­wer BI, если не указано иное. На рис. 1.1 показан типичный процесс построения отчета в Po­wer BI Desktop.

Получение данных

Преобразование данных

Загрузка данных

Моделирование данных

Визуализация данных

Рис. 1.1    Формирование нового отчета в Po­wer BI

Для осуществления описанного на рис. 1.1 процесса мы используем различные концептуальные слои (conceptual layer) в Po­wer BI. В Po­wer BI Desktop эти слои отражены так, как показано на рис. 1.2.

Отчет Данные

Power Query

Модель

Рис. 1.2    Слои Po­wer BI

Понятие слоев в Power BI Desktop  25

Загрузите пример Microsoft Contoso Sales для Power BI Desktop по адресу https://www.microsoft.com/en-us/download/confirmation.aspx?id=46801. Давайте детально разберем все представленные слои:  слой Power Query (подготовка данных);  слой модели данных;  слой визуализации данных.

Слой подготовки данных (Power Query) На этом слое мы получаем исходные данные из различных источников, преобразовываем, очищаем их и делаем доступными для других слоев. Это первый слой обработки данных, так что он играет важную роль в  вашем путешествии по миру Power BI. В  слое Power Query вы определяете, какие запросы будут служить для загрузки данных в вашу модель данных, а какие – выполнять исключительно служебные задачи по трансформации и очистке информации без загрузки в модель, как показано на рис. 1.3. Слой Power Query

Запросы без загрузки данных

Рис. 1.3  Power Query

Слой модели данных Этот слой включает в себя два представления: Данные (Data view) и Модель (Model view). В первом из них вы можете работать с исходными данными, во втором – с целыми моделями.

26    Введение в моделирование данных в Power BI

Вкладка Данные После окончания работы с данными в слое Po­wer Query происходит их загрузка в слой модели данных. На вкладке с данными мы видим исходные сведения в  том виде, в  котором они поступили в  модель после их преобразования и очистки. В зависимости от типа подключения эти исходные данные могут быть доступны или нет. Помимо просмотра данных в этой вкладке, мы также можем выполнять сопутствующие действия над ними, создавая объекты аналитики, такие как вычисляемые таб­ли­цы, вычисляемые столбцы и меры, и копируя данные из таб­лиц. ПРИМЕЧАНИЕ  Все объекты, создаваемые при помощи языка DAX, становятся частью­нашей модели данных.

На рис. 1.4 показан внешний вид представления Данные (Data) в Po­wer BI Desktop при установленном режиме хранения Импорт (Import).

Рис. 1.4    Представление данных, режим хранения Импорт

Понятие слоев в Power BI Desktop    27

Исходные данные на вкладке отображаются только в  случае выбора для соответствующих таб­лиц режима хранения Импорт (Import). При выборе режима хранения DirectQuery информация на вкладке отображаться не будет, что видно по рис. 1.5.

Рис. 1.5    Представление данных, режим хранения DirectQuery

Вкладка Модель данных Как ясно из названия, на этой вкладке мы сводим все наши исходные данные воедино. При этом мы не только видим, какие таб­ли­цы у нас есть и как именно они объединены между собой, но также можем создавать новые связи, форматировать поля и синонимы, показывать/скрывать элементы и т. д., что показано на рис. 1.6.

28    Введение в моделирование данных в Power BI

Рис. 1.6    Представление модели данных

Слой визуализации данных В этом слое мы возвращаем наши исходные данные к жизни, создавая наполненные смыслом визуализации. Доступ к этому слою осуществляется при помощи вкладки Отчет (Report), которая в Po­wer BI Desktop открывается по умолчанию.

Вкладка Отчет На вкладке Отчет (Report) мы можем строить визуализации разной степени сложности, помогающие бизнесу принимать решения на основании имеющихся данных, как показано на рис. 1.7. Еще здесь можно создавать аналитические вычисления с использованием языка DAX, такие как вычисляемые таб­ли­цы и столбцы, а также меры. Но это не значит, что эти вычисляемые объекты становятся частью слоя визуализации. Фактически они принадлежат слою модели данных. Загрузите файл Sales & Returns Sample v201912.pbix по адресу https://docs. microsoft.com/en-us/Po­wer-bi/create-reports/sample-datasets#sales--returns-sample-pbix-file.

Понятие слоев в Power BI Desktop    29

Рис. 1.7    Вкладка Отчет (Report)

Поток данных в Power BI Осознание того, как данные перемещаются внутри Po­wer BI, очень важно в плане понимания общей картины происходящего. К примеру, если вы видите, что с каким-то вычислением в отчете возникла проблема, вы должны быстро уметь разобраться в причинах и добраться до уровня, на котором эту проблему стоит решать. Допустим, если вы видите, что на графике выводятся неправильные цифры, и  знаете, что этот график использует для расчетов меры, базирующейся на вычисляемом столбце, то должны понимать, что не стоит искать этот столбец в слое Po­wer Query, поскольку объекты, создаваемые в модели данных, недоступны в Po­wer Query. Также вы никогда не станете искать меру в слое подготовки данных или пользовательскую функцию в слое модели данных. Мы будем подробно говорить о  пользовательских функциях в главе 3.

Data Visualisation

Data Model

Data Preparation (Power Query)

Рис. 1.8    Поток данных в Po­wer BI

30    Введение в моделирование данных в Power BI Для лучшего понимания общей картины давайте рассмотрим конкретный сценарий. В отчете Po­wer BI разработчик определил параметр запроса (query para­ meter), содержащий список заглавных букв E, O и  P. Есть запрос Product в Po­wer Query, содержащий описательную информацию о товарах. Столбец Product Name отфильтрован по списку параметров. Таким образом, когда разработчик выбирает букву E в параметре, запрос Product фильтрует результаты, оставляя только товары, начинающиеся с этой буквы. Вы создаете табличный визуальный элемент в отчете с выводом столбца Product Name. Можете ли вы добавить срез в отчет, показывающий значения параметра, чтобы пользователь имел возможность выбора и  фильтрации списка товаров? Это довольно распространенный вопрос, который время от времени задают разработчики Po­wer BI. Чтобы ответить на него, необходимо поразмышлять о слоях Po­wer BI. Давайте проведем небольшой анализ:   параметры запроса определяются в  слое подготовки данных (Po­wer Query);   фильтрация запроса также представляет собой шаг преобразования в  Po­wer Query, влияющий на результирующий набор запроса. Таким образом, когда мы импортируем данные в модель данных, результирующий набор запроса не изменится, пока мы не вернемся в Po­wer Query и  не поменяем значение параметра. Только в  этом случае итоговый набор данных изменится, и эти изменения будут загружены в модель данных в момент следующего импорта;   по умолчанию значения параметров запросов не загружаются в модель данных, если не установить флажок Включить загрузку (Enable Load). Включение этой опции позволит загрузить только выбранные значения параметра, а не весь список;   срез представляет собой элемент визуализации. Таким образом, мы говорим о слое визуализации данных, а значит, срез может пользоваться только значениями, доступными в модели данных. Следовательно, ответ нет. После загрузки результирующего набора запроса в модель только эти данные будут доступны в слое визуализации.

Что означает моделирование данных в Power BI Моделирование данных (data modeling) является одной из важнейших составляющих процесса разработки в  Po­wer BI. Цель моделирования данных в Po­wer BI существенно отличается от создания моделей в транзакционных системах. В последнем случае моделирование направлено на оптимизацию процесса фиксирования транзакций. В то же время хорошо спроектированная модель данных в Po­wer BI служит целям оптимизации выполнения за-

Что означает моделирование данных в Power BI    31

просов к данным и снижения размера результирующих наборов за счет агрегирования данных. Далеко не у всех есть доступ к готовому хранилищу данных, так что зачас­ тую нам приходится проектировать модель данных непосредственно в Po­ wer BI. При этом многим хочется просто взять все имеющиеся данные из источников и импортировать их в Po­wer BI. Но в этом случае формирование запросов к  модели будет занимать достаточно много времени, что в  условиях бизнеса неприемлемо. Таким образом, рекомендуется отказаться от соблазна загрузки всех доступных данных в модель, а решать проблемы по мере их поступления. В идеале ваша модель данных должна включать в себя все элементы, достаточные и необходимые для того, чтобы отвечать на требования бизнеса в максимально короткие сроки. Моделируя данные в Po­wer BI, вы должны делать это в строгом соответствии с имеющейся бизнес-логикой. Для этого вам может понадобиться объединить некоторые таб­ли­цы и до определенной степени агрегировать исходные данные. Но это бывает проб­ лематично, когда данные из различных источников, объединенные общей логикой, имеют разную гранулярность. В связи с этим перед загрузкой данных в Po­wer BI их бывает полезно преобразовать, и лучше других с  этой задачей может справиться Po­wer Query. После очистки данных мы получим удобную и лаконичную модель данных, работать с которой будет очень просто.

Семантическая модель Истоки Po­wer BI восходят к моделям Po­wer Pivot и SSAS (SQL Server Analysis Services) Tabular. Все они используют в своей основе движок xVelocity, представляющий собой обновленную версию движка VertiPaq. Он был разработан для обработки данных в оперативной памяти и содержит объекты семантической модели (semantic model), такие как таб­ли­цы, связи, иерархии и меры, хранящиеся в  памяти с  применением колоночной индексации (column store indexing). В этой связи вы могли бы ожидать значительного прироста производительности по сравнению с сильно сжатыми данными, не так ли? Но здесь есть свои нюансы. Ваши отчеты будут отличаться высокой скоростью и производительностью только при условии, что вы эффективно преобразовали данные для поддержки бизнес-логики. Путем загрузки данных в модель данных Po­wer BI вы строите семантическую модель, содержащую всю заложенную в информацию логику. Это унифицированная модель, предлагающая бизнес-контексты для ваших данных. К семантической модели можно осуществлять доступ из разных инструментов визуализации без необходимости повторно преобразовывать данные. Таким образом, после публикации отчета в службе Po­wer BI (Po­wer BI service) вы можете анализировать набор данных при помощи Excel или использовать сторонние инструменты, такие как Tableau, для подключения к набору данных Po­wer BI при наличии лицензии Premium и их визуализации.

32    Введение в моделирование данных в Power BI

Построение эффективной модели данных в Power BI Эффективная модель данных способна с  минимальными временными затратами отвечать на все интересующие вас бизнес-вопросы, а  также она проста для понимания и  поддержки. Давайте разберемся, что это значит. Ваша модель должна:   быстро реагировать и выполнять вычисления;   быть построена с учетом существующих бизнес-требований;   обладать минимально возможным уровнем сложности (быть легкой для понимания);   обеспечивать необходимую поддержку с минимальными затратами. Рассмотрим озвученные требования применительно к реальному сценарию. Вам поставили задачу создать отчет на базе трех следующих источников данных:   источник данных OData из 15 таб­лиц, каждая из которых содержит от 50 до 250 столбцов;   файл Excel с  20 зависящими друг от друга рабочими листами с  мно­ жеством формул;   хранилище данных в SQL Server, в котором вас интересуют пять измерений и две таб­ли­цы фактов:   из этих измерений одно содержит даты, второе – время. Гранулярность измерения времени исчисляется часами и минутами;   в таб­ли­цах фактов содержится от 50 до 200 млн строк. Гранулярность обеих таб­лиц фактов в отношении даты и времени исчисляется днями, часами и минутами;   ваша организация обладает лицензией Po­wer BI Pro. Уже по одному описанию сценария к представленным источникам данных могут возникать серьезные вопросы, и ниже я перечислил некоторые из них. OData. Это онлайновый источник, а значит, со скоростью загрузки данных из него могут возникать следующие проблемы:   таб­ли­цы в источнике слишком широкие, что может негативно сказываться на эффективности загрузки;   с имеющейся лицензией Po­wer BI Pro мы будем ограничены размером файла 1 Гб;   на следующие вопросы также придется найти ответы. Без этого итоговая модель данных может получиться объемнее, чем это необходимо, а скорость обращения к ней будет страдать, что приведет к недовольству конечных пользователей: – нужно ли нам импортировать все столбцы из 15 таб­лиц? – нужно ли нам загружать все данные или хватит их части? Иными словами, если в  базе хранятся исторические данные за последние десять лет, стоит ли импортировать их все, или для принятия бизнесрешений будет достаточно ограничиться одним-двумя последними годами?

Что означает моделирование данных в Power BI    33

Excel. Обычно рабочие книги Excel с большим количеством формул бывает достаточно тяжело поддерживать. Так что нам необходимо задаться следующими вопросами:   сколько из 20 рабочих листов на самом деле содержат данные, необходимые нам для анализа? Некоторые листы мы можем исключить из обработки;   как часто редактируются формулы на листах Excel? Это очень важно знать, поскольку изменение формул может привести к ошибкам при обработке данных в Po­wer Query. Таким образом, вам нужно быть готовыми к тому, что некоторые формулы придется продублировать в Po­ wer BI при необходимости. Хранилище данных в SQL Server. Всегда полезно иметь в качестве источника хранилище данных (data warehouse), поскольку обычно в нем с точки зрения аналитики все структурировано гораздо лучше. Но в нашем сценарии гранулярность обеих таб­лиц фактов установлена на уровне минуты. Это очень быстро может обернуться проблемами. Помните, что у нас в наличии есть только лицензия Po­wer BI Pro, а значит, мы ограничены размером файла 1 Гб. Таким образом, будет нелишним ответить на ряд бизнес-вопросов, преж­де чем принимать такую структуру:   нужен ли нам анализ всех показателей с  точностью до минуты или хватит уровня гранулярности день?   нужно ли нам загружать все имеющиеся данные в Po­wer BI или достаточно будет загрузить их часть? Теперь мы знаем, какого рода вопросы нужно задать. Но что, если нам действительно понадобится анализировать все имеющиеся исторические данные? В этом случае можно рассмотреть вариант использования составной модели с агрегатами. Помимо этого, есть еще один момент, который нужно учитывать. У  нас в хранилище уже присутствуют пять измерений. Эти измерения потенциально можно повторно использовать в нашей модели данных. Таким образом, разумно будет рассмотреть и другие источники данных на предмет поиска общностей в шаблонах данных. У вас могут возникнуть собственные вопросы к бизнесу по поводу будущей структуры данных. Главное – понять, что эти вопросы просто необходимо формулировать и задавать до начала проектирования модели, – в противном случае вы рискуете совершить очень большую ошибку. Существуют и другие аспекты, которые необходимо учитывать при управлении проектом, но они выходят за рамки данной книги. Итак, сейчас мы можем выделить три основных момента, которые стоит принимать во внимание при создании модели данных:   мы должны заранее задать бизнесу интересующие нас вопросы, чтобы впоследствии не возникло проблем и необходимости все переделывать;   нужно иметь в виду технологические ограничения и предпринять соответствующие меры;   необходимо хорошо разбираться в вопросах моделирования данных, чтобы осуществить полноценный поиск общих шаблонов данных во избежание перекрытий данных.

34    Введение в моделирование данных в Power BI Вы можете спросить: «И как мне все это сделать?», на что я отвечу, что первый шаг на этом пути вы уже сделали, взяв в руки данную книгу. Все вопросы, которые мы здесь обсуждали, и многие другие будут максимально подробно освещены в книге. Остальное зависит от вас и от того, как вы применяете на практике то, что изучили теоретически.

Схемы «звезда» (многомерное моделирование) и «снежинка» Сразу хочется отметить, что термины схема «звезда» (star schema) и  многомерное моделирование (dimensional modeling) относятся к одному и тому же. Применительно к Po­wer BI термин схема «звезда» употребляется чаще, так что в этой книге мы будем использовать в основном его. Здесь мы не ставим себе цель научить вас многомерному моделированию. Однако, несмотря на это, мы рассмотрим общие принципы моделирования данных с использованием техники схемы «звезда» и напомним вам базовые концепции этого подхода.

Транзакционные модели против схемы «звезда» В транзакционных системах (transactional system) главной целью является повышение производительности при создании новых записей и  редактировании/удалении существующих. Таким образом, при проектировании транзакционных систем очень важно провести процесс нормализации (normalization) данных с  целью снижения избыточности данных и  повышения производительности ввода информации. Обычно при нормализации мы разбиваем все таб­ли­цы на главные и подчиненные. В то же время перед системами бизнес-аналитики стоит совершенно иная задача. Здесь на первый план выходит эффективность запросов к данным, и именно с этим расчетом выполняется оптимизация модели данных. Давайте продолжим со сценарием. Скажем, у нас есть транзакционная система для международной сети розничных магазинов. Каждую секунду в  нашу систему записываются сотни транзакций с  разных магазинов по всему миру. Владелец компании хочет видеть общую сумму продаж за последние полгода. Звучит несложно. Достаточно применить простую функцию суммирования к продажам. Но не забывайте, что у нас каждую секунду добавляются сотни операций в базу. Даже если взять по минимуму – сто транзакций в секунду, – за день у нас наберется 8 640 000 транзакций, а за полгода – более полутора миллиарда строк. Очевидно, что простая операция суммирования вдруг перестала быть такой уж простой и быстрой. Следующий шаг сценария. От руководства компании поступает новый запрос. Теперь владельцу хочется посмотреть сумму продаж за полгода в разрезе стран и городов, чтобы определить лидирующие географические направления. Итак, нам необходимо добавить дополнительное условие к  нашему расчету суммы с объединением (join) с таблицей географии. Если у вас есть опыт работы с реляционными базами данных, вы должны понимать, что объединение таб­лиц – это достаточно дорогостоящая операция. Этот сценарий мы

Что означает моделирование данных в Power BI    35

можем развивать до бесконечности, но вы уже видите, как быстро у вас могут возникнуть проблемы с производительностью. В схеме «звезда» все нужные нам объединения таб­лиц уже произведены на основании бизнес-требований. Данные агрегированы и  загружены в денормализованные (denormalized) таб­ли­цы. В описанном выше сценарии руководство компании не интересуют продажи с  детализацией до секунды. Таким образом, мы можем агрегировать данные по дням, что позволит уменьшить объем представленной информации с полутора миллиардов до нескольких тысяч строк за интересующий нас период в  полгода. Вряд ли нужно объяснять, что на таком объеме данных операция суммирования будет выполняться куда быстрее. Идея схемы «звезда» состоит в разделении данных на числовые, хранящие­ ся в  таб­ли­цах фактов (fact table), и  описательные, которые размещаются в таб­ли­цах измерений (dimension table). Обычно на схеме таб­ли­цы фактов располагаются по центру – в окружении измерений, описывающих эти факты. При взгляде на такую схему невольно возникает ассоциация со звездой, что видно по рис. 1.9. Именно отсюда и произошло такое ее название. В этой книге мы в основном будем работать с базой Adventure Works DW – известным тестовым набором данных от Microsoft, если не указано иное. Это вымышленная компания по продаже велосипедов, ведущая торговлю как онлайн, так и через сеть розничных магазинов. На рис. 1.9 показана таб­ли­ца фактов Internet Sales в окружении измерений на схеме «звезда».

Рис. 1.9    Модель данных Adventure Works DW, таб­ли­ца фактов Internet Sales («звезда»)

36    Введение в моделирование данных в Power BI

Схема «снежинка» Схема «снежинка» (snowflake) образуется тогда, когда при окружении таб­лиц фактов измерениями не получается идеальная звезда. Зачастую бывает, что описательная информация хранится в нескольких таб­ли­цах – в виде уровней. В таких ситуациях традиционные измерения оказываются объединены связями с другими измерениями, в которых находится более детализированная информация. По сути, «снежинка» представляет собой процесс нормализации таб­лиц измерений. Бывают случаи, когда образование такой схемы неизбежно, но в общем случае при моделировании данных в Po­wer BI следует любыми способами избегать образования схемы «снежинка». На рис.  1.10 показана эта схема применительно к модели данных Adventure Works.

Снежинки

Рис. 1.10    Модель данных Adventure Works DW, таб­ли­ца фактов Internet Sales («снежинка»)

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

Что означает моделирование данных в Power BI    37

быть построена на основании разных источников данных, включая транзакционные системы и нетранзакционные, такие как файлы Excel и CSV. Таким образом, вам просто необходимо до определенной степени денормализовывать ваши модели. В зависимости от ваших требований вы можете сочетать нормализацию и денормализацию в нужной вам пропорции. Никакого золотого правила соотношения нормализованных и денормализованных данных в схеме просто не существует. Принято считать, что денормализовать данные необходимо до тех пор, пока измерения не будут полноценно их описывать. В предыдущем примере с моделью Adventure Works DW «снежинка», образуемая ветвью измерений Product Category и Product Subcategory, может быть легко денормализована в таб­ли­це Product. Давайте рассмотрим конкретный пример. Выполните следующие действия, чтобы денормализовать таб­ли­цы Product Category и Product Subcategory в измерении Product. ПРИМЕЧАНИЕ  Вы можете загрузить файл Adventure Works, Internet Sales.pbix по ад­ ресу https://github.com/PacktPublishing/Expert-Data-Modeling-with-Po­wer-BI/blob/ master/Adventure%20Works%20DW.pbix.

Откройте файл Adventure Works, Internet Sales.pbix и проделайте следующие шаги, как показано на рис. 1.11. 1. Нажмите на кнопку Преобразование данных (Transform data) на вкладке Главная (Home) в группе Запросы (Queries).

Рис. 1.11    Объединение таб­лиц Product и Product Subcategory

38    Введение в моделирование данных в Power BI 2. Выберите запрос Product1. 3. Нажмите на кнопку Объединить запросы (Merge Queries) на вкладке Главная (Home) в группе Объединить (Combine). 4. Выберите в выпадающем списке запрос Product Subcategory. 5. В таб­ли­це Product выделите столбец ProductSubcategoryKey. 6. В таб­ли­це Product Subcategory выделите столбец ProductSubcategoryKey. 7. Выберите тип Внешнее соединение слева (все из первой таб­ли­цы, совпадающие из второй) в  выпадающем списке Тип соединения (Join Kind). 8. Нажмите на кнопку OK. В результате на панели Примененные шаги (Applied steps) добавится новый шаг Объединенные запросы (Merged Queries). При этом в  новом столбце Product Subcategory, являющемся структурированным (Structured Column), во всех строках будет содержаться табличное значение Table. Больше о структурированных столбцах вы узнаете в главе 3.

Структурированный столбец

Щелкните здесь

Добавленный шаг

Рис. 1.12    Объединение таб­лиц Product и Product Subcategory

Теперь давайте посмотрим, как развернуть структурированный столбец в редакторе запросов. 1. Нажмите на кнопку Развернуть (Expand) в заголовке столбца Product Subcategory, как показано на рис. 1.13. 2. Установите флажок напротив поля ProductCategoryKey. 3. Установите также флажок для поля EnglishProductSubcategoryName и снимите все остальные флажки. 4. Снимите флажок Использовать исходное имя столбца как префикс (Use original column names as prefix). 5. Нажмите на кнопку OK. 1

Предварительно необходимо прописать путь к локальному файлу Excel в парамет­ рах Po­wer BI. – Прим. ред.

Что означает моделирование данных в Power BI    39

Рис. 1.13    Разворачивание структурированного столбца в редакторе запросов

В результате мы добавили столбцы EnglishProductSubcategoryName и  ProductCategoryKey из запроса Product Subcategory в запрос Product. Теперь нужно добавить столбец EnglishProductCategoryName из запроса Product Category. Для этого необходимо выполнить объединение запросов Product и Product Cate­ gory, как показано на рис. 1.14. 1. Снова нажмите на кнопку Объединить запросы (Merge Queries). 2. Выберите в выпадающем списке запрос Product Cate­gory. 3. В таб­ли­це Product выделите столбец ProductCategoryKey. 4. В таб­ли­це Product Cate­gory выделите столбец ProductCategoryKey.

Рис. 1.14    Объединение таб­лиц Product и Product Category

40    Введение в моделирование данных в Power BI 5. Выберите тип Внешнее соединение слева (все из первой таб­ли­цы, совпадающие из второй) в  выпадающем списке Тип соединения (Join Kind). 6. Нажмите на кнопку OK. В результате будет добавлен еще один шаг к запросу и еще один структурированный столбец с именем Product Cate­gory. Развернем его, как показано на рис. 1.15. 1. Разверните новый столбец при помощи соответствующей кнопки в заголовке. 2. Выделите в списке только поле EnglishProductCategoryName. 3. Снимите флажок Использовать исходное имя столбца как префикс (Use original column names as prefix). 4. Нажмите на кнопку OK.

Рис. 1.15    Разворачивание структурированного столбца

Осталось избавиться от столбца ProductCategoryKey, в котором больше нет необходимости. Для этого проделайте следующие действия, показанные на рис. 1.16. 1. Выделите столбец ProductCategoryKey. 2. Нажмите на кнопку Удалить столбцы (Remove Columns) в  группе Управление столбцами (Manage Columns) на вкладке Главная (Home).

Что означает моделирование данных в Power BI    41

Рис. 1.16    Удаление столбца в редакторе запросов

Итак, мы объединили лучи снежинки Product Cate­gory и Product Subca­tegory в запросе Product, тем самым денормализовав нашу снежинку. На заключительном шаге нам необходимо исключить запросы Product Cate­gory и Product Subcategory из загрузки. Для этого выполните следующие действия, показанные на рис. 1.17.

Рис. 1.17    Исключение запросов из загрузки в редакторе запросов

42    Введение в моделирование данных в Power BI 1. Щелкните правой кнопкой мыши по каждому из этих запросов. 2. Снимите флажок Включить загрузку (Enable load) в  контекстном меню. 3. Нажмите кнопку Продолжить (Continue) в  появившемся окне с предупреж­дением о возможной потере данных. Все, что нам осталось сделать, – это импортировать данные в модель путем нажатия на кнопку Закрыть и применить (Close & Apply), как показано на рис. 1.18.

Рис. 1.18    Импорт данных в модель

Итак, мы достигли поставленной цели – денормализовали таб­ли­цы Product Cate­gory и Product Subcategory, сведя их к столбцам EnglishProductCategoryName и EnglishProductSubcategoryName в измерении Product.

Варианты лицензирования в Power BI Вы наверняка подумали, как могут быть связаны варианты лицензирования в Po­wer BI с моделированием данных. Оказывается, они связаны напрямую, поскольку выбор лицензии непосредственно влияет на характеристики, от которых зависят особенности будущей модели данных. В то же время, какой бы тип лицензии вы ни использовали, Po­wer BI Desktop был и остается бесплатным продуктом. В  этом разделе мы рассмотрим некоторые аспекты, связывающие моделирование данных с выбранным типом лицензии. В табл. 1.1 приведена упрощенная версия сравнения лицензий на Po­wer BI с сайта Microsoft. Таб­ли­ца 1.1. Сравнение типов лицензирования Po­wer BI Лицензия Po­wer BI

Максимальный размер набора данных (Гб) 1 1 2

Free Professional Po­wer BI Report Server EM1/A1 3 EM2/A2 5 EM3/A3 10

Общие Потоки Добавочная Группы наборы данных загрузка вычислений данных Po­wer BI данных Нет Нет Нет Нет Да Нет Да Да Да Нет Н/А Н/А Да Да Да

Да Да Да

Да Да Да

Да Да Да

Варианты лицензирования в Power BI    43

Таблица 1.1 (окончание) Лицензия Po­wer BI P1/A4 P2/A5 P3/A6 P4 P5 PPU

Максимальный размер набора данных (Гб) 25 50 100 200 400 100

Добавочная загрузка данных Да Да Да Да Да Да

Группы вычислений Да Да Да Да Да Да

Общие наборы данных Да Да Да Да Да Да

Потоки данных Po­wer BI Да Да Да Да Да Да

Максимальный размер набора данных Как видно по табл. 1.1, при наличии лицензий Po­wer BI Free и Professional вы будете ограничены в отношении каждого опубликованного набора данных размером 1 Гб. А значит, этому аспекту придется уделить повышенное внимание при проектировании модели данных. Существует несколько способов удерживаться в рамках установленного ограничения:   импортировать в модель данных только нужные столбцы;   импортировать только часть данных. Опишите имеющиеся у вас ограничения руководству и узнайте, какие данные не являются критически важными для принятия решений. К примеру, мало какой отрасли бизнеса может понадобиться оперативный анализ данных за последние десять лет, так что вы с большой долей вероятности можете избавиться от лишних периодов;   используйте агрегации. В большинстве случаев данные в вашем хранилище будут находиться с максимальной степенью детализации (низкой гранулярностью). В  то же время при анализе обычно требуется повышать уровень гранулярности данных. Таким образом, вы можете агрегировать данные, повысив их гранулярность, после чего загружать в модель данных. К примеру, в источнике ваши данные могут храниться с  детализацией до минуты, а  руководству компании информация предоставляется с точностью до дня;   рассмотрите вариант отключения настройки автоматических даты и времени в Po­wer BI Desktop;   оптимизируйте типы данных. Подробнее о приведенных способах мы будем говорить в следующих главах книги.

Добавочная загрузка данных Одной из самых полезных возможностей в Po­wer BI является настройка добавочной (инкрементной) загрузки данных (incremental data load). Эта операция была унаследована Po­wer BI от SSAS для работы с объемными моделями данных. При правильной настройке этого параметра Po­wer BI не будет каж-

44    Введение в моделирование данных в Power BI дый раз импортировать данные с  нуля. Вместо этого будет производиться загрузка только измененных с момента последнего импорта данных. Такой подход позволяет значительно повысить эффективность обновления данных и минимизировать вычислительную нагрузку на сервер. Добавочная загрузка данных доступна в лицензиях Professional и Premium.

Группы вычислений Группы вычислений (calculation groups) аналогичны вычисляемым элементам (calculated member) в MDX. Изначально группы вычислений были представлены в табличных моделях SSAS 2019. Также они доступны в службах Azure Analysis Services и Po­wer BI. Зачастую разработчикам Po­wer BI приходится создавать некоторые базовые меры, после чего на их основе плодить большое количество мер, производящих идентичные вычисления с использованием логики операций со временем. В рассматриваемом примере у нас есть три следующие меры:   Product cost: SUM('Internet Sales'[TotalProductCost]);   Order quantity: SUM('Internet Sales'[OrderQuantity]);   Internet sales: SUM('Internet Sales'[SalesAmount]). В то же время бизнес требует создания следующих расчетов с использованием логики операций со временем для каждой из перечисленных мер:   накопительная сумма с начала года (Year to date);   накопительная сумма с начала квартала (Quarter to date);   накопительная сумма с начала месяца (Month to date);   накопительная сумма с начала года в предыдущем периоде (Last year to date);   предыдущая накопительная сумма с  начала квартала в  предыдущем периоде (Last quarter to date);   предыдущая накопительная сумма с начала месяца в предыдущем периоде (Last month to date);   сравнение годов (Year over year);   сравнение кварталов (Quarter over quarter);   сравнение месяцев (Month over month). Таким образом, нам пришлось бы создавать по девять вычислений на базе каждой из трех представленных мер. Несложно подсчитать, что в результате в нашей модели данных добавилось бы 9 × 3 = 27 мер. Как видите, количество мер в моделях способно увеличиваться очень быстро, так что не удивляйтесь, если вам кто-то скажет, что у него в модели сотни мер. Еще один сценарий связан с учетом нескольких валют. Без групп вычислений вам пришлось бы преобразовывать значения в текст, чтобы снабдить суммы нужным знаком валюты при помощи функции FORMAT() в DAX. А если совместить учет валют с вычислениями на основе логики операций со временем, проблемы умножатся. Группы вычислений способны легко и элегантно решать подобные вопросы. Вы научитесь пользоваться ими в главе 10.

Итеративный подход к моделированию данных    45

Общие наборы данных Как понятно из названия, общий набор данных (shared dataset) может совместно использоваться в  разных отчетах в  новых рабочих областях (пришедших на смену классическим) в рамках службы Po­wer BI. Таким образом, эта возможность доступна только для обладателей лицензионных планов Professional и  Premium. Использование данной технологии предоставляет больше гибкости при создании обобщенных наборов данных, отвечающих за несколько бизнес-сущностей, вместо содержания множества наборов, обладающих схожими особенностями.

Потоки данных Power BI Потоки данных (dataflows), также называемые Po­wer Query Online, представляют собой централизованный механизм подготовки данных в рамках службы Po­wer BI, плодами которого могут пользоваться все сотрудники компании. Подобно тому, как Po­wer Query используется в Po­wer BI Desktop для подготовки локальных данных, можно готовить, очищать и преобразовывать данные в потоках. И если запросы, создаваемые в Po­wer BI Desktop при помощи Po­wer Query и публикуемые в службе Po­wer BI, остаются изолированными в рамках набора данных, в потоках данных вы можете совместно использовать операции очистки и манипулирования данными. Создавать потоки данных Po­wer BI можно внутри рабочей области, так что этот функционал доступен только владельцам лицензий Professional и Premium. О потоках данных Po­wer BI мы будем подробнее говорить позже в этой книге.

Итеративный подход к моделированию данных Как и  в  случае с  разработкой любого программного обеспечения, моделирование данных представляет собой непрерывный процесс. Вы начинаете с переговоров с руководством, после чего реализуете определенную бизнеслогику в модели данных. Далее вы продолжаете разработку решения в Po­wer BI. Часто после построения визуальных элементов вы понимаете, что возможно добиться лучших результатов, если внести определенные изменения в  модель данных. Да и  реализованная в  модели бизнес-логика нередко не соответствует тому, что на самом деле нужно бизнесу. Мы часто слышим следующую фразу от руководства после осуществления первых нескольких итераций: Все выглядит прекрасно, но это не то, что нам нужно!

46    Введение в моделирование данных в Power BI Именно поэтому при разработке сценариев в Po­wer BI лучше всего применять пошаговый динамический подход. На рис. 1.19 показан один из способов реализации подобного подхода.

Демонстрация бизнес-логики в базовой визуализации

Проверка логики

Сбор информации от руководства

Подготовка данных на основе бизнес-логики Моделирование данных

Рис. 1.19    Итеративный подход к моделированию данных

Сбор информации от руководства Как и в случае с любым другим программным обеспечением, процесс разработки в Po­wer BI начинается со сбора информации от постановщиков задачи для общего понимания бизнес-требований. В реальных условиях этим может заниматься бизнес-аналитик, но многие пользователи Po­wer BI сами являются бизнес-аналитиками. Вне зависимости от того, занимаетесь ли вы бизнес-анализом или просто моделируете данные, вам необходимо знать, какие требования к  сценарию выдвигает бизнес изначально. Вы должны уметь задавать правильные вопросы и  намечать определенные решения. Кроме того, вам должны быть понятны очевидные риски, и вы должны обсуждать их с пользователями продукта. Только после сбора всей необходимой информации и обсуждения со сторонами возможных решений, рисков и технических ограничений вы можете переходить к следующему шагу.

Подготовка данных на основе бизнес-логики По завершении первого пункта в  вашем распоряжении будет достаточно ценной информации. Теперь вам необходимо собрать данные из различных источников и подготовить их для анализа, пользуясь сведениями, полученными на предыдущем шаге. К примеру, если бизнес-требования предполагают подключение к источнику OData и извлечение данных из нескольких

Итеративный подход к моделированию данных    47

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

Моделирование данных Если вы тщательно выполнили все предшествующие подготовительные действия, ваша модель данных должна получиться максимально компактной и эффективной. На этом этапе пришло время задуматься об аналитической стороне дела. Одновременно с  этим вы должны учитывать все собранные на предыдущих этапах нюансы относительно бизнес-требований, рисков и технических ограничений. К примеру, если руководство не готово мириться с более чем пятиминутными задержками в данных, вам стоит задуматься об использовании режима DirectQuery. Но этот режим сопряжен со своими ограничениями и рисками. Таким образом, вам необходимо выработать такие подходы к  разработке модели данных, которые будут максимально удовлетворять требованиям. Подробно о режиме хранения DirectQuery мы будем говорить в главе 4.

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

Демонстрация бизнес-логики в базовой визуализации При моделировании данных нам нет необходимости заботиться об их визуа­ лизации. Самый быстрый способ убедиться в  том, что бизнес-логика реа­ лизована правильно,  – получить подтверждение этого от самого бизнеса. А самый простой способ сделать это – продемонстрировать логику при помощи визуальных элементов – таб­лиц и матриц – с добавкой в виде срезов. Помните, что в данном случае речь идет именно о подтверждении корректности реализации бизнес-логики, а не о конечном продукте. Обычно процесс демонстрации данных приводит к  пониманию того, какая информация не была учтена, после чего начинается вторая итерация сбора данных от представителей бизнеса.

48    Введение в моделирование данных в Power BI Раз за разом повторно проходя по всем этим шагам, вы постепенно будете развивать навыки моделирования данных. В следующем разделе мы поговорим о том, как мыслят профессиональные разработчики моделей данных. ПРИМЕЧАНИЕ  В данной книге также реализован итерационный подход, так что мы будем то и дело возвращаться от главы к главе при рассмотрении сценариев.

Думай как профессиональный разработчик моделей данных Раньше, в  середине 90-х, я  работал с  транзакционными системами баз данных. В то время одним из ключевых навыков считалась нормализация модели данных как минимум до уровня третьей нормальной формы (third normal form). Иногда мы приводили данные к  нормальной форме Бойса– Кодда (Boyce-Codd normal form). Я вел множество проектов, разрабатывал модели данных, допускал ошибки и учился на них. Со временем я научился визуализировать модели данных вплоть до второй или даже третьей нормальной формы прямо в голове во время сбора информации от потенциальных клиентов. Все подходы к моделированию данных, с которыми мне приходилось работать и о которых я читал, основывались на реляционных моделях, независимо от их использования, будь то транзакционные модели, схема «звезда» или хранилища данных с архитектурой Inmon или Data Vault. Все они основываются на реляционных принципах моделирования. И моделирование данных в Po­wer BI ничем не отличается. Профессионалы могут без труда визуализировать будущие модели данных в голове уже на этапе первичного сбора информации у заказчика. Но этот навык приходит с опытом. Более того, с приобретением опыта вы также научитесь задавать правильные вопросы заказчикам, сравнивая новые сценариями с уже готовыми и заранее предвосхищая возможные ловушки. Правильные вопросы помогут вам избежать большого количества доработок в будущем. Помимо этого, вы можете сами подсказать заказчику новые идеи для реализации тех или иных возможностей. Зачастую требования к решению будут меняться в процессе работы над системой, и вам не стоит удивляться, когда это будет происходить.

Заключение В данной главе мы поговорили о различных слоях Po­wer BI и обсудили присущие каждому слою элементы и  требования. Таким образом, теперь при возникновении проблемы вы будете точно знать, куда смотреть. Также мы узнали, что при разработке модели данных мы фактически выстраиваем семантический слой в  Po­wer BI. Дополнительно мы рассмотрели различия между схемами «звезда» и «снежинка», которые позволяют очень эффектив-

Заключение    49

но моделировать данные. При обсуждении вопросов моделирования данных мы также узнали, какие ограничения могут накладываться теми или иными видами лицензии на Po­wer BI. Наконец, мы вкратце обсудили особенности итеративного подхода к  моделированию данных, который позволяет проектировать более жизнеспособные и надежные модели. В следующей главе мы рассмотрим язык запросов DAX применительно к моделированию данных. Мы обсудим такую неоднозначную тему, как виртуальные таб­ли­цы, и пройдемся по нескольким сценариям с применением логики операций со временем, которые помогут вам при моделировании данных.

Глава

2 DAX и моделирование данных

В предыдущей главе мы говорили о том, что в  Po­wer BI есть разные слои, включающие подготовку данных, их моделирование и визуализацию. В этой главе мы подробнее остановимся на языке DAX (Data Analysis eXpressions – выражения для анализа данных), напрямую относящемся к слою моделирования данных. Несмотря на неразрывную связь между языком запросов DAX и процессом моделирования данных, мы в этой книге не будем фокусировать свое внимание исключительно на DAX. Моделирование включает в себя большое множество концепций, а язык DAX разработчики используют для того, чтобы реализовать требования бизнес-логики в модели данных. Мы в этой книге будем предполагать, что вы в  какой-то степени знакомы с  DAX, так что на самых базовых концепциях языка останавливаться не будем. Вместо этого мы обратимся к более продвинутым техникам языка и обсудим их на примерах. Темы, которые мы будем обсуждать в этой главе:   понимание виртуальных таб­лиц;   связи в виртуальных таб­ли­цах;   логика операций со временем и моделирование данных.

Понимание виртуальных таблиц Концепция виртуальных таб­лиц (virtual table) в DAX является весьма недооцененной, но в то же время представляет одну из наиболее мощных техник языка. Говоря о виртуальных таб­ли­цах, мы имеем в виду таб­ли­цы, расположенные в  памяти, создаваемые при помощи функций или конструкторов DAX. Данные в виртуальных таб­ли­цах либо проистекают из модели данных, либо создаются при помощи конструкторов для конкретных нужд. Помните, что всякий раз, когда вы выполняете функцию DAX, возвращающую таб­ли­цу значений, вы тем самым создаете виртуальную таб­ли­цу. Здесь вы можете спросить, всякий ли раз при создании вычисляемой таб­ ли­цы (calculated table) посредством языка DAX вы создаете виртуальную таб­ ли­цу. Однозначного ответа нет, все зависит от обстоятельств. Если вы просто

Понимание виртуальных таблиц    51

используете набор функций DAX для генерации данных или их выборочной загрузки из других таб­лиц в  вычисляемую таб­ли­цу, ответом будет нет, вы не создаете при этом виртуальную таб­ли­цу. Но предположим, что вы сгенерировали или загрузили данные из других таб­лиц. При этом вы выполнили некоторые табличные операции над данными и загрузили полученные результаты в вычисляемую таб­ли­цу. Вероятнее всего, в этот момент вы создали виртуальную таб­ли­цу. Виртуальные таб­ли­цы, как понятно из названия, не хранятся в модели данных физически. Таким образом, мы не можем их увидеть, но они существуют в  памяти при выполнении соответствующих вычислений. Соответственно, доступ к ним можно получить только из этого конкретного вычисления, а не из какого-то другого или из другой части модели данных. Если у вас есть опыт написания запросов на языке SQL, вы можете рассматривать виртуальные таб­ли­цы как вложенные запросы в SQL. Все еще не до конца понятно? Давайте рассмотрим конкретные примеры.

Создание вычисляемой таблицы Давайте создадим вычисляемую таб­ли­цу с именем Sequential Numbers и одним столбцом ID. В этом столбце будут находиться последовательные значения от 1 и 20 с увеличением на единицу. 1. Откройте Po­wer BI Desktop. 2. Нажмите на кнопку Создать таб­ли­цу (New table) на вкладке Моделирование (Modeling), как показано на рис. 2.1.

Рис. 2.1    Создание вычисляемой таб­ли­цы в Po­wer BI

3. Введите в  строку формул следующее выражение DAX и  нажмите на клавишу Enter1: Sequential Numbers = GENERATESERIES(1; 20; 1)

В результате будет создана вычисляемая таб­ли­ца Sequential Numbers, как показано на рис. 2.2, но столбец в ней будет называться Value, а не ID. 1

Здесь и далее мы будем использовать в качестве разделителей аргументов точку с запятой, как принято в русской локализации операционной системы. Эту установку можно сделать в настройках программы. – Прим. перев.

52    DAX и моделирование данных

Рис. 2.2    Использование функции GENERATESERIES() для создания вычисляемой таб­ли­цы

Функция GENERATESERIES() генерирует значения за нас. В результате мы получили таб­ли­цу, в которой осталось переименовать столбец Value в ID. 4. Замените предыдущее выражение следующим и нажмите на клавишу Enter: Sequential Numbers = SELECTCOLUMNS( GENERATESERIES(1; 20; 1) ; "ID" ; [Value] )

На рис. 2.3 показан результат приведенного вычисления.

Рис. 2.3    Вычисляемая таб­ли­ца и виртуальная таб­ли­ца

Что мы сделали, так это сначала создали виртуальную таб­ли­цу со столбцом Value, после чего переименовали его в ID и заполнили значениями. В данном сценарии мы рассмотрели использование виртуальных таб­лиц в вычисляемых таб­ли­цах. В следующем примере мы узнаем, как использовать виртуальные таб­ли­цы в мерах.

Понимание виртуальных таблиц    53

Давайте сделаем еще один шаг и рассмотрим более сложный сценарий.

Использование виртуальных таблиц в мерах, часть 1 В примере из файла Adventure Works, Internet Sales.pbix создайте меру в таб­ли­ це Internet Sales для расчета количества товаров с розничной ценой, равной или превышающей $1000. Назовите меру Orders with List Price Bigger than or Equal to $1,000. ПРИМЕЧАНИЕ  Всегда создавайте новые меры путем нажатия правой кнопкой мыши на нужной таб­ли­це на панели Поля (Fields) и выбора пункта меню Создать меру (New measure). Так вы сможете быть уверены в  том, что мера будет создана в нужной вам таб­ли­це. Создавая меру при помощи соответствующей кнопки на вкладке Главная (Home), вы будете автоматически размещать ее в последней выбранной таб­ли­це. Если ни одна таб­ли­ца не выделена, мера будет создана в первой таб­ли­це в модели данных, а это не лучший вариант.

1. Щелкните правой кнопкой мыши по таб­ли­це Internet Sales. 2. Выберите пункт Создать меру (New measure). 3. Введите следующий код на языке DAX, как показано на рис. 2.4, и нажмите на клавишу Enter: Orders with List Price Bigger than or Equal to $1,000 = CALCULATE( SUM('Internet Sales'[OrderQuantity]) ; FILTER('Product' // Начало виртуальной таб­ли­цы ; 'Product'[List Price]>=1000 ) // Конец виртуальной таб­ли­цы )

На рис. 2.4 показано предшествующее выражение в Po­wer BI Desktop. Давайте проанализируем предыдущее вычисление:   мы создали виртуальную таб­ли­цу при помощи функции FILTER() на основании таб­ли­цы Product, оставив в ней только товары со значением атрибута List Price, большим или равным $1000. В созданной в памяти виртуальной таб­ли­це доступны все столбцы из таб­ли­цы Product. При этом обращаться к этой таб­ли­це вы можете только внутри меры Orders with List Price Bigger than or Equal to $1,000 и больше ниоткуда;   функция SUM() выполняет суммирование по столбцу OrderQuantity в таб­ли­це Internet Sales. Чтобы использовать созданную меру, поместите визуальный табличный элемент на страницу отчета и выберите поле Product Name в таб­ли­це Pro­duct и меру Orders with List Price Bigger than or Equal to $1,000. Результат вывода показан на рис. 2.5.

54    DAX и моделирование данных

Рис. 2.4    Поиск заказов по товарам с ценой, большей или равной $1000

Рис. 2.5    Заказы по товарам с ценой, большей или равной $1000

Давайте сделаем еще один шаг и реализуем более сложный сценарий.

Понимание виртуальных таблиц    55

Использование виртуальных таблиц в мерах, часть 2 В файле Adventure Works, Internet Sales.pbix создайте меру в таб­ли­це Internet Sales для определения покупателей, которые приобрели более четырех товаров с розничной ценой, равной или превышающей $1000. Назовите меру Order Qty for Customers Buying More than 4 Products with List Price Bigger Than $1,000. Для этого сценария нам необходимо создать виртуальную таб­ли­цу с покупателями, совершившими более четырех покупок товаров, цена которых превышает $1000. Это позволит сделать следующий код: Order Qty for Customers Buying More than 4 Product with List Price Bigger Than $1,000 = SUMX( FILTER( VALUES(Customer[CustomerKey]) // Виртуальная таб­ли­ца ; [Orders with List Price Bigger than or Equal $1,000] > 4 ) ; [Orders with List Price Bigger than or Equal $1,000] )

Анализ этого вычисления поможет вам лучше понять концепцию применения виртуальных таб­лиц:   здесь виртуальная таб­ли­ца содержит один столбец CustomerKey. Помните, что этот столбец будет доступен только внутри вычисления;   затем мы используем функцию FILTER(), чтобы оставить в  таб­ли­це, созданной при помощи функции VALUES(), только ключи покупателей, которые приобретали товары с ценой выше $1000 больше четырех раз;   в заключение мы суммируем количество товаров по таб­ли­це, созданной в результате применения функции FILTER(). Теперь можно вынести в отчет табличный визуальный элемент, выбрать поля First Name и Last Name из таб­ли­цы Customer, а также созданную нами меру. На рис. 2.6 показаны покупатели, приобретавшие товары дороже $1000 более четырех раз. Как мы уже упоминали ранее, вы можете использовать любые функции DAX, возвращающие табличные значения, для создания виртуальных таб­лиц. На рис. 2.7 перечислены наиболее популярные из них. Виртуальные таб­ли­цы создаются только в памяти. Более того, они недоступны для просмотра на вкладке Модель (Model) в Po­wer BI Desktop. Именно поэтому они не так просты для понимания. К счастью, существуют способы для просмотра результатов создания виртуальных таб­лиц, о которых мы поговорим далее.

56    DAX и моделирование данных

Рис. 2.6    Клиенты, купившие товары дороже $1000 более четырех раз

Рис. 2.7    Распространенные функции для создания виртуальных таб­лиц

Визуальное представление виртуальных таблиц В этом разделе речь пойдет о  том, как вы можете просматривать данные в  виртуальных таб­ли­цах. Всегда удобно иметь визуальное представление о данных, а не просто воспроизводить их в сознании. Здесь мы рассмотрим два варианта просмотра содержимого виртуальных таб­лиц.

Создание вычисляемых таблиц в Power BI Desktop Вы можете создавать вычисляемые таб­ли­цы в Po­wer BI Desktop при помощи функций, которые используются для создания виртуальных таб­лиц. Рассмотрим первую часть второго сценария, обсуждаемого в этой главе, и увидим, как это работает. 1. В Po­wer BI Desktop нажмите на кнопку Создать таб­ли­цу (New Table) на вкладке Моделирование (Modeling). 2. Скопируйте и вставьте следующий код и нажмите на клавишу Enter: Test Virtual Table = FILTER('Product' // Начало виртуальной таб­ли­цы ; 'Product'[List Price]>=1000 ) // Конец виртуальной таб­ли­цы

3. Перейдите на вкладку Данные (Data) на левой панели.

Понимание виртуальных таблиц    57

4. Выделите таб­ли­цу Test Virtual Table на панели Поля (Fields) для просмотра содержимого таб­ли­цы. Как видите, вам будут доступны все столбцы из таб­ли­цы Product. При этом в  данную таб­ли­цу будет загружено всего 126 строк, что видно по рис.  2.8. Именно столько товаров в столбце List Price имеют значение, равное или превосходящее 1000. В исходной таб­ли­це Product содержится 397 строк.

Рис. 2.8    Визуальное отображение данных виртуальной таб­ли­цы в Po­wer BI Desktop

Использование DAX Studio DAX Studio – это один из наиболее популярных инструментов для бизнесаналитики, который можно загрузить бесплатно. Вы можете найти его на официальном сайте по адресу https://daxstudio.org и использовать в том числе для просмотра содержимого виртуальных таб­лиц. Прежде чем подключаться к файлу с расширением *.pbix из DAX Studio, необходимо открыть его в Po­wer BI. Запустите DAX Studio и выполните следующие действия. 1. Установите переключатель в положение PBI/SSTD Model. 2. Выберите нужный экземпляр Po­wer BI Desktop. 3. Введите ключевое слово EVALUATE, после чего введите следующий код вычисления виртуальной таб­ли­цы, как показано на рис. 2.9: FILTER('Product' // Начало виртуальной таб­ли­цы ; 'Product'[List Price]>=1000 ) // Конец виртуальной таб­ли­цы

4. Нажмите на клавишу F5 или кнопку Run, чтобы выполнить запрос.

58    DAX и моделирование данных

Рис. 2.9    Запуск выражений виртуальных таб­лиц в DAX Studio ПРИМЕЧАНИЕ  В DAX Studio вы можете выполнять запросы на языке DAX, предваряя их ключевым словом EVALUATE.

Связи в виртуальных таблицах Когда мы говорим о таб­ли­цах в реляционных системах, мы подразумеваем как сами таб­ли­цы, так и связи (relationship) между ними. Мы уже научились создавать виртуальные таб­ли­цы, теперь пришло время подумать о  связях между ними и другими виртуальными или физическими таб­ли­ца­ми, располагающимися в модели данных. Как мы уже упоминали ранее, виртуальную таб­ли­цу можно создать путем генерирования, конструирования или наследования из существующих таб­лиц в  модели данных. В  некоторых случаях мы можем создавать более одной виртуальной таб­ли­цы для произведения необходимых расчетов. Применительно к виртуальным таблицам можно говорить о двух видах связей:   если виртуальная таб­ли­ца создана на основании таб­ли­цы, физически существующей в модели данных, между этими таб­ли­ца­ми есть связь, также называемая происхождением (lineage);   при создании более одной виртуальной таб­ли­цы в рамках вычисления мы создаем связи между этими таб­ли­ца­ми программным путем. В обоих случаях речь идет не о  физических связях (physical relationship) в модели данных. Эти связи создаются «на лету» при выполнении вычисления. Поэтому виртуальные связи (virtual relationship) бывает не так просто освоить. Давайте попробуем сделать это на примерах. Руководство потребовало рассчитать среднюю нормативную себестоимость товаров по категориям (Product Category), подкатегориям (Product Subcategory) и самим товарам (Product).

Понимание виртуальных таблиц    59

Чтобы следовать сценарию, откройте файл Chapter 2, Virtual Tables.pbix. Взгляните на модель данных – она довольно простая и состоит всего из двух таб­лиц: Product и Internet Sales. При этом в таб­ли­це Internet Sales вы увидите столбец ProductStandardCost, который мы будем использовать при создании мер. На рис. 2.10 представлен внешний вид модели данных.

Рис. 2.10    Таб­ли­цы Product и Internet Sales

Теперь давайте создадим меру для расчета средней нормативной себестои­ мости товаров со следующим кодом: Avg. Product Standard Costs = AVERAGE('Internet Sales'[ProductStandardCost])

Проверим созданную меру путем выполнения следующих действий. 1. Создайте на листе отчета визуальный элемент с матрицей. 2. Перенесите поля Product Category, Product Subcategory и Product из таб­ ли­цы Product в область Строки (Rows). 3. Переместите созданную меру Avg. Product Standard Costs в область Значения (Values). На рис. 2.11 наглядно проиллюстрированы эти действия. Выглядит просто. Но давайте внимательнее присмотримся к  данным и убедимся, что наши расчеты верны. Перейдите на вкладку Данные (Data) на левой панели Po­wer BI Desktop и выберите таб­ли­цу Internet Sales. На рис. 2.12 видно, что в поле ProductStandardCost присутствует значение для каждой транзакции, отражающее общие затраты на товар с момента его поставки и до продажи с полки. Но себестоимость – величина переменная, и она может меняться с течением времени. И нам важно знать, как с этим обстоит дело в нашем сценарии. Если в нашем случае это так, то наши предыдущие расчеты верны.

60    DAX и моделирование данных

Рис. 2.11    Визуализация меры Avg. Product Standard Costs по полям Product Category, Product Subcategory и Product

Рис. 2.12    Для каждой транзакции прописано значение в поле ProductStandardCost

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

Понимание виртуальных таблиц    61

Также из этого ответа нам стало понятно, что наши предыдущие расчеты были неверны. И, чтобы исправить ошибку, нам нужно перенести столбец ProductStandardCost в таб­ли­цу Product. Сделав это, мы закрепим за конкретными товарами их нормативную себестоимость. Таким образом моделирование данных способно снизить сложность выражений на языке DAX. Для демонстрации работы с  виртуальными таб­ли­ца­ми мы создадим еще одну меру и проанализируем результаты. Но перед этим подытожим все, что знаем о требованиях компании. Итак, нам необходимо рассчитать среднюю нормативную себестоимость товаров по категориям, подкатегориям и товарам. Для каждого товара есть своя текущая нормативная себестоимость. Таким образом, мы можем создать виртуальную таб­ли­цу со столбцами ProductKey и ProductStandardCost. Обратите внимание, что изначально эти столбцы находятся в двух разных таб­ли­цах в модели данных. Но мы знаем, что между этими таб­ли­ца­ми сущест­вует физическая связь, а значит, мы без труда можем объединить данные из разных столбцов в одну виртуальную таб­ли­цу. Приведенная ниже мера поможет нам реализовать поставленную задачу: Avg. Product Standard Costs Correct = AVERAGEX( SUMMARISE ( 'Internet Sales' ; 'Product'[ProductKey] ; 'Internet Sales'[ProductStandardCost] ) ; 'Internet Sales'[ProductStandardCost] )

Теперь можно добавить созданную меру в нашу матрицу, чтобы сравнить полученные значения. Как видите, разница получилась ощутимая, и она еще больше заметна на итоговых значениях. Давайте посмотрим, как работает приведенная выше мера. AVERAGEX() представляет собой итерационную функцию (iterator function), проходящую по всем строкам переданной таб­ли­цы и  вычисляющую выражение для каждой из них. Именно здесь появляется виртуальная таб­ли­ца, созданная при помощи функции SUMMARIZE() и переданная на вход итератору. На рис. 2.13 наглядно показано, что наша виртуальная таб­ли­ца создана на основе таб­ли­цы Internet Sales. При этом мы группируем данные по столбцу ProductKey из таб­ли­цы Product и агрегируем значения по полю ProductStandardCost. Как это возможно? Вот как это работает. Функция AVERAGEX() проходит по строкам таб­ли­цы Internet Sales, извлекая значения из поля ProductStandardCost, сгруппированные по столбцу ProductKey из таб­ли­цы Product на основании существующей связи между таб­ли­ца­ми. Если выполнить часть запроса с функцией SUMMARIZE() в DAX Studio, мы получим 158 строк, что видно по рис. 2.14, в то время как в таб­ли­це Internet Sales присутствует более 60 тыс. строк. Причина такого ограничения строк кроется в существующей между таб­ли­ца­ми Internet Sales и Product связи.

62    DAX и моделирование данных

Из Product

Из Internet Sales

Рис. 2.13    Виртуальная таб­ли­ца, созданная на базе двух таб­лиц

Рис. 2.14    Результат выполнения функции SUMMARIZE() в DAX Studio

Пока все в порядке. Также стоит отметить, что здесь мы создали виртуальную таб­ли­цу внутри меры. При вынесении полей Product Category, Product Subcategory и  Product в  матрицу мера Avg. Product Standard Costs Correct вычисляется правильно. Но мы не создавали никаких связей между таблицей Internet Sales и нашей виртуальной таблицей. Как же мы получили корректные результаты? Ответ кроется в происхождении (lineage) или привязке данных между виртуальной и  физической таб­ли­ца­ми. Виртуальная таб­ли­ца наследует связь с таблицей Internet Sales от таб­ли­цы Product. Иными словами, наша виртуальная таб­ли­ца объединена с таблицей Product посредством виртуальной связи

Понимание виртуальных таблиц    63

«один к одному» по полю ProductKey. Таким образом, когда мы размещаем столбцы Product Category, Product Subcategory и  Product в  матрице, фильтры распространяются на таб­ли­цу Product, а через нее на таб­ли­цу Internet Sales. На рис. 2.15 показано, как виртуальная таб­ли­ца связана с таб­ли­ца­ми Product и Internet Sales. ПРИМЕЧАНИЕ  Ни сама виртуальная таб­ли­ца, ни ее виртуальная связь не будут видны при просмотре модели данных. Здесь они приведены только для демонстрации.

Виртуальная связь

Виртуальная таблица

Рис. 2.15    Виртуальная таб­ли­ца, объединенная виртуальной связью с физической таблицей

Использование виртуальных таб­лиц представляет собой эффективную технику, которую можно применять в самых разных ситуациях. В частности, бывает, что между двумя таб­ли­ца­ми в модели нет физической связи, и создать ее не представляется возможным из-за бизнес-ограничений. Давайте рассмотрим более сложные сценарии с наличием нескольких виртуальных таб­лиц и связей между ними. Руководство требует рассчитывать продажи в таб­ли­це Internet Sales в американских долларах. Но в текущем варианте таб­ли­ца содержит информацию в разных валютах. Откройте файл Chapter 2, Virtual Tables and Relationships. pbix. В нем вы увидите дополнительную таб­ли­цу Exchange Rates. Тогда как базовой валютой является американский доллар (USD), в таб­ли­це Exchange Rates информация по доллару не хранится. На рис. 2.16 представлено содержимое таб­ли­цы Exchange Rates. Как видите, обменные курсы в ней хранятся на каждый день. Если бы нам нужно было снабдить эту таб­ли­цу первичным ключом, пришлось бы остановиться на составном – из столбцов CurrencyKey и Date.

64    DAX и моделирование данных

Рис. 2.16    Данные в таб­ли­це Exchange Rates

Если присмотреться к  данным в  таб­ли­це Exchange Rates внимательнее, можно заметить, что базовой валютой является американский доллар. Таким образом, в столбце AverageRate хранятся курсы различных валют по отношению к доллару на конкретную дату. Чтобы лучше понять описываемый сценарий, давайте взглянем на таб­ли­ цы Internet Sales и Exchange Rates одновременно на рис. 2.17.

SalesAmount в USD: 1000,4375 * 1,47 = 1470,64 782,99 * 1,47 = 1362,40

Рис. 2.17    Пересчет данных из таб­ли­цы Internet Sales в доллары

Чтобы рассчитать сумму продаж за день в долларах, нужно найти соответствующее значение поля CurrencyKey для указанной даты в таб­ли­це Exchange

Понимание виртуальных таблиц    65

Rates, после чего умножить значение поля SalesAmount из таб­ли­цы Internet Sales на значение AverageRate из таб­ли­цы Exchange Rates. Ниже приведена мера, успешно с этим справляющаяся: Internet Sales USD = SUMX( NATURALINNERJOIN ( SELECTCOLUMNS( 'Internet Sales' ; "CurrencyKeyJoin"; 'Internet Sales'[CurrencyKey] * 1 ; "DateJoin"; 'Internet Sales'[OrderDate] + 0 ; "ProductKey"; 'Internet Sales'[ProductKey] ; "SalesOrderLineNumber"; 'Internet Sales'[SalesOrderLineNumber] ; "SalesOrderNumber"; 'Internet Sales'[SalesOrderNumber] ; "SalesAmount"; 'Internet Sales'[SalesAmount] ) ; SELECTCOLUMNS ( 'Exchange Rates' ; "CurrencyKeyJoin"; 'Exchange Rates'[CurrencyKey] * 1 ; "DateJoin"; 'Exchange Rates'[Date] + 0 ; "AverageRate"; 'Exchange Rates'[AverageRate] ) ) ; [AverageRate] * [SalesAmount] )

На рис.  2.18 схематически показано, как работает предыдущее вычис­ ление. Виртуальная таблица Internet Sales

Итоговая объединенная виртуальная таблица Виртуальная таблица Exchange Rates

Итерации по объединенной виртуальной таблице

Рис. 2.18    Как работает мера Internet Sales USD

Как продемонстрировано на рис. 2.18, сначала мы создаем две виртуальные таб­ли­цы. После этого объединяем эти таб­ли­цы по полям CurrencyKeyJoin и DateJoin. Если взглянуть на то, как образованы эти столбцы, можно заметить следующее:

66    DAX и моделирование данных   мы добавили 0 дней к  значению поля 'Internet Sales'[OrderDate] при создании поля DateJoin для виртуальной таб­ли­цы на основании таб­ли­ цы Internet Sales. То же самое мы сделали в отношении поля 'Exchange Rates'[Date] при создании столбца DateJoin для виртуальной таб­ли­цы на основании таб­ли­цы Exchange Rates;   мы умножили на единицу значения поля CurrencyKey при создании столбца CurrencyKeyJoin применительно к обеим виртуальным таблицам. Вас наверняка волнует вопрос,  зачем же мы это сделали. Ответ прост – чтобы функция NATURALINNERJOIN() сработала корректно. Функция NATURALINNERJOIN(), как следует из ее названия, выполняет внутреннее объединение таб­лиц с использованием одних и тех же имен столбцов с одинаковыми типами данных и происхождением. Нам необходимо объединить две виртуальные таб­ли­цы по следующим полям: 'Exchange Rates'[Date];   'Internet Sales'[OrderDate] 'Exchange Rates'[CurrencyKey].   'Internet Sales'[CurrencyKey] Первым требованием для успешного выполнения функции NATURALINNERJOIN() является идентичность названий столбцов, по которым будет выполняться связывание. Чтобы это требование выполнить, мы при создании виртуальных таб­лиц переименовали поля OrderDate из таб­ли­цы Internet Sales и Date из таб­ли­цы Exchange Rates в DateJoin. Второе требование предполагает, что связываемые столбцы должны обладать одним типом данных, и в нашем случае оно выполняется. Что касается третьего требования, которое обычно вызывает больше всего вопросов, заключается оно в том, что поля, по которым осуществляется объединение, должны иметь одинаковое происхождение при наличии физической связи между таб­ли­ца­ми. Если такой связи нет, колонки, участвующие в  объединении, не должны иметь никакого происхождения от физических столбцов в модели данных. Таким образом, нам необходимо разорвать существующие привязки объединяемых столбцов, иначе функция NATURALINNERJOIN() корректно не отработает. А  чтобы это сделать, нужно использовать выражения вместо имен столбцов. Именно это мы и делаем, добавляя 0 дней к полю 'Internet Sales'[OrderDate] и умножая на единицу поле 'Exchange Rates'[CurrencyKey], – это позволит нам избавить наши столбцы от их происхождения. Получив желаемый результат, мы можем перемножить значения в столбцах [SalesAmount] и [AverageRate], чтобы получить суммы продаж в долларах. На рис. 2.19 меры Internet Sales и Internet Sales USD выведены рядом, что позволяет сравнить их значения. ПРИМЕЧАНИЕ  При помощи виртуальных таб­лиц мы можем объединять две таб­ли­ цы с использованием нескольких столбцов.

Итак, мы создали меру Internet Sales USD для демонстрации работы виртуальных таб­лиц и связей. В реальных сценариях лучше будет по возможности

Понимание виртуальных таблиц    67

перенести столбец AverageRate в таб­ли­цу Internet Sales. В нашем примере сделать это очень легко. Мы можем объединить таб­ли­цы Internet Sales и Exchange Rates в  редакторе Po­wer Query для переноса столбца AverageRate в таб­ли­цу Internet Sales.

Рис. 2.19    Одновременный вывод мер Internet Sales и Internet Sales USD в матрице ПРИМЕЧАНИЕ  Всегда, когда это возможно, лучше реализовывать бизнес-логику в источнике данных. Если это сделать нет возможности, попробуйте решить поставленную задачу при помощи редактора Po­wer Query. В случае если логика слишком сложная, чтобы реализовать ее посредством Po­wer Query, рассмотрите вариант создания необходимых физических связей в модели данных в противовес виртуальным. К примеру, в нашем случае с курсами валют мы можем перенести курсы по каждой транзакции в таб­ли­цу Internet Sales без изменения ее гранулярности. Исследуйте бизнес-логику на предмет использования одних и тех же виртуальных таб­лиц. Если вы видите, что виртуальная таб­ли­ца может использоваться многократно, рассмотрите вариант ее замены на физическую или вычисляемую таб­ли­цу, к которой можно будет обращаться в модели данных. Виртуальные таб­ли­цы и  связи – это тот инструмент, который обязательно должен присутствовать в арсенале специалиста по моделям данных, но стоит сказать и об их ресурсоемкости. При использовании применительно к большим наборам данных виртуальные таб­ли­цы могут снижать эффективность решений.

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

68    DAX и моделирование данных

Логика операций со временем и моделирование данных Логика операций со временем (time intelligence) представляет собой одну из наиболее распространенных и мощных областей функций в Po­wer BI. Люди с опытом в SQL прекрасно знают, как трудно бывает организовать аналитическую работу со временем в реляционных базах данных вроде SQL Server. В Po­wer BI эти сложные вычисления производятся довольно легко и просто при помощи целого набора специальных функций логики операций со временем. В этом разделе мы затронем основные трудности, возникающие при работе со временем в Po­wer BI. ПРИМЕЧАНИЕ  В данной книге мы не ставим себе целью обучить вас работе с функциями DAX. Мы просто описываем наиболее полезные концепции при работе с моделями данных.

На текущий момент в Po­wer BI реализовано 35 функций логики операций со временем, с которыми можно ознакомиться по адресу https://docs.microsoft.com/en-us/dax/time-intelligence-functions-dax.

Определение валидности дат в измерении При работе с периодическими вычислениями в области логики операций со временем часто бывает трудно получить только валидные даты для отображения в визуальных элементах. Давайте рассмотрим это на примере сценария. Заказчику необходимо видеть следующие вычисления:   Internet Sales Month to Date (MTD) – продажи с начала месяца;   Internet Sales Last Month to Date (LMTD) – продажи с  начала месяца в предыдущем месяце;   Internet Sales Year to Date (YTD) – продажи с начала года;   Internet Sales Last Year to Date (LYTD) – продажи с начала года в предыдущем году;   Internet Sales Last Year Month to Date (LY MTD) – продажи с начала месяца в аналогичном периоде прошлого года. Вы знаете, что в DAX все эти показатели можно легко рассчитать при помощи функций логики операций со временем. Ниже приведены соответствующие формулы.

Логика операций со временем и моделирование данных    69

Для расчета меры Internet Sales MTD необходимо использовать следующее выражение DAX: Internet Sales MTD = TOTALMTD( [Internet Sales] ; 'Date'[Full Date] )

Формула для меры Internet Sales LMTD: Internet Sales LMTD = TOTALMTD( [Internet Sales] ; DATEADD('Date'[Full Date]; -1; MONTH) )

Формула для меры Internet Sales YTD: Internet Sales YTD = TOTALYTD( [Internet Sales] ; 'Date'[Full Date] )

Формула для меры Internet Sales LYTD: Internet Sales LYTD = TOTALYTD ( [Internet Sales] ; DATEADD('Date'[Full Date]; -1; YEAR) )

Наконец, для меры Internet Sales LY MTD можно применить следующую формулу: Internet Sales LY MTD = TOTALMTD( [Internet Sales] ; SAMEPERIODLASTYEAR('Date'[Full Date]) )

Теперь можно вынести на страницу отчета табличный визуальный элемент и разместить на нем созданные меры вместе со столбцом Full Date из таб­ли­цы Date. Все выглядит хорошо, пока мы не отсортируем столбец Full Date по убыванию, – только после этого проявятся проблемы. Как видите, меры Internet Sales, Internet Sales MTD и Internet Sales LMTD выдают пустые значения по многим датам. А в мере Internet Sales YTD мы получаем по ним дублирующиеся значения. Это показано на рис. 2.20.

70    DAX и моделирование данных

Рис. 2.20    Проблема будущих дат при расчетах, связанных со временем

Что ж, это вполне ожидаемое поведение мер. В измерении с датами у нас должен быть заведен полный календарь с  1 января по 31 декабря по всем нужным нам годам. Но это приводит к тому, что в мерах Internet Sales, Internet Sales MTD и Internet Sales LMTD выводятся пустые значения за будущие даты, а в мере Internet Sales YTD происходит дублирование данных. На рис. 2.21 показано, как данные в таб­ли­це отображаются при прокрутке вниз – на уровень последней даты с  продажами: 28 января 2014 года. Понятно, что все наши предыдущие меры должны прекратить вывод после этой даты.

Логика операций со временем и моделирование данных    71

Все остальные меры должны прекратить вывод после 28.01.2014

Рис. 2.21    Последняя валидная дата продаж – 28 января 2014 года

Одним из решений этой проблемы может быть возвращение BLANK() для невалидных дат. Ниже приведена мера Internet Sales MTD Blanking Invalid Dates, возвращающая пустые значения в  случае отсутствия транзакций за указанную дату: Internet Sales MTD Blanking Invalid Dates = VAR lastorderDate = MAX('Internet Sales'[OrderDateKey]) RETURN IF( MAX('Date'[DateKey]) = MIN('Internet Sales'[OrderDateKey]) ; 'Date'[DateKey] = firstValidDateWithSalesLM && 'Date'[Full Date] = firstValidDateWithSalesLY && 'Date'[Full Date] = firstOderDate; [Full Date] ) и идет определение функции. Например, следующая функция вычисляет последнюю дату месяца для текущей даты: ()as date => Date.EndOfMonth(Date.From(DateTime.LocalNow()))

102    Подготовка данных с помощью Power Query Эта функция не принимает параметров, но возвращает результат. На рис. 3.8 показан способ вызова функции без параметров с помощью кнопки Вызвать (Invoke).

Вы

зва

нн

ая

фу

нкц

ия

Рис. 3.8    Вызов настраиваемой функции

Типы В Po­wer Query все значения имеют тип (type). Существует две основные категории типов: примитивные (primitive type) и пользовательские (custom type).

Примитивные типы Значение может иметь один из следующих примитивных типов:   двоичный (binary);   дата (date);   дата и время (datetime);   дата, время и часовой пояс (datetimezone);   продолжительность (duration);   список (list);   истина/ложь (logical);   null;   числовой (number);   запись (record);   текст (text);   время (time);

Введение в редактор Power Query    103

  тип (type);   функция (function);   таб­ли­ца (table);   any;   none. Среди перечисленных здесь типов данных наибольший интерес представляет тип any. Все остальные типы в Po­wer Query совместимы с типом any. При этом мы не можем говорить, что значение имеет тип any.

Пользовательские типы Пользовательские типы  – это типы, которые мы можем создавать сами. К  примеру, в  следующем выражении определяется пользовательский тип как список чисел: type { number }

Введение в редактор Power Query В Po­wer BI Desktop инструмент Po­wer Query доступен посредством редактора Po­wer Query (Po­wer Query Editor). Перейти в редактор Po­wer Query можно сразу несколькими способами, включая следующие:   нажать на кнопку Преобразование данных (Transform data) на вкладке Главная (Home), как показано на рис. 3.9;

Рис. 3.9    Открытие редактора Po­wer Query из ленты Po­wer BI

  перейти непосредственно к  указанной таб­ли­це в  редакторе Po­wer Query путем нажатия правой кнопкой мыши по ней на панели Поля (Fields) и выбора пункта Изменить запрос (Edit query), как показано на рис. 3.10. В редакторе Po­wer Query содержатся следующие области, показанные цифрами на рис. 3.11. 1. Лента. 2. Панель Запросы (Queries). 3. Панель Параметры запроса (Query Settings). 4. Область данных (Data View). 5. Строка состояния.

104    Подготовка данных с помощью Power Query

Рис. 3.10    Открытие редактора Po­wer Query для редактирования выбранного запроса

Рис. 3.11    Области редактора Po­wer Query

В следующих разделах мы познакомимся с инструментами редактора Po­ wer Query, напрямую связанными с процессом моделирования данных.

Введение в редактор Power Query    105

Панель Запросы В этой области показаны все активные и неактивные запросы, включая таб­ ли­цы, настраиваемые функции, параметры запросов, константы и группы. В следующих разделах мы поговорим о них.

Таблицы Сюда включаются таб­ли­цы, загруженные из источников данных, созданные внутри Po­wer BI при помощи инструмента Введите данные (Enter data), и таб­ ли­цы, ссылающиеся на другие запросы. Таб­ли­цы обозначаются иконкой .

Настраиваемые функции Настраиваемые функции (custom function) – это функции, которые мы создаем в редакторе Po­wer Query. В запросах можно вызывать и повторно использовать эти функции. Значок настраиваемых функций – .

Параметры запросов Мы можем параметризовать различные части запросов с помощью парамет­ ров запросов (query parameter). В  противном случае должны быть введены фиксированные значения. На панели Запросы параметры можно определить по значку .

Константы Есть запросы, возвращающие константы текстового, числового или любого другого типа. Такие запросы легко распознать по соответствующему типу данных значку. К  примеру, если запрос возвращает значение типа Дата и время (DateTime), его значок будет такой: , а если Текст (Text) – то такой: .

Группы Запросы на панели можно организовать по группам следующим образом. 1. Выделите запросы, которые хотите объединить в группу, мышью с зажатой клавишей Ctrl. 2. Щелкните правой кнопкой мыши по любому из выделенных запросов и в контекстном меню выберите пункт Переместить в группу (Move To Group). 3. Выберите в открывшемся меню пункт Создать группу… (New Group…). На рис. 3.12 показаны описанные выше действия.

106    Подготовка данных с помощью Power Query

Рис. 3.12    Организация запросов по группам в редакторе Po­wer Query

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

Панель Параметры запроса Эта панель, расположенная в  редакторе Po­wer Query справа, содержит все свойства и примененные шаги выбранного запроса. Панель Параметры запроса не будет отображаться при выборе в качестве запроса параметра. Также эта панель разделена на две части: Свойства (PROPERTIES) и Примененные шаги (APPLIED STEPS), как показано на рис. 3.14.

Введение в редактор Power Query    107

Рис. 3.13    Группы запросов в редакторе Po­wer Query

Рис. 3.14    Панель параметров запроса в редакторе Po­wer Query

108    Подготовка данных с помощью Power Query

Свойства Переименовать запрос можно, введя его новое название в  текстовое поле Имя (Name). Другие свойства запроса можно изменить, нажав на ссылку Все свойства (All Properties), как показано на рис. 3.15.

Рис. 3.15    Редактирование свойств запроса на панели Параметры запроса

В открывшемся диалоговом окне вы можете изменить следующие свойства запроса:   Имя (Name) – название запроса;   Описание (Description) – для любого запроса можно ввести соответствующее ему описание. Это бывает очень полезно, поскольку помогает с документированием проекта;   Включить загрузку в отчет (Enable load to report) – если этот флажок установлен, данные из запроса будут загружаться в модель данных из источника. Как понятно по рис.  3.15, мы объединили запрос Product с  другими двумя запросами. При этом все эти запросы могут находиться в разных источниках. При отключении этой опции данные из запроса не будут загружаться в модель. Однако если другие запросы ссылаются на этот запрос, данные пройдут полный процесс преобразования;   Включить в  обновление отчета (Include in report refresh): иногда нам может понадобиться загрузить данные в  модель лишь раз и  не включать запрос в процесс обновления. Если установить этот флажок, запрос будет обновляться всякий раз при обновлении модели данных. Мы можем обновлять модель данных из Po­wer BI Desktop по нажатии на кнопку Обновить (Refresh), а можем опубликовать отчет в службе Po­ wer BI и выполнять обновление там. В обоих случаях при отключенной

Введение в редактор Power Query    109

опции обновления запрос не будет включаться в будущие обновления данных. ВАЖНОЕ ПРИМЕЧАНИЕ  Опция Включить в  обновление отчета находится в  зависимости от флажка Включить загрузку в отчет. Если он выключен, то и обновление отчета будет неактивно. Для сложных сценариев принятой практикой является отключение опции Включить загрузку в отчет для запросов, использующихся с целью преобразования данных. На эти запросы впоследствии ссылаются другие запросы.

На рис. 3.16 показано, что к опциям загрузки и обновления данных можно получить доступ и на панели Запросы, щелкнув по нужному запросу правой кнопкой мыши и выбрав пункт Включить загрузку (Enable load) или Включить в обновление отчета (Include in report refresh).

Рис. 3.16    Доступ к загрузке и обновлению данных в запросе с помощью контекстного меню

Область данных Область данных занимает центральное место в редакторе Po­wer Query. При выборе запроса на одноименной панели слева область данных будет принимать вид в зависимости от типа выбранного запроса:   таб­ли­ца с данными, если в списке запросов выбрана таб­ли­ца, как показано на рис. 3.17;

110    Подготовка данных с помощью Power Query

Таблица

Исходные данные

Рис. 3.17    Область данных при выборе таб­ли­цы

  при выборе функции будет отображаться область ввода параметров функции, как показано на рис. 3.18;

Ввод параметров для выбранной функции

Настраиваемая функция

Рис. 3.18    Область данных при выборе функции

  результат выбранного запроса. На рис. 3.19 показана область данных при выборе запроса, возвращающего местную дату и время.

Введение в редактор Power Query    111

Инструменты для работы с датой и временем

Вывод запроса

Запрос с константой в виде даты и времени

Рис. 3.19    Область данных при выборе константы ПРИМЕЧАНИЕ  В зависимости от типа данных возвращаемого запросом значения на ленте будет появляться свой набор инструментов. На рис. 3.20 показан результат запроса, ссылающегося на Environment, являющийся параметром запроса. Таким образом, результат вывода запроса Current Environment будет варьироваться в зависимости от значения, выбранного в параметре Environment.

112    Подготовка данных с помощью Power Query

Инструменты для работы с текстом

Вывод запроса

Запрос с константой в виде текста

Рис. 3.20    Инструменты преобразования данных для запроса с текстовым выводом

Как видно, инструменты для работы с данными на рис. 3.19 и 3.20 отличаются.

Строка состояния В нижней части редактора Po­wer Query располагается строка состояния (status bar), включающая информацию о  выбранном запросе, как показано на рис. 3.21.

Введение в редактор Power Query    113

Выбранный запрос

В выбранном запросе 29 столбцов и более 999 строк

Информация о профиле столбца основывается на первых 1000 строках

Данные для предпросмотра загружены в 14:24

Рис. 3.21    Строка состояния в редакторе Po­wer Query

По приведенному выше рисунку мы видим следующее. 1. Количество столбцов в запросе. Это дает возможность быстро оценить, насколько широкой является исходная таб­ли­ца. 2. Количество строк, на основе которых выведена информация о профиле столбца. По этим данным можно судить о том, насколько можно доверять представленной для предварительного просмотра информации. Иногда профиль столбца может отображать недостоверную информацию, базируясь на первой тысяче строк, что заложено в настройках по умолчанию. 3. Дата обновления области предварительного просмотра.

Расширенный редактор Для создания и изменения запросов можно использовать расширенный редактор (Advanced Editor). Как видно на рис. 3.22, к расширенному редактору можно получить доступ самыми разными способами. Для использования редактора выполните следующие действия. 1. Выберите запрос на левой панели. 2. Нажмите на кнопку Расширенный редактор (Advanced Editor) на вкладке Главная (Home) или щелкните правой кнопкой мыши по запросу и выберите одноименный пункт из контекстного меню. Оба варианта показаны на рис. 3.22.

114    Подготовка данных с помощью Power Query

Рис. 3.22    Открытие расширенного редактора

Возможности Power Query в области моделирования данных В этом разделе мы поговорим о  возможностях редактора Po­wer Query, позволяющих специалистам в области моделирования данных быстрее обнаруживать и устранять возникающие ошибки. Po­wer Query дает возможность разработчикам самостоятельно оценивать качество данных, их распределение и  статистику по столбцам (не по всему набору данных). К  примеру, специалист может быстро определить кратность столбца, процент пустых значений в нем и прочее. ПРИМЕЧАНИЕ  Как мы уже упоминали ранее, информация о  качестве, распределении и  профиле столбцов рассчитывается на основании первых 1000 строк (по умолчанию), в связи с чем иногда может не совсем точно отражать картину в целом. Для небольших наборов данных уместно выполнять профилирование столбцов на основании всех строк. Однако при наличии большого количества записей это может привести к значительному увеличению времени загрузки данных, так что с этой настройкой необходимо быть осторожным.

Возможности Power Query в области моделирования данных    115

Для изменения количества строк, на основании которых строится статис­ тика по столбцам, сделайте следующее. 1. Щелкните мышью по сообщению Профилирование столбца на основе первых строк (1000) (Column profiling based on top 1000 rows). 2. В выпадающем списке выберите вариант Профилирование столбца на основе всего набора данных (Column profiling based on entire data set). На рис. 3.23 наглядно показано, как это можно сделать.

Выбранный запрос

Рис. 3.23    Расчет статистики по столбцам на основе всего набора данных

Качество столбца Если присмотреться, под заголовком любой колонки в области данных Po­ wer Query располагается зеленая полоска, характеризующая качество столбца (column quality). Если навести мышью на эту полоску, во всплывающем окне будет показано больше информации о качестве данных в столбце. На рис. 3.24 показано это окно для столбца Size в запросе Product. Полоска качества данных

Рис. 3.24    Полоска качества данных в редакторе Po­wer Query

116    Подготовка данных с помощью Power Query И хотя этот инструмент дает определенную полезную информацию о качестве данных столбца, есть возможность получить больше сведений в этой области. Чтобы получить к ним доступ, сделайте следующее. 1. В редакторе Po­wer Query перейдите на вкладку Просмотр (View). 2. Установите флажок Качество столбца (Column quality). 3. Больше информации будет появляться во всплывающем окне при наведении на область отображения качества данных под заголовком каждого столбца, как показано на рис. 3.25. С помощью инструмента качества данных можно быстро оценить валидность значений в  колонке, а также количество ошибок и  пустых значений в ней в процентном выражении. Этот инструмент может быть незаменимым при обнаружении ошибок в  данных. Также он помогает определить долю ошибочных значений в столбце, чтобы впоследствии их можно было удалить из результирующего набора.

Column Quality

Рис. 3.25    Качество столбца в редакторе Po­wer Query

Также мы можем выполнить дополнительные действия прямо из всплывающего окна, щелкнув мышью на кнопку с тремя точками, как показано на рис. 3.26. Как видите, посредством этого меню можно скопировать информацию о качестве данных, которая может пригодиться для составления документации. Также здесь можно предпринять действия по удалению ошибок. Обычно рекомендуется выявлять ошибки в данных и исправлять их тем или иным способом, а прибегать к их удалению можно только в случае крайней необходимости. Давайте посмотрим, как инструмент определения качества столбца может помочь нам в реальных сценариях. Для этого примера воспользуемся файлом с названием Chapter 3, Query Editor.pbix. Нам необходимо удалить из таб­ли­цы Customer столбцы, содержащие менее 10 % допустимых (valid) данных. Для этого нужно выполнить следующие действия. 1. Откройте Chapter 3, Query Editor.pbix. 2. Откройте редактор Po­wer Query.

Возможности Power Query в области моделирования данных    117

Рис. 3.26    Доступные действия из меню окна с качеством данных

3. Беглого взгляда в область качества данных под заголовками столбцов достаточно, чтобы определить, что следующие колонки можно смело удалять: •• Title; •• Suffix; •• AddressLine2. На рис. 3.27 видно, что перечисленные столбцы содержат большое количество пустых значений.

Рис. 3.27    Использование инструмента качества данных для выявления столбцов с недостаточным процентом допустимых значений

Удалить столбцы из итогового набора можно очень просто. 1. Перейдите на вкладку Главная (Home). 2. Нажмите на кнопку Выбор столбцов (Choose Columns).

118    Подготовка данных с помощью Power Query 3. Снимите флажки с перечисленных выше колонок. 4. Нажмите на кнопку OK. На рис. 3.28 графически показана последовательность этих действий.

Снимите флажки со столбцов для их удаления

Рис. 3.28    Удаление столбцов

Распределение столбцов Распределение столбца (column distribution) – еще один полезный инструмент, позволяющий получить больше информации о  содержании данных, а также количестве отдельных (distinct) и уникальных (unique) значений. Информация о распределении данных в столбце может помочь разработчику определиться с его кратностью. Кратность (cardinality) столбца – очень важная тема в процессе моделирования данных, особенно когда речь заходит об управлении памятью и сжатии данных. ПРИМЕЧАНИЕ  В общем случае необходимо всегда стремиться к уменьшению кратности столбца. При загрузке данных в модель движок xVelocity значительно более эффективно выполняет сжатие столбцов с  низкой кратностью. Столбцы с  низкой кратностью отличаются малым количеством (или отсутствием) уникальных значений.

Возможности Power Query в области моделирования данных    119

Инструмент определения распределения столбца может помочь с выбором в  отношении загрузки того или иного столбца в  модель данных. Удаление необязательных колонок способно положительно повлиять на размер итогового файла и его быстродействие. Чтобы активировать этот инструмент, перейдите на вкладку Просмотр (View) и установите флажок Распределение столбцов (Column distribution), как показано на рис. 3.29.

Рис. 3.29    Включение распределения столбцов в редакторе Po­wer Query

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

Раздел распределения данных

Всплывающее окно

Рис. 3.30    Всплывающее окно инструмента распределения столбцов

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

120    Подготовка данных с помощью Power Query Давайте посмотрим, как пользоваться этим инструментом на практике. Откройте файл Chapter 3, Query Editor.pbix и присмотритесь к таб­ли­це Customer. Это очень широкая и длинная таб­ли­ца. Нам необходимо определить среди столбцов список кандидатов на удаление, который впоследствии будет обсуждаться с руководством компании в целях экономии ресурсов. 1. Выделите таб­ли­цу Customer на панели Запросы. 2. Установите расчет профилирования столбцов по всем имеющимся данным. 3. Быстро просканируйте области распределения столбцов на предмет поиска колонок с высокой кратностью. Вот список столбцов с высокой кратностью:   CustomerKey;   CustomerAlternateKey;   EmailAddress;   Phone. На рис. 3.31 эти колонки подсвечены цветом.

Столбцы с высокой кратностью

Рис. 3.31    Определение столбцов с высокой кратностью в таб­ли­це Customer

Столбец CustomerKey не является кандидатом на удаление, поскольку он участвует в связи между таб­ли­ца­ми Internet Sales и Customer в модели данных. При этом мы можем избавиться от столбца с именем CustomerAlternateKey. Это избыточная колонка с  очень высокой кратностью (100 % уникальных значений), кроме того, она не добавляет никакой ценности таб­ли­це с точки зрения анализа данных. Присутствие двух оставшихся столбцов в  модели данных необходимо обсудить с руководством. Для примера, удаление всех трех столбцов из таб­ли­цы позволит уменьшить размер файла с 2,5 до 1,9 Мб. Это очень существенно, особенно применительно к большим моделям данных.

Возможности Power Query в области моделирования данных    121

Профиль столбца Ранее мы говорили о качестве и распределении столбцов. Также мы можем посмотреть профиль столбца (column profile), чтобы получить больше информации о значениях в выбранной колонке. Для этого установите флажок Профиль столбца (Column profile) на вкладке Просмотр (View), как показано на рис. 3.32.

Рис. 3.32    Профиль столбца в редакторе Po­wer Query

Как видно на рис. 3.33, после установки этой опции в нижней части окна появятся области Статистика по столбцам (Column Statistics) и Распределение значений (Value Distribution). Вы можете навести мышью на значения, чтобы увидеть во всплывающем окне количество и процент этих значений в общем объеме. Вам также доступны некоторые действия со значениями по нажатии на кнопку с тремя точками, что также видно на рис. 3.33.

Распределение значений

Профиль столбца

Рис. 3.33    Профиль столбца

Мы уже поговорили о том, как работает язык формул Po­wer Query и  как использовать редактор Po­wer Query в  Po­wer BI. Мы также рассмотрели несколько вспомогательных инструментов, облегчающих процесс моделирования данных. В следующих нескольких разделах обсудим не менее важные аспекты моделирования данных, включая параметры запросов, а также рассмотрим несколько полезных сценариев из практики.

122    Подготовка данных с помощью Power Query

Параметры запросов Одной из наиболее важных возможностей при работе с Po­wer Query является возможность создавать параметры запросов (query parameter) и использовать их повторно по своему усмотрению. К  примеру, мы можем создать запрос, ссылающийся на параметр для извлечения информации из разных наборов данных, или параметризовать фильтрацию строк. В целом с помощью параметров запросов мы можем параметризовать следующие области и операции:   источник данных;   фильтрацию строк;   сохранение строк;   удаление строк;   замену строк. В дополнение мы можем загрузить значения параметров в модель данных, чтобы ссылаться на них из мер, вычисляемых столбцов и таб­лиц, а также из элементов отчетов при необходимости. Определить параметр запроса в редакторе Po­wer Query можно следующим образом. 1. Нажмите на кнопку Управление параметрами (Manage Parameters) на вкладке Главная (Home). 2. Нажмите на кнопку Создать (New). 3. Введите имя параметра. 4. Введите описание параметра, которое поможет пользователю понять его предназначение. 5. Установите флажок Требуется (Required), чтобы сделать параметр обязательным. 6. Выберите тип данных параметра из выпадающего списка. 7. Выберите нужный вариант в выпадающем списке Предлагаемые значения (Suggested Values). 8. В зависимости от выбранного на предыдущем шаге варианта вам может потребоваться ввести несколько значений, что показано на рис. 3.34. Если вы выбрали пункт Запрос (Query), вам необходимо выбрать запрос в появившемся списке. 9. Также в  зависимости от выбранного варианта на шаге 7 вы можете видеть или не видеть поле для ввода значения по умолчанию. Если ваш выбор – Список значений (List of values), вам необходимо будет выбрать значение по умолчанию. 10. Выберите или введите значение в  поле Текущее значение (Current Value). 11. Нажмите на кнопку OK. Описанные выше шаги проиллюстрированы на рис. 3.34.

Параметры запросов    123

Рис. 3.34    Определение нового параметра запроса ПРИМЕЧАНИЕ  Всегда лучше использовать параметры для определения источников данных, вместо того чтобы указывать их вручную. Некоторые организации считают имена своих источников данных и строки подключения конфиденциальной информацией. Также они разрешают обмен внутри компании и со сторонними организациями только файлами с расширением PBIT, поскольку это шаблонные файлы и они не содержат данных. В отсутствие параметризации источников данных эти файлы могут включать в  себя информацию об имени сервера, путях к  данным, ссылках SharePoint и т. д. Использование параметров с выбором варианта Любое значение (Any value) позволит избежать утечки важной информации.

Количество областей применения параметров запросов невероятно велико. Давайте рассмотрим сценарий из жизни, в котором параметризация будет очень кстати.

124    Подготовка данных с помощью Power Query В данном случае мы будем параметризовать источники данных. Этот вид параметризации может использоваться по-разному – от подключения к различным источникам данных до загрузки разных комбинаций столбцов. Одним из главных преимуществ параметризации источников данных является возможность избежать прямого указания имен серверов, баз данных, файлов, папок и т. д. Итак, в организации принята политика совмещения трех раздельных окружений данных для разработки (Development – Dev), тестирования пользователями (User Acceptance Testing – UAT) и рабочего использования (Production – Prod). В наши задачи входит формирование отчета с анализом продаж на основе данных из хранилища на базе SQL Server. Для каждого окружения выделен отдельный сервер со своим хранилищем данных. На стадии разработки отчет в Po­wer BI должен соединяться с сервером Dev и получать данные из одноименной базы данных. По готовности к тестированию пользователями отчет должен перенаправляться в окружение и базу данных UAT, а когда будет принято решение о его вводе в эксплуатацию, окружение должно смениться на Prod. Для реализации описанного сценария нам необходимо определить два параметра. В одном будет храниться имя сервера, в другом – базы данных. После этого нужно настроить соответствующие запросы на работу с  этими параметрами. Всегда лучше предусмотреть использование параметров с  самого запуска проекта. Но не беспокойтесь: если у  вас есть готовый отчет в Po­wer BI, параметризовать источник данных для него не составит большого труда. Зато в дальнейшем вам не придется менять код при переключении между различными окружениями. Итак, давайте создадим параметр. 1. Нажмите на кнопку Управление параметрами (Manage Parameters) на вкладке Главная (Home). 2. Нажмите на кнопку Создать (New). 3. В поле Имя (Name) введите Server Name. 4. Поле описания параметра заполните по своему усмотрению. 5. Установите флажок Требуется (Required). 6. Выберите тип данных параметра Текст (Text) из выпадающего списка. 7. В выпадающем списке Предлагаемые значения (Suggested Values) выберите вариант Список значений (List of values). 8. Заполните появившийся список именами серверов. 9. Выберите сервер devsqlsrv01\edw в качестве значения по умолчанию. 10. Выберите сервер devsqlsrv01\edw в качестве текущего значения. 11. Нажмите на кнопку OK. Описанные шаги проиллюстрированы на рис. 3.35.

Параметры запросов    125

Рис. 3.35    Создание параметра с именами серверов для различных окружений

Теперь нужно проделать все те же шаги для создания параметра с именами баз данных. Если их имена одинаковые в каждом окружении, этот этап можно пропустить. На рис.  3.36 показан созданный нами параметр для хранения имен баз данных.

126    Подготовка данных с помощью Power Query

Рис. 3.36    Создание параметра с именами баз данных для разных окружений

Если у вас уже есть созданные запросы, необходимо изменить источники данных для них следующим образом. 1. Выберите нужный запрос для параметризации. 2. Нажмите на панели примененных шагов на кнопку с шестеренкой рядом с шагом Источник (Source). 3. Выберите пункт Параметр (Parameter) в выпадающем списке Сервер (Server). 4. Выберите параметр Server Name в соседнем выпадающем списке. 5. Выберите пункт Параметр (Parameter) в  выпадающем списке База данных (Database). 6. Выберите параметр Database Name в соседнем выпадающем списке. 7. Нажмите на кнопку OK. Все эти шаги продемонстрированы на рис. 3.37. Похожие действия по параметризации источника данных нужно проделать и с другими существующими запросами. После этого для переключения между источниками нам достаточно будет поменять значение параметра. Сделать это в редакторе Po­wer Query можно следующим образом.

Параметры запросов    127

1. Нажмите на выпадающую кнопку Управление параметрами (Manage Parameters) на вкладке Главная (Home). 2. Выберите из выпадающего списка пункт Изменить параметры (Edit Parameters). 3. Выберите в списке Server Name значение, соответствующее окружению UAT. 4. Аналогичный выбор сделайте в списке Database Name. 5. Нажмите на кнопку OK. Эти шаги проиллюстрированы на рис. 3.38.

Рис. 3.37    Параметризация источника данных

Рис. 3.38    Изменение значений параметров в редакторе Po­wer Query

128    Подготовка данных с помощью Power Query Также значения параметров можно менять из главного окна Po­wer BI Desktop. Для этого нужно сделать следующее. 1. Нажмите на раскрывающуюся кнопку Преобразование данных (Transform data) на вкладке Главная (Home). 2. Выберите пункт Изменить параметры (Edit parameters). 3. Выберите в списке Server Name значение, соответствующее окружению UAT. 4. Аналогичный выбор сделайте в списке Database Name. 5. Нажмите на кнопку OK. Эти шаги схематически показаны на рис. 3.39.

Рис. 3.39    Изменение значений параметров в Po­wer BI Desktop

Настраиваемые функции Зачастую возникают ситуации, когда нам необходимо повторно выполнять одни и те же вычисления. В таких случаях лучше всего бывает один раз создать настраиваемую функцию (custom function), в которой будет заключена вся логика необходимых вычислений. После этого мы можем бесчисленное количество раз вызывать созданную функцию. Как мы уже упоминали выше, настраиваемую функцию можно создать, заключив в  круглые скобки список параметров, если они имеются, указав тип данных выходного значения и определив тело функции после специальных символов =>.

Настраиваемые функции    129

Ниже показан пример простейшей функции, принимающей в  качестве аргумента дату и возвращающей следующий за ней день в виде даты: SimpleFunction = (DateValue as date) as date => Date.AddDays(DateValue, 1)

Вызвать эту функцию легко и просто: SimpleFunction(#date(2020,1,1))

Результат вывода будет следующим: 2/01/2020. Допустимо создавать и вызывать настраиваемые функции непосредственно в тексте одного и того же запроса с  использованием расширенного редактора. На рис.  3.40 показано, как показанную выше функцию с  именем SimpleFunction создать внутри запроса и вызвать там же.

Определение функции внутри запроса

Вызов функции внутри запроса

Рис. 3.40    Определение и вызов функций внутри запроса

Давайте сделаем шаг в реальность и рассмотрим пример из жизни, в котором настраиваемая функция позволит сэкономить немало времени на этапе разработки проекта. Итак, перед нами стоит задача построить модель данных на основании более ста таб­лиц. Первоначальный анализ показал, что в среднем в таб­ли­цах будет от 20 до 150 столбцов. При этом заголовки столбцов написаны в «верблюжьем» стиле (слитное написание слов с заглавными буквами) и плохо читаются. Варианта у нас два: мы можем вручную переименовать все столбцы или найти способ сделать это за один проход. И хотя нам придется делать это отдельно для каждой таб­ли­цы, это все равно позволит сэкономить немало времени. Для выполнения данной задачи мы можем создать настраиваемую функцию и вызвать ее впоследствии во всех таб­ли­цах. Давайте рассмотрим именование столбцов на примере одной таб­ли­цы. На рис. 3.41 показаны имена колонок в таб­ли­це Product – далеко не самые удобочитаемые. Обратите внимание, что в строке состояния есть информация

130    Подготовка данных с помощью Power Query об общем количестве столбцов в таб­ли­це, – в данном случае оно составляет 37. Согласитесь, было бы очень трудозатратно переименовывать все столбцы вручную, разделяя в них слова.

Рис. 3.41    Исходные имена столбцов в таб­ли­це Product

В нашем случае достаточно будет разделить пробелами заголовки столбцов в  тех местах, где строчные буквы сменяются прописными. Для этого выполните следующие шаги. 1. Создайте в редакторе Po­wer Query пустой запрос, нажав на выпадающую кнопку Создать источник (New Source) и выбрав пункт Пустой запрос (Blank Query), как показано на рис. 3.42.

Рис. 3.42    Создание пустого запроса в редакторе Po­wer Query

2. Откройте Расширенный редактор (Advanced Editor). 3. Скопируйте и вставьте запрос, показанный на шаге 4, в окно расширенного редактора, и нажмите на кнопку OK.

Настраиваемые функции    131

4. Переименуйте запрос в fnRenameColumns. let fnRename = (ColumnName as text) as text => let SplitColumnName = Splitter.SplitTextByCharacterTransition({"a".."z"}, {"A".."Z"})(ColumnName) in Text.Combine(SplitColumnName, " ") in fnRename

На рис. 3.43 показано, как выглядит созданная нами функция в редакторе Po­wer Query.

Рис. 3.43    Создание настраиваемой функции

Наша функция принимает текстовое значение, преобразует его в список по разделителю, соответствующему переходу со строчной буквы на прописную, после чего объединяет элементы полученного списка, используя в качестве разделителей пробелы. Чтобы понять, как работает этот код, достаточно озна­комиться с документацией по функции Splitter.SplitTextByCha­ racterTransition() на сайте Microsoft Docs. Обратите внимание, что функция Splitter.SplitTextByCharacterTransition() сама возвращает функцию, так что для применения функции SplitTextByCha­ racterTransition к входному параметру ColumnName применяется конструкция Splitter.SplitTextByCharacterTransition({"a".."z"}, {"A".."Z"})(ColumnName), возвращающая список элементов. Теперь давайте вызовем функцию fnRenameColumns из таб­ли­цы Product. Для этого сделайте следующее. 1. Активируйте опцию Строка формул (Formula Bar) на вкладке Просмотр (View), если еще этого не сделали, как показано на рис. 3.44.

Рис. 3.44    Активация строки формул в редакторе Po­wer Query

132    Подготовка данных с помощью Power Query 2. Выберите таб­ли­цу Product на панели запросов. 3. Нажмите слева от строки формул на кнопку Добавить шаг (Add Step) в виде значка fx для создания нового шага в запросе. Очень удобно, что по умолчанию в  строке формул вы увидите имя предыдущего шага, которое мы будем использовать в формуле. На рис. 3.45 показано, как выглядит добавленный шаг.

Имя предыдущего шага

Новый шаг

Рис. 3.45    Добавление нового шага из строки формул

4. Теперь используем функцию Table.TransformColumnNames(), которая преобразует имена столбцов заданной таб­ли­цы в соответствии с переданной ей функцией генерации имен. В качестве таб­ли­цы мы используем вывод предыдущего шага, а в качестве генератора – созданную ранее функцию fnRenameColumns. Таким образом, вызов функции будет выглядеть так: Table.TransformColumnNames(#"Renamed Columns", fnRenameColumns)

5. После сохранения этого шага все столбцы в таб­ли­це будут немедленно переименованы, что видно по рис. 3.46.

Имя предыдущего шага

Рис. 3.46    Переименование столбцов при помощи функции

6. Теперь осталось переименовать сам шаг, чтобы было понятно, что он делает. Для этого щелкните по нему правой кнопкой мыши, выберите пункт Переименовать (Rename) и введите новое имя, как показано на рис. 3.47.

Настраиваемые функции    133

Рис. 3.47    Переименование шага запроса

Рекурсивные функции Из любой функции можно обратиться непосредственно к ней же, что делает функцию рекурсивной (recursive function). Из курса школы вы должны помнить, что факториал вычисляется путем перемножения всех положительных чисел от заданного вниз до единицы. В  математике для обозначения факториала используется восклицательный знак (n!). Следующая формула позволяет вычислить факториал числа: n! = n * (n – 1)!

Как видно по этой формуле, вычисление факториала представляет собой рекурсию. При расчете факториала мы должны выбрать любое положительное число больше нуля. При выборе нуля факториал будет равен единице. Ниже приведены несколько примеров расчета факториала для лучшего понимания: 10! = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 3 628 800 5! = 5 * 4 * 3 * 2 * 1 = 120 1! = 1 0! = 1

При написании рекурсивной функции необходимо использовать оператор @ для ссылки на функцию внутри самой себя. Например, следующая функция приведет к вычислению факториала переданного числа:

134    Подготовка данных с помощью Power Query let Factorial = (ValiedNumber as number) as number => if ValiedNumber < 0 then error "Факториал для отрицательных чисел не вычисляется. Введите положительное число." else if ValiedNumber = 0 then 1 else ValiedNumber * @Factorial(ValiedNumber - 1) in Factorial

Как видите, при неправильном входном значении функции мы генерируем ошибку с текстовым сообщением. Далее, если на вход было передано число 0, возвращаем единицу, в  противном случае вычисляем факториал с помощью рекурсии. На рис. 3.48 показан вывод сообщения об ошибке при передаче функции отрицательного значения.

Рис. 3.48    Сгенерированная ошибка в ответ на передачу функции отрицательного числа

На рис. 3.49 показан результат вычисления факториала числа 10.

Рис. 3.49    Вычисление факториала числа 10

Заключение    135

Заключение В этой главе мы обсудили различные аспекты встроенного в  Po­wer Query языка формул M и  посмотрели, как можно использовать редактор Po­wer Query. Мы также рассмотрели несколько сценариев, предвещающих проблемы с производительностью, и на их примере научились более эффективно управлять подготовкой данных. В следующей главе мы поговорим о получении данных из различных источников и использовании разных режимов подключения, а также затронем некоторые важные аспекты моделирования данных.

Глава

4

Получение данных из различных источников В предыдущих главах мы обсуждали разные аспекты моделирования данных, включая слои в Po­wer BI и движение данных между ними, виртуальные таб­ли­цы, созданные при помощи DAX, и их взаимосвязь с построением эффективных моделей. Мы также затронули тему использования параметров запросов и создания настраиваемых функций в редакторе Po­wer Query. В этой главе мы научимся импортировать данные из различных источников. Вместе с тем рассмотрим частые ошибки и ловушки, преследующие разработчиков в  области загрузки данных. Также мы коснемся темы сертификации источников данных и  использования различных режимов при подключении к источникам. Разделы, которые будут представлены в главе:   получение данных из распространенных источников данных;   сертификация источников данных;   работа с разными режимами подключения;   работа с разными режимами хранения;   режимы хранения наборов данных.

Получение данных из распространенных источников данных С помощью Po­wer BI мы можем подключаться к самым разным источникам данных. В  этом разделе мы коснемся наиболее распространенных источников и на их примере покажем общие принципы подключения к внешней информации. Также мы обсудим некоторые ошибки, зачастую возникающие на этом этапе. Но сначала давайте попробуем устранить распространенное недопонимание в  среде разработчиков и  пользователей Po­wer BI по поводу самого термина получение данных. Когда мы говорим получить данные, мы имеем в виду подключение к источнику данных посредством редактора Po­wer Query – вне зависимости от типа источника. Далее мы создаем последовательность шагов преобразования исходных данных для их подготовки к импорту в модель данных.

Получение данных из распространенных источников данных    137

При этом, работая в редакторе Po­wer Query, мы не говорим о физическом импорте данных, пока не нажмем на кнопку Закрыть и применить (Close and Apply) на вкладке Главная (Home) или Применить (Apply) в выпадающем меню. Только после этого информация физически переносится в модель данных. Вы можете спросить: а  что за данные показываются в  окне предварительного просмотра в редакторе Po­wer Query? Ответ прост: это просто фрагмент исходных данных для визуального отображения влияния применяемых шагов. Таким образом, чисто технически мы просто подключаемся к источнику и создаем шаги преобразования данных. Эти шаги будут применены ко всем данным в момент их физической загрузки в модель.

Папка Получение исходных данных из папок – один из самых распространенных способов взаимодействия с информацией, хранящейся в виде файлов. При этом в папке, к которой вы подключаетесь, могут находиться файлы самых разных типов, включая Excel, Access, CSV, PDF, JSON, TXT и др. Структура данных внут­ ри этих файлов, как вы понимаете, может быть различной, что значительно затрудняет работу с ними. Одной из самых мощных возможностей при подключении к папкам в Po­wer Query является автоматическое извлечение всех файлов, включая те, которые хранятся во вложенных директориях. Зачастую это бывает очень полезно, но в некоторых случаях может мешать, в частности когда мы не хотим объединять файлы, находящиеся в разных папках. В таких ситуациях вы можете отфильтровать нужные вам файлы, исходя из пути к папке, чтобы исключить из выбора нежелательные объекты. Давайте рассмотрим процесс подключения к  папкам на примере. Часто бывает так, что файлы в  формате Excel складываются в  одну папку, после чего выполняется их обобщенный анализ. В нашем сценарии будет производиться анализ файлов, экспортируемых из ERP-системы при помощи инструмента ETL. Этот инструмент генерирует файлы разных форматов, но нас интересуют только файлы Excel. Архивные файлы система переносит в папку с именем Archive, и они не должны участ­ вовать в анализе. Итак, нам необходимо импортировать файлы Excel из папки, не затрагивая при этом файл в директории Archive. На рис. 4.1 показана структура папок.

Рис. 4.1    В папке Excel находится директория Archive, файлы из которой загружать не нужно

138    Получение данных из различных источников Для выполнения поставленной задачи сделайте следующее. 1. Откройте Po­wer BI Desktop и  нажмите на кнопку Получить данные (Get data). 2. В разделе Все (All) выберите пункт Папка (Folder). 3. Нажмите на кнопку Подключить (Connect). 4. Нажмите на кнопку Обзор… (Browse…) и  укажите местоположение папки на диске. 5. Нажмите на кнопку OK. 6. В нижней части окна нажмите на кнопку Преобразовать данные (Transform Data). Перечисленные шаги схематически показаны на рис. 4.2.

Рис. 4.2    Получение данных из папки

Как видно на рис. 4.1, в папке Excel содержится три файла для анализа. В то же время при подключении к папке мы видим четыре файла, что показано на рис. 4.2. Чтобы исключить ненужные файлы, необходимо воспользоваться фильтром по столбцу Folder Path, что продемонстрировано на рис. 4.3.

Рис. 4.3    Фильтрация данных на основании столбца Folder Path

Получение данных из распространенных источников данных    139

Для этого выполните следующие действия. 7. Нажмите на выпадающую кнопку фильтрации справа от заголовка столбца Folder Path. 8. Наведите на выпадающее меню Текстовые фильтры (Text Filters). 9. Выберите пункт Не содержит… (Does Not Contain…). 10. В появившемся диалоговом окне Фильтрация строк (Filter Rows) введите имя папки Archive, из которой мы не хотим импортировать файлы. 11. Нажмите на кнопку OK. Эти шаги показаны на рис. 4.4.

Рис. 4.4    Исключение папки Archive

На данный момент нам удалось оставить в запросе только те файлы, которые нам необходимо проанализировать. Осталось объединить содержимое этих файлов. Для этого сделайте следующее. 12. Нажмите на кнопку Объединить файлы (Combine Files) справа от заголовка столбца Content для открытия одноименного диалогового окна, как показано на рис. 4.5.

Рис. 4.5    Объединение файлов

В открывшемся окне у  вас есть возможность выбрать пример файла. Po­wer BI будет использовать этот файл в процессе создания настраиваемой функции для навигации по файлам Excel. Здесь у вас есть два варианта: •• выбрать таб­ли­цу или лист из списка с  заголовком Параметр1 (Parameter1); •• щелкнуть правой кнопкой мыши по папке Параметр1 (Parameter1) и выбрать пункт Преобразовать данные (Transform Data).

140    Получение данных из различных источников Работать с данными, хранящимися в таб­ли­цах, обычно гораздо проще, чем с информацией на рабочих листах. 13. Выберите таб­ли­цу Sales_Data. 14. Нажмите на кнопку OK. Последние два шага схематически показаны на рис. 4.6.

Таблица Лист

Рис. 4.6    Навигация по файлам Excel для их объединения

Выполнение предыдущих шагов приведет к созданию сразу четырех шагов, что видно по рис. 4.7.

Создано и организовано в Power BI автоматически

Рис. 4.7    Запросы и папки, автоматически созданные для объединения файлов

Давайте присмотримся внимательнее к четырем новым запросам, автоматически созданным в редакторе Po­wer Query:

Получение данных из распространенных источников данных    141

  Параметр1 (Parameter1): параметр запроса типа Двоичный (Binary), используемый в настраиваемой функции Преобразовать файл (Transform File) и  запросе Преобразовать пример файла (Transform Sample File);   Пример файла (Sample File): это наш исходный запрос с добавленным шагом навигации к первому двоичному файлу, который соответствует первой рабочей книге Excel;   Преобразовать файл (Transform File): настраиваемая функция, принимающая в  качестве аргумента Параметр1 (Parameter1). Далее на основании нашего выбора на шаге 13 она проходит по файлу Excel, считывая данные с листов или из таб­лиц (в нашем случае из таб­лиц);   Преобразовать пример файла (Transform Sample File): простой запрос для открытия файла Excel с использованием Параметр1 (Parameter1). Этот запрос исключен из загрузки в модель данных. Бывает, что нам необходимо сохранить какие-то метаданные, например дату создания (Date Created) файла, которая видна на рис.  4.4. В  столбце Attribute собраны и  другие метаданные, организованные в виде записей. Вы можете исследовать содержимое этого столбца самостоятельно. В данном примере мы хотели бы сохранить столбец Date Created для использования в будущем. С этой целью давайте изменим автоматически созданный шаг следующим образом. 15. Щелкните по кнопке с шестеренкой справа от шага Другие удаленные столбцы1 (Removed Other Columns1). 16. Установите флажок в поле Date Created. 17. Нажмите на кнопку OK. Заключительные действия показаны на рис. 4.8.

Рис. 4.8    Сохранение нужных столбцов

142    Получение данных из различных источников Итак, мы объединили данные из файлов Excel, находящихся в одной папке. Как видно на рис. 4.9, мы можем легко определить, из какого файла пришла та или иная строка. Также мы видим даты создания файлов Excel, что может быть очень удобно для тех, кто будет поддерживать отчет в будущем. С помощью этих колонок всегда можно понять, в каком именно файле возникла проблема.

Рис. 4.9    Результат объединения данных из файлов Excel, сохраненных в папке

Осталось переименовать запрос Excel в Sales.

CSV/Текст/TSV Хотя в Po­wer BI есть отдельные коннекторы для подключения к файлам CSV и TXT, для извлечения информации из файлов с разделителями в виде табуляции (tab-separated values – TSV) специального коннектора не предусмотрено. В данном разделе мы кратко рассмотрим работу с этими тремя типами файлов. Давайте обратимся к конкретному сценарию. В предыдущем разделе мы загружали данные из файлов Excel, находящихся в одной папке. Теперь же мы получили на вход данные в разных форматах. А  именно данные для таб­ли­цы Product содержатся в  формате CSV, Product Subcategory  – в  формате TSV, а  Product Category  – в  TXT. Нам необходимо загрузить все эти данные из файлов в  Po­wer BI. В  этом примере мы будем работать с файлом Chapter 4, Get Data From Various Sources.pbix. На рис. 4.10 показаны файлы, данные из которых нужно импортировать в Po­wer BI.

Получение данных из распространенных источников данных    143

Рис. 4.10    Файлы CSV, TXT и TSV для загрузки в Po­wer BI

Начнем с файла Product Category. 1. В редакторе Po­wer Query нажмите на кнопку Создать источник (New Source). 2. Выберите вариант Текстовый или CSV-файл (Text/CSV). 3. Укажите папку с файлами примера и выберите файл Product Category. txt. 4. Нажмите на кнопку Открыть (Open). 5. Po­wer BI правильно определил содержимое полей Источник файла (File Origin) и Разделитель (Delimiter), так что можно просто нажать на кнопку OK. Эти шаги схематически показаны на рис. 4.11. Итак, мы успешно извлекли данные о категориях товаров из файла Product Category.txt. Теперь перейдем к импорту информации о подкатегориях товаров, хранящейся в файле TSV. Как мы упоминали ранее, на данный момент в Po­wer BI нет отдельного коннектора для подключения к файлам TSV. При этом мы знаем, что данные в таких файлах хранятся в текстовом виде и разделены символами табуляции. Так что мы вполне можем извлечь их при помощи того же коннектора Текстовый или CSV-файл (Text/CSV). Вот что для этого нужно сделать. 1. Снова нажмите на кнопку Создать источник (New Source). 2. Выберите вариант Текстовый или CSV-файл (Text/CSV). 3. Укажите папку с файлами примера и выберите тип файлов Все файлы (All files) (*.*). 4. В списке появится файл Product Subcategory.tsv. Выберите его. 5. Нажмите на кнопку Открыть (Open). 6. Po­wer BI снова правильно определил содержимое полей Источник файла (File Origin) и Разделитель (Delimiter) – на этот раз это символ табуляции, – так что можно просто нажать на кнопку OK. Эти шаги показаны на рис. 4.12.

144    Получение данных из различных источников

Рис. 4.11    Получение данных из текстового файла

Как видите, мы довольно легко справились с импортом данных из файлов TXT и TSV, и все прошло нормально. Но так бывает не всегда. В реальности на этом этапе могут появляться самые разные проблемы, и сейчас мы разберем одну из наиболее распространенных ошибок, возникающих при работе с текстовыми файлами. Загрузив данные в таб­ли­цы Product Category и Product Subcategory, мы перейдем к импорту информации о товарах (таб­ли­ца Product), которая поступила к  нам в  формате CSV. Сам процесс загрузки будет таким же, как и в предыдущих примерах, так что мы не будем его повторять. Как видно на рис. 4.13, после импорта данных в столбце ProductKey появились ошибочные значения. Таб­ли­ца Product насчитывает 607 записей, информация о чем присутствует в строке состояния слева. Обратите внимание, что в  нашем случае ошибки присутствуют непосредственно в  данных, загруженных в окно предварительного просмотра. В других случаях они могут не проявляться до момента загрузки данных в модель. Давайте прокрутим строки вниз и узнаем, где начинаются ошибки. Оказывается, первая ошибка в столбце ProductKey возникла сразу за строкой со значением 226. Щелкнем по ячейке с ошибкой, чтобы прочитать сообщение.

Получение данных из распространенных источников данных    145

Рис. 4.12    Извлечение данных из файла TSV

Более пристальный взгляд на данные позволил выявить в  загруженном наборе и другие проблемы. Например, в той же строке в столбце ProductAlter­ nateKey стоит дата. Также столбец ProductSubcategoryKey обладает явно неправильным типом данных. Причина этого очевидна – в этом столбце вдруг тоже появилась дата, хотя предполагается, что должны быть только числовые значения. И хотя иногда мы можем просто удалить ошибки, в  нашем случае они возникли в явно значимых строках – просто оказались перепутаны столбцы. Все это показано на рис. 4.13. Давайте присмотримся к данным более внимательно. Мы имеем дело с небольшим набором данных из 607 строк, так что можно открыть наш файл CSV в любом текстовом редакторе вроде Notepad++. ПРИМЕЧАНИЕ  Notepad++ можно загрузить по адресу https://notepad-plus-plus.org/ downloads.

В Notepad++ можно нажать на кнопку Отображать все символы (Show All Characters). Теперь давайте найдем строку, в которой значение поля ProductKey равно 226. Что ж, понятно, что произошло. По какой-то причине специальные символы возврата каретки (carriage return – CR) и перевода строки (line feed – LF) были введены прямо внутри текста.

146  Получение данных из различных источников

Неправильный тип данных

Щелкните здесь, чтобы увидеть ошибку

Количество строк в таблице Product

Даты не в нужных столбцах

Сообщение об ошибке

Рис. 4.13  Ошибки при загрузке данных из файла CSV

Если посмотреть на содержимое файла внимательнее, можно обнаружить, что и  в  поле EnglishProductDescription встречаются специальные символы. Эти ошибки могут появляться, например, если оператор при вводе названия товара в своей программе нажал на клавишу Enter. В результате данные в таком виде и сохраняются в файле CSV. Подобные ошибки могут появляться в любых столбцах текстового типа. Другие ошибки, показанные на рис. 4.14, могут быть не столь очевидными, в том числе из-за того, что они не приводят к возникновению ошибочных значений при загрузке данных в редактор Power Query. Но эти ошибки вполне могут проявиться в дальнейшем при работе с загруженными данными.

Режим отображения всех символов

Символы возврата каретки и перевода строки внутри текста

Строка с ошибками

Строка с ошибками

Символ перевода строки внутри текста

Строка с ошибками

Рис. 4.14  Проблемный файл Product.csv, открытый в Notepad++

Получение данных из распространенных источников данных    147

И хотя мы нашли конкретный источник проблемы, она может появиться и в других частях файла, где обнаружить ее будет очень проблематично. Самый простой способ изжить проблему на корню – внести изменения в источник данных. Но в нашем случае мы утратили к нему доступ. Таким образом, будем решать ее в слое Po­wer Query. Первой мыслью может быть замена всех последовательностей символов "(CR)(LF)" на пустую строку. Но проблема в том, что эти символы служат для перевода строки. Так что нельзя просто взять и заменить их на пустые строки, проблему это не решит. К счастью, в  нашем случае обнаружилось простое решение. Дело в  том, что перед всеми сочетаниями символов перевода строки (как "(CR)(LF)", так и "(LF)") стоит пробел. Так что перед загрузкой данных мы должны внести небольшие изменения в текст файла. Ну хорошо, мы исправим это в нашем файле, а что делать, если эта проблема появится в других файлах? В главе 3 мы обсуждали, как создать настраиваемую функцию, и здесь вам пригодятся эти знания. Давайте создадим функцию со следующим алгоритмом. 1. Принять путь к файлу в виде текста. 2. Открыть файл как текст. 3. Заменить все вхождения символов " (CR)(LF)" (с ведущим пробелом) на пустую строку (""). 4. Применительно к  полученному результату выполнить замену всех вхождений символов " (LF)" (с ведущим пробелом) на пустую строку (""). 5. Преобразовать текст в двоичный формат. 6. Открыть результат предыдущего шага в виде CSV. 7. Повысить заголовки. 8. Изменить типы данных столбцов. Этой инструкции достаточно, чтобы написать настраиваемую функцию следующего вида: // fnTextCleaner = (FilePath as text) as table => let Source = File.Contents(FilePath), GetText = Text.FromBinary(Source), ReplaceCarriageReturn = Text.Replace(GetText, " #(cr,lf)",""), ReplaceLineBreaks = Text.Replace(ReplaceCarriageReturn, "#(lf)", ""), TextToBinary = Text.ToBinary(ReplaceLineBreaks), #"Imported CSV" = Csv.Document(TextToBinary,[Delimiter=",", Columns=25, Encoding=1252, QuoteStyle=QuoteStyle.None]), #"Promoted Headers" = Table.PromoteHeaders(#"Imported CSV", [PromoteAllScalars=true]), #"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"ProductKey", Int64.Type}, {"ProductAlternateKey", type text}, {"ProductSubcategoryKey", type number}, {"WeightUnitMeasureCode", type text}, {"SizeUnitMeasureCode", type text}, {"EnglishProductName", type text}, {"StandardCost", type text}, {"FinishedGoodsFlag", type logical}, {"Color", type text}, {"SafetyStockLevel", Int64.Type}, {"ReorderPoint", Int64.Type}, {"ListPrice", type text}, {"Size", type text}, {"SizeRange", type text}, {"Weight", type text}, {"DaysToManufacture", Int64.Type}, {"ProductLine", type text}, {"DealerPrice", type text}, {"Class", type text}, {"Style", type text}, {"ModelName", type text}, {"EnglishDescription", type text}, {"StartDate", type datetime}, {"EndDate", type datetime}, {"Status", type text}}) in #"Changed Type"

148    Получение данных из различных источников Для создания настраиваемой функции сначала необходимо было создать пустой запрос, открыть расширенный редактор и вставить код. После этого мы переименовали запрос в fnTextCleaner. Теперь можно вызвать созданную функцию, передав ей путь к файлу Product.csv, в котором необходимо устранить проблемы. Для этого сделайте следующее. 1. Выберите на панели запросов функцию fnTextCleaner. 2. Введите в поле путь к файлу Product.csv. 3. Нажмите на кнопку Вызвать (Invoke). 4. В результате будет создан новый запрос с именем Вызванная функция (Invoked Function). 5. Переименуйте запрос в Product. Эти шаги показаны на рис. 4.15.

Рис. 4.15    Вызов функции fnTextCleaner для внесения изменений в данные из файла Product.csv

Как видно на рис. 4.15, теперь в нашем запросе 606 строк, что соответствует истине.

Excel Файлы Excel остаются одними из самых популярных источников данных для Po­wer BI. Для Excel существует полноценный коннектор, так что подключаться к  файлам этого формата не представляет никакого труда. При этом работать с файлами Excel в качестве источников данных бывает далеко

Получение данных из распространенных источников данных    149

не всегда просто. Зачастую в файлах Excel формулы в ячейках ссылаются на другие таб­ли­цы, столбцы и строки с других рабочих листов или даже книг. При работе с такими файлами могут возникать ошибки, вызванные этими формулами. Также файлы Excel могут содержать сводные таб­ли­цы со множеством измерений. В то же время Po­wer BI следует реляционным принципам построе­ ния моделей данных, основанных на таб­ли­цах, состоящих из столбцов, что не всегда сочетается с обработкой многомерных сводных таб­лиц. Еще одной распространенной проблемой при работе с файлами Excel являются объединенные ячейки, приводящие к появлению отсутствующих значений в Po­wer BI. Есть и другие сложности при работе с этим форматом файлов. В данном разделе мы рассмотрим ситуацию с содержащейся в файле Excel сводной таблицей. В  примере мы будем использовать файл Yearly Product Category Sales.xlsx, содержание которого показано на рис. 4.16.

Рис. 4.16    Продажи по годам и категориям товаров в Excel

Наша цель – загрузить данные из показанной на рис. 4.16 сводной таб­ли­цы в Po­wer BI. Сделайте следующее. 1. В редакторе Po­wer Query нажмите на кнопку Создать источник (New Source). 2. Выберите вариант Excel. 3. Перейдите в папку с файлом Excel и выделите его. 4. Нажмите на кнопку Открыть (Open). 5. Выберите лист Yearly Product Category Sales. 6. Нажмите на кнопку OK. Приведенные выше шаги схематически показаны на рис. 4.17.

150    Получение данных из различных источников

Рис. 4.17    Получение данных из Excel

В результате Po­wer BI создаст сразу несколько шагов. Давайте присмот­ римся к  ним, чтобы понять, как можно преобразовать сводную таб­ли­цу в обычную. Вот что нам нужно сделать:   шаг Измененный тип (Changed Type) не является обязательным, так что его можно удалить;   нужно избавиться от столбца Column8 и  строки 19, в  которых представлены итоги;   необходимо заполнить пропущенные значения в столбце Column1;   заголовки столбцов у нас попали в данные, так что нужно их повысить;   данные по годам должны быть представлены в виде столбца. Схематически эти действия показаны на рис. 4.18.

Получение данных из распространенных источников данных    151

Узаконить заголовки

Показать в столбце

Пропущенные значения

Надо удалить

Необязательно Надо удалить

Рис. 4.18    Преобразование сводной таб­ли­цы

Чтобы выполнить все эти действия, проделайте следующее. 7. Удалите шаг Измененный тип (Changed Type). 8. Выделите столбец Column8. 9. Нажмите на кнопку Удалить столбцы (Remove Columns) на вкладке Главная (Home), как показано на рис. 4.19.

Шаг изменения типа удален

Рис. 4.19    Удаление лишнего шага и столбца

Теперь займемся строкой с итогами. 10. Нажмите на кнопку Удалить строки (Remove Rows) на вкладке Главная (Home) и  нажмите на кнопку Удалить нижние строки (Remove Bottom Rows). 11. Введите единицу в поле Количество строк (Number of rows). 12. Нажмите на кнопку OK. Эти шаги показаны на рис. 4.20.

152    Получение данных из различных источников

Удалить строку Grand Total

Рис. 4.20    Удаление последней строки

Для заполнения пропущенных значений в столбце Column1 сделайте следующее. 13. Выделите столбец Column1. 14. Нажмите на выпадающую кнопку Заполнить (Fill) на вкладке Преобразование (Transform) и выберите пункт Вниз (Down), как показано на рис. 4.21.

Рис. 4.21    Заполнение пропущенных значений

Получение данных из распространенных источников данных    153

Теперь повысим заголовки. Нам нужно, чтобы столбцы назывались Cate­ gory и Subcategory, года также станут именами колонок. 15. Нажмите на кнопку Использовать первую строку в  качестве заголовков (Use First Row as Headers) на вкладке Главная (Home), как показано на рис. 4.22. Обратите внимание, как заполнились значения в первом столбце.

Пропущенные значения заполнены

Рис. 4.22    Использование первой строки в качестве заголовков

Теперь нам необходимо перенести годы из заголовков в столбец. Но сначала давайте избавимся от необязательного шага Измененный тип (Changed Type), который был создан при выполнении последнего действия автоматически. Далее мы отменим свертывание столбцов. 16. Удалите шаг Измененный тип (Changed Type), нажав на крестик слева от его имени. 17. Выделите все столбцы с годами с использованием клавиши Ctrl. ПРИМЕЧАНИЕ  Вы можете отметить диапазон столбцов, выделив первый из них, зажав клавишу Shift и  выбрав последний. В  результате все столбцы между ними будут выделены.

18. Щелкните правой кнопкой мыши по заголовку любого из выделенных столбцов и  выберите пункт Отменить свертывание столбцов (Unpivot Columns), как показано на рис. 4.23.

154    Получение данных из различных источников Выбор нескольких столбцов

Нажмите, чтобы удалить шаг

Рис. 4.23    Удаление ненужного шага и отмена свертывания столбцов

Теперь выполним заключительные шаги. 19. Переименуйте столбец Атрибут (Attribute) в Year, а столбец Значение (Value) – в Sales. 20. Выделите все столбцы для изменения их типов. 21. Нажмите на кнопку Определить тип данных (Detect Data Type) на вкладке Преобразование (Transform), как показано на рис. 4.24.

Рис. 4.24    Переименование столбцов и определение их типов

Получение данных из распространенных источников данных    155

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

Наборы данных Power BI Наборы данных Po­wer BI (Po­wer BI datasets) очень популярны в  командной работе. При создании модели данных в  Po­wer BI Desktop и  ее публикации в рабочей области службы Po­wer BI она превращается в набор данных, размещенный в службе. После этого можно предоставить доступ к созданному набору данных коллегам, что очень облегчает совместную работу в рамках объемных проектов. Разработчики моделей данных создают и  публикуют их в службе, а проектировщики отчетов используют доступные им наборы данных для создания визуальных представлений. ПРИМЕЧАНИЕ  Наборы данных Po­wer BI недоступны в  бесплатной лицензии Po­ wer BI.

К наборам данных Po­wer BI можно подключаться в реальном времени (connect live) непосредственно из Po­wer BI Desktop, – в этом случае Po­wer BI Desktop превращается в инструмент визуализации в чистом виде. Это означает, что вы не сможете использовать редактор Po­wer Query и вносить изменения в модель данных. Причина в том, что семантическая модель в этом случае содержится в самом наборе данных. Таким образом, при необходимости чтото изменить в модели данных необходимо будет обращаться к разработчику модели с просьбой применить изменение к набору данных. ПРИМЕЧАНИЕ  Далее в этой главе мы будем обсуждать разные режимы подключения к данным.

При подключении к набору данных в реальном времени допускается создавать меры уровня отчета непосредственно в Po­wer BI Desktop. Эти меры не вносят изменения в модель данных, а доступны исключительно из соответствующего отчета. Можно получить доступ к этим мерам и из других отчетов набора данных. Ниже показан алгоритм подключения к набору данных Po­wer BI. 1. Нажмите на кнопку Получить данные (Get data) на вкладке Главная (Home). 2. Перейдите в раздел Po­wer Platform. 3. Выберите пункт Наборы данных Po­wer BI (Po­wer BI datasets). 4. Нажмите не кнопку Подключить (Connect), как показано на рис. 4.25.

156    Получение данных из различных источников

Рис. 4.25    Подключение к набору данных Po­wer BI

Также подключиться к набору данных Po­wer BI можно, нажав на кнопку Наборы данных Po­wer BI (Po­wer BI datasets), вынесенную в группу Данные (Data) на вкладке Главная (Home), как показано на рис. 4.26.

Рис. 4.26    Кнопка Наборы данных Po­wer BI

Получение данных из распространенных источников данных    157

5. Выберите нужный набор данных для подключения. 6. Нажмите на кнопку Создать (Create), как на рис. 4.27.

Рис. 4.27    Выбор доступного для подключения набора данных

При подключении к набору данных в режиме реального времени в Po­wer BI Desktop будут введены следующие ограничения:   все инструменты в группе Данные (Data) на вкладке Главная (Home) будут недоступны;   кнопка Преобразование данных (Transform data), открывающая редактор Po­wer Query, также будет неактивна;   на вкладке Моделирование (Modeling) все инструменты будут недоступны, за исключением двух: Создать меру (New measure) и Быстрая мера (Quick measure). С  их помощью можно создавать меры уровня отчета;   на левой панели исчезнет вкладка Данные (Data), останутся только вкладки Отчет (Report) и Модель (Modeling). Далее в этом разделе мы поговорим о последней более подробно. На рис. 4.28 показаны изменения интерфейса Po­wer BI Desktop после подключения к набору данных Po­wer BI.

158    Получение данных из различных источников

Вкладка Данные исчезла

Рис. 4.28    Элементы управления Po­wer BI Desktop после подключения к набору данных Po­wer BI

Как видно на рис.  4.28, вкладка Модель на левой панели по-прежнему доступна. Щелкнув по ней, можно посмотреть все таб­ли­цы в модели данных и связи между ними, что очень удобно для понимания концепции данных. На рис. 4.29 показана вкладка Модель.

Рис. 4.29    Модель данных подключенного набора данных Po­wer BI

Вы также можете создавать новые макеты (layout) на основе модели данных, как показано на рис. 4.30.

Получение данных из распространенных источников данных    159

Нажмите для создания нового слоя

Рис. 4.30    Создание макетов в модели данных

Также стоит упомянуть, что у вас будет доступ к наборам данных только в тех рабочих областях, куда вас пригласили. Кроме того, вы должны обладать одной из следующих ролей: администратор (Admin), член (Member) или участник (Contributor).

Потоки данных Power BI Поток данных Po­wer BI (Po­wer BI dataflow) представляет собой облачную версию Po­wer Query в службе Po­wer BI и открывает безграничные возможности для преобразования данных в рамках компании. В потоке очень удобно реализовывать процессы трансформации данных, к которым впоследствии можно дать доступ коллегам в компании. Это позволяет повторно использовать существующие наработки и  повысить эффективность рабочих процессов. В Po­wer BI для потоков данных предусмотрен отдельный коннектор. ПРИМЕЧАНИЕ  В данный момент подключение к потокам данных в режиме Direct­ Query находится на стадии публичного предварительного просмотра и  доступно только применительно к  потокам данных, созданным в  рабочих областях с  поддержкой премиумных лицензий.

160    Получение данных из различных источников Если в вашем распоряжении есть поток данных, подключиться к нему не составит труда. Для этого достаточно сделать следующее. 1. Нажать на выпадающую кнопку Получить данные (Get data). 2. Выбрать пункт Потоки данных Po­wer BI (Po­wer BI dataflows). 3. В открывшемся окне Навигатор (Navigation) вы увидите список доступных источников. Раскройте нужную рабочую область. 4. Раскройте модель потока данных. 5. Выберите таб­ли­цу. 6. Нажмите на кнопку Загрузить (Load). Эти шаги схематически показаны на рис. 4.31.

Рис. 4.31    Импорт из потока данных Po­wer BI

Нажимая на кнопку загрузки, вы запускаете процесс импорта данных из потока в модель данных Po­wer BI.

SQL Server SQL Server – это один из самых распространенных источников данных для Po­wer BI. При подключении к  SQL Server можно выбрать между импортом данных в модель и соединением с базой данных напрямую с использованием режима DirectQuery. Режимы подключения мы обсудим подробно далее в этой главе. Следующий алгоритм действий, схематически показанный на рис. 4.32, позволит вам подключиться к данным, находящимся в SQL Server. 1. Нажмите на кнопку SQL Server на вкладке Главная (Home). 2. Введите имя сервера в поле Сервер (Server). 3. В зависимости от ваших требований вы можете ввести имя базы данных для подключения в поле База данных (Database).

Получение данных из распространенных источников данных    161

4. Выберите один из двух режимов подключения к данным: Импорт (Import) или DirectQuery. 5. Также вы можете ввести скрипты на языке Transact-SQL (T-SQL), которые будут выполняться при подключении. Для этого необходимо раскрыть область Расширенные параметры (Advanced options). 6. Оставьте установленным флажок Включить столбцы отношений (Include relationship columns). Вы можете снять его, если не хотите, чтобы Po­wer BI определял при подключении к источнику данных связанные таб­ли­цы. 7. Не устанавливайте флажок Навигация с помощью полной иерархии (Navigate using full hierarchy). Эта опция служит для использования навигации на основе схем баз данных. 8. Если в настройках вашего экземпляра SQL Server установлен высокий уровень доступности (High Availability – HA), активируйте опцию Включить поддержку отработки отказа SQL Server (Enable SQL Server Failover support). В противном случае оставьте ее неактивной. 9. Нажмите на кнопку OK. На рис. 4.32 показаны перечисленные шаги графически.

Рис. 4.32    Получение данных из SQL Server

10. Отметьте галочками нужные вам таб­ли­цы, как показано на рис. 4.33. 11. Нажмите на кнопку Выбор связанных таб­лиц (Select Related Tables). 12. В зависимости от требований вы можете нажать либо на кнопку Загрузить (Load), чтобы немедленно импортировать выбранные таб­ли­цы

162    Получение данных из различных источников в модель данных, либо на кнопку Преобразовать данные (Transform Data), что позволит открыть редактор Po­wer Query. Эти шаги показаны на рис. 4.33.

Рис. 4.33    Выбор таб­лиц и связанных с ними объектов в окне навигатора ПРИМЕЧАНИЕ  Ручной ввод запроса на языке T-SQL (пункт 5 на рис. 4.32) сделает невозможным выполнение свертывания запросов (query folding) в Po­wer Query, что потенциально может негативно сказаться на производительности во время обновления данных. Подробнее об этом мы поговорим в главе 7.

SQL Server Analysis Services и Azure Analysis Services В рамках SQL Server Analysis Services (SSAS) используются технологии хранения многомерных и  табличных моделей данных. Azure Analysis Services (AAS)  – это версия табличной модели данных в  Azure, реализованная по

Получение данных из распространенных источников данных    163

принципу «платформа как услуга» (Platform as a Service – PaaS). Существует отдельный коннектор для подключения к  обоим типам локальных версий SSAS, а также коннектор с поддержкой AAS. При подключении из Po­wer BI Desktop к SSAS или AAS вам будет доступно два типа соединения: Подключение в реальном времени (Connect Live) и Импорт (Import). В первом случае Po­wer BI Desktop превратится, по сути, в инструмент создания отчетов. При выборе этого типа подключения семантическая модель размещается в локальных версиях SSAS или AAS. Используя режим подключения в реальном времени к SSAS Tabular или AAS, вы сможете создавать меры уровня отчета. Эти меры будут доступны только в соответствующем отчете, но не в лежащей в его основе семантической модели. ПРИМЕЧАНИЕ  Рекомендуется не использовать режим импорта при подключении к SSAS или AAS. Создавая модель данных в Po­wer BI, мы фактически создаем семантическую модель. А импорт данных из SSAS и AAS в Po­wer BI, по сути, приводит к  созданию новой семантической модели поверх существующей, что не слишком хорошо. Таким образом, лучше избегать использования режима импорта, если у вас нет на то действительно веских причин. В декабре 2020 года компания Microsoft анонсировала выход новой версии составных моделей, в которой можно переводить подключение в реальном времени к AAS или набору данных Po­wer BI в режиме DirectQuery. Так что теперь мы можем подключаться к нескольким экземплярам AAS или наборам данных Po­wer BI для создания единого источника достоверной информации на семантическом слое в Po­wer BI. С составными моделями данных мы познакомимся в главе 12.

SSAS многомерная/табличная Для подключения к SSAS выполните следующие шаги. 1. Нажмите на выпадающую кнопку Получить данные (Get data). 2. Выберите пункт Analysis Services. 3. Введите имя сервера в поле Сервер (Server). 4. При необходимости введите имя базы данных для подключения в поле База данных (Database). 5. Выберите один из двух режимов подключения к данным: Импорт (Import) или Подключение в реальном времени (Connect live). В режиме импорта вы можете ввести запрос на языке MDX или DAX для получения набора данных. 6. Нажмите на кнопку OK. Эти шаги показаны на рис. 4.34. 7. Выберите модель (в  вашем случае имя модели может отличаться от того, что показано на рис. 4.35). 8. Нажмите на кнопку OK, как показано на рис. 4.35.

164    Получение данных из различных источников

Рис. 4.34    Подключение к SSAS

Рис. 4.35    Подключение к модели

Получение данных из распространенных источников данных    165

AAS Подключение к экземпляру AAS почти не отличается от подключения к SSAS. Единственным отличием является то, что мы используем для этого отдельный коннектор База данных Azure Analysis Services (Azure Analysis Services database), скрывающийся в папке Azure инструмента Получить данные (Get Data), что видно на рис. 4.36. Второй раз все те же шаги мы расписывать не будем.

Рис. 4.36    Подключение к табличной модели AAS

Также есть возможность загрузить файл PBIX с подключением к нужной модели AAS непосредственно с портала Azure. Для этого нужно сделать следующее. 1. Подключившись к порталу Azure, откройте свой экземпляр AAS и нажмите на кнопку Overview. 2. Найдите модель, к которой хотите подключиться, и нажмите на кнопку с тремя точками справа от нее. 3. Нажмите на кнопку Open in Po­wer BI Desktop, как показано на рис. 4.37.

166    Получение данных из различных источников

Рис. 4.37    Открытие модели AAS в Po­wer BI Desktop из Azure

В результате на ваш компьютер будет загружен файл PBIX. В Po­wer BI Desktop можно будет открыть файл с подключением в режиме реального времени к нашей модели AAS.

Канал OData Еще одним распространенным источником данных для Po­wer BI в компаниях является Open Data Protocol (OData). Многие веб-службы поддерживают формат канала OData (OData feed), что и делает его таким популярным в бизнессреде. Если в качестве источника данных, совместимого с протоколом OData, выступает CRM- или ERP-система, в модели данных наверняка будет большое количество таб­лиц и столбцов. Мы встречались с достаточно широкими таб­ ли­ца­ми, в которых было больше 200 столбцов. Понятно, что в таких случаях очень важно хорошо понимать исходную модель данных. Давайте рассмот­ рим подключение к модели на примере Microsoft Project Web App (PWA). 1. В Po­wer BI Desktop нажмите на выпадающую кнопку Получить данные (Get data). 2. Выберите пункт Канал OData (OData feed). 3. Введите в поле URL-адрес ссылку на ваш PWA. Вид ссылки должен быть следующим: https://Your_Tenant.sharepoint.com/sites/pwa/_api/Projectdata. 4. Нажмите на кнопку OK.

Получение данных из распространенных источников данных    167

5. Выберите раздел Учетная запись в организации (Organizational account). 6. Нажмите на кнопку Вход (Sign in) и введите свои учетные данные. 7. Нажмите на кнопку Подключение (Connect). Эти шаги показаны на рис. 4.38.

Рис. 4.38    Подключение к Microsoft Project Web App (PWA) с помощью канала OData

8. Выберите нужные вам таб­ли­цы в источнике данных. Мы выберем таб­ ли­цу Project. 9. Нажмите на кнопку Загрузить (Load) или Преобразовать данные (Transform Data), как показано на рис. 4.39. Мы выбрали второй вариант. На рис. 4.40 видно, что в загруженной таб­ли­це присутствует 131 столбец. Нам могут быть не нужны все столбцы в модели данных. Здесь важно очень хорошо понимать структуру базы данных PWA. Если вы не обладаете такими знаниями, стоит заручиться помощью экспертов, которые помогут определить список столбцов, которые необходимо импортировать в модель данных. Всегда желательно иметь понимание о том, сколько таб­лиц находится в источнике данных, а также сколько в них столбцов и строк. В главе 7 мы предложим настраиваемую функцию fnODataFeedAnalysis, предназначенную как раз для этих целей.

168    Получение данных из различных источников

Рис. 4.39    Выбор таб­лиц на панели навигатора

Рис. 4.40    Таб­ли­ца Project из источника данных PWA в редакторе Po­wer Query

Сертификаты источников данных    169

Сертификаты источников данных Хотя тема, связанная с  сертификацией источников данных (data source certification), больше относится к  администрированию Po­wer BI, вы должны понимать, что из себя представляют эти сертификаты и как они влияют на процесс моделирования данных. Сертификация источников данных напрямую связана с  качеством и  достоверностью информации, содержащейся в этих источниках. В данном разделе мы не будем детально обсуждать процесс сертификации, поскольку эта тема выходит за рамки данной книги. Мы лишь отметим, что в результате сертификации источники данных могут быть поделены на три (или более) категории. В разных компаниях используется своя терминология относительно качества данных. Мы для примера введем следующие названия категорий источников: Bronze, Silver и Gold, – основываясь на качестве хранящихся в них данных. В своей организации вы можете применять другую систему именования.

Bronze Источники данных со статусом Bronze содержат непроверенные данные, которые никогда не подвергались тщательному контролю. И хотя в них может находиться ценная для нас информация, также здесь могут быть дубликаты и даже некорректные данные. Еще одним фактором, который необходимо учитывать, помимо качества данных, является место, где они хранятся, например в файлах Excel или в личном хранилище OneDrive или Google Drive. Данные из источников со статусом Bronze обычно копируются или извлекаются из интернета или других систем-источников. К  примеру, один из сотрудников провел определенный анализ данных. При этом данные могут быть не слишком хорошо структурированы, чтобы их можно было импортировать в  аналитические инструменты, такие как Po­wer BI. Кроме того, исходная информация может храниться в  недоверенных источниках, находящихся вне контроля организации, таких как персональное хранилище OneDrive. Наиболее распространенные источники данных, попадающие в эту категорию, – это файлы Excel, CSV и TXT. Многие компании в своей работе запрещают доступ к источникам с таким статусом по причине непроверенности данных и большой вероятности появления в них ошибок. Затраты на обслуживание, сопровождение и анализ данных, полученных из источников со статусом Bronze, обычно достаточно высоки. Если вам так или иначе приходится работать с такими данными, заранее запланируйте расходы на их преобразование и обслуживание.

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

170    Получение данных из различных источников в аналитические инструменты для их углубленного разбора. В то же время подготовка таких данных может занимать немало времени, поскольку зачастую изначально они находятся не в лучшем виде. В качестве примеров источников данных со статусом Silver можно привести транзакционные хранилища с использованием разных технологий и местоположения. Обычно это транзакционные базы данных на основе SQL Server или Oracle, а также файлы Excel, располагающиеся в хранилищах SharePoint или OneDrive для бизнеса. В  некоторых организациях к  источникам со статусом Silver относят и свои хранилища данных, так что здесь вопрос еще в определении границ.

Gold/Platinum Источники со статусами Gold или Platinum содержат полностью проверенные и достоверные данные с минимальными проблемами в плане качества. При этом информация хранится в предельно подходящем виде для анализа и  построения отчетов в  аналитических системах вроде Po­wer BI. Обычно к этим категориям относятся семантические модели SSAS, как многомерные, так и табличные, SAP Business Warehouse (SAP BW), хранилища данных и т. д. Имея дело с источниками Gold/Platinum, мы можем быть практически уверены в достоверности и корректности данных. Кроме того, в плане подготовки и  моделирования данных нам потребуется абсолютный минимум усилий.

Режимы подключения к данным При извлечении данных из источника мы можем воспользоваться следующими тремя режимами подключения:   импорт;   DirectQuery;   подключение в реальном времени (Connect Live). Любой запрос, извлекающий данные из одного или нескольких источников в  редакторе Po­wer Query, может использовать режим подключения импорт или DirectQuery. При использовании режима реального времени модель данных Po­wer BI не может одновременно подключаться к нескольким экземплярам SSAS, AAS или наборам данных Po­wer BI. ПРИМЕЧАНИЕ  Компания Microsoft выпустила предварительную новую версию составных моделей данных в  декабре 2020 года, позволяющую подключаться при помощи режима DirectQuery более чем к одному экземпляру AAS или наборам данных Po­wer BI. В данный момент эта версия не поддерживает SSAS Tabular. Более подробно о составных моделях данных мы будем говорить в главе 12.

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

Режимы подключения к данным    171

Импорт Импорт (Import) представляет собой наиболее распространенный режим подключения в Po­wer BI Desktop. Для многих типов источников данных это единственный способ подключения, например для файлов. Как понятно из названия, при использовании этого режима подключения данные физически импортируются из источника в модель данных Po­wer BI, меняя при этом свою форму. При этом они могут быть предварительно преобразованы при помощи инструмента Po­wer Query. Обновлять данные можно вручную в Po­wer BI Desktop или в автоматическом режиме после их публикации в службе Po­wer BI.

Применение По большей части импортирование применяется для консолидации данных из нескольких источников в одной модели. Кроме того, этот тип подключения позволяет нам создать семантическую модель непосредственно в  Po­wer BI. При этом можно несколько раз в день обновлять всю информацию. Но все эти возможности предполагают и определенные ограничения, описанные ниже.

Ограничения Подключение к наборам данных Po­wer BI в режиме импорта связано со следующими ограничениями в отношении объема данных и возможностей автоматического обновления в зависимости от используемого типа лицензии. Объем информации в расчете на один набор данных:   1 Гб на набор данных для бесплатной лицензии и плана Pro;   100 Гб для наборов данных, опубликованных в рабочей области с лицензией Premium Per User (PPU);   100 Гб для наборов данных, опубликованных в рабочей области с лицензией Premium. В зависимости от типа лицензии существуют следующие ограничения на обновление данных:   до одного раза в день для бесплатной лицензии;   до восьми раз в день для лицензии Po­wer BI Pro;   до 48 раз в день для лицензий Po­wer BI Premium и PPU. С учетом всех перечисленных ограничений этот режим подключения может оказаться не лучшим выбором при необходимости анализировать данные в реальном или близком к реальному времени.

DirectQuery Тогда как самым распространенным режимом подключения в Po­wer BI является именно импорт, для некоторых источников более приемлемым является метод прямого подключения к данным или DirectQuery. При использовании этого режима подключения физический перенос данных в модель не происходит. Вместо этого между Po­wer BI и источником данных, который может

172    Получение данных из различных источников быть представлен реляционной базой данных, происходит обмен параллельными запросами для извлечения данных.

Применение Режим подключения DirectQuery идеально подходит для сценариев с обработкой данных в реальном времени с минимальной задержкой и хранением данных в реляционной базе. Также этот режим уместно использовать в случаях, когда 1 Гб исходных данных оказывается недостаточно в связи с большим объемом данных в источнике. И хотя в режиме DirectQuery данные не импортируются в модель, вы по-прежнему можете создавать модели данных с определенными ограничениями.

Ограничения Если говорить в целом, запросы в режиме подключения DirectQuery выполняются не столь эффективно по сравнению с аналогичными запросами в режиме импорта. Дело в том, что в  режиме DirectQuery множество запросов отправляются в источник данных параллельно, и если источник физически неспособен или плохо настроен для обработки такого количества обращений, могут возникать большие задержки. В  этом случае модель данных, а  с  ней и отчеты могут давать сбои. Если в  режиме DirectQuery используются достаточно сложные запросы, можно ожидать проблем с производительностью. Еще одно неудобство этого режима связано с  одновременным доступом нескольких пользователей к одному отчету – зачастую это приводит к запуску еще большего количества параллельных запросов к источнику. Также применительно к  режиму подключения DirectQuery действуют определенные ограничения в языке DAX и Po­wer Query, что делает его еще более сложным в использовании. Помимо этого, в режиме DirectQuery есть лимит на извлечение 1 млн строк для облачных источников данных и 4 Мб в расчете на строку для локальных источников, или максимальный объем данных 16 Мб для всего визуального представления при наличии лицензии Po­wer BI Pro. Максимальное ограничение на строку для лицензии Po­wer BI Premium может быть задано администратором. В связи со всем перечисленным выше мы советуем тщательно подумать и все проанализировать, прежде чем останавливать свой выбор на режиме подключения DirectQuery.

Подключение в режиме реального времени Режим реального времени (Connect Live) используется при подключении отчетов к источнику в SSAS, включая AAS, как многомерному, так и табличному. Этот режим может быть рекомендован для построения системы отчетов в BI-решении уровня организации. При его использовании вся бизнес-логика аккумулируется в  семантической модели и  становится доступной для ин-

Режимы хранения данных    173

струментов создания отчетов в рамках экземпляра SSAS, к которому выполняется подключение. Исходные данные при этом остаются на стороне SSAS, так что нам нет необходимости импортировать их в Po­wer BI.

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

Ограничения При подключениии к экземпляру SSAS в реальном времени Po­wer BI, по сути, превращается в инструмент создания отчетов. Это означает, что возможности моделирования данных и использования Po­wer Query в этом режиме вам будут недоступны. В то же время вы сможете видеть модель данных, с которой работаете, в Po­wer BI Desktop. Более того, при подключении в реальном времени к табличной модели SSAS вам будет доступна возможность создания мер уровня отчета (для многомерной модели SSAS это неприменимо). Однако, хотя модель данных вы видеть сможете, вносить изменения в нее вам, увы, будет не разрешено. К  тому же, поскольку весь процесс обработки данных будет выполняться в экземпляре SSAS, подключение к источнику должно быть достаточно надежным для обслуживания множества параллельных запросов.

Режимы хранения данных В предыдущем разделе мы обсуждали режимы подключения к данным в запросах с точки зрения Po­wer Query. Сейчас же мы поговорим о различных режимах хранения (storage mode) данных, применяющихся к таблицам после их загрузки в модель данных или подключения к ним в источнике данных. У всех таб­лиц в модели данных Po­wer BI есть свойство режима хранения, показывающее, были данные кешированы или нет. Всего насчитывается три режима хранения данных:   Импорт (Import): означает, что данные из таб­ли­цы кешированы в памяти. Таким образом, все запросы, направленные на извлечение данных из таб­лиц с этим режимом хранения, будут пользоваться данными из кеша;   DirectQuery: данные не кешируются, и все запросы отправляются непосредственно в источник данных;   Двойной (Dual): данные из таб­лиц с таким режимом хранения могут извлекаться как из сохраненного кеша, так и  из источника – в зависимости от запроса. К  примеру, при настройке агрегации исходные данные могут браться из кеша или напрямую из источника – это определяется уровнем детализации. Подробнее об агрегациях мы будем говорить в главе 9.

174    Получение данных из различных источников ПРИМЕЧАНИЕ  Все ограничения режима подключения DirectQuery, о  которых мы говорили в предыдущем разделе, действуют и применительно к таблицам с двойным режимом хранения.

Посмотреть и изменить режим хранения таб­ли­цы можно на вкладке Модель (Model) в левой панели Po­wer BI Desktop следующим образом. 1. Откройте вкладку Модель. 2. Выберите таб­ли­цу на панели Поля (Fields). 3. Раскройте раздел Дополнительно (Advanced) на панели Свойства (Properties). 4. Выберите нужный вариант в  выпадающем списке Режим хранения (Storage mode). Эти шаги схематически показаны на рис. 4.41.

Рис. 4.41    Изменение режима хранения для таб­ли­цы

Режимы хранения наборов данных    175 ПРИМЕЧАНИЕ  Невозможно изменить режим хранения таб­ли­цы с Импорт на Direct­ Query или Двойной.

В этом разделе мы перечислили доступные режимы хранения таб­лиц и  описали их особенности. В  следующем разделе мы подробно поговорим о режимах хранения наборов данных.

Режимы хранения наборов данных Как вы уже, наверное, догадались, под режимом хранения набора данных (dataset storage mode) подразумевается, хранятся данные из этого набора в кеше или нет. Всего существует три режима хранения набора данных:   Импорт (Import): в этом случае все данные из набора содержатся в сохраненном кеше в  памяти, а  для всех таб­лиц из набора установлен аналогичный режим хранения;   DirectQuery: данные в этом случае в памяти не кешируются, а все таб­ ли­цы из набора находятся в режиме хранения DirectQuery;   Составной (Composite – Mixed): при таком режиме хранения часть данных из набора кешируется в памяти, а другая часть остается в источнике. Режимы хранения для таб­лиц в наборе могут быть как Импорт, так и DirectQuery или Двойной. Чтобы посмотреть и изменить режим хранения данных в наборе в Po­wer BI Desktop, нужно обратить внимание на правую часть строки состояния, как показано на рис. 4.42. Как видите, вы можете щелкнуть по этой надписи, чтобы изменить режим хранения. Заметьте также, что режим хранения Импорт не может быть изменен. О режиме хранения наборов данных стоит задуматься на самом старте планирования проекта. Необходимо убедиться, что выбранный режим будет отвечать всем требованиям бизнес-сценария. Кроме того, эта настройка напрямую влияет на архитектуру вашего решения в  Po­wer BI. Например, если в вашей прикладной области недопустимы большие задержки, а данные должны анализироваться в реальном времени, возможно, вашим выбором должен стать режим хранения DirectQuery.

176    Получение данных из различных источников

Рис. 4.42    Определение режима хранения набора данных в Po­wer BI Desktop

Рис. 4.43    Изменение режима хранения набора данных

Заключение    177

Заключение В этой главе мы научились работать с  наиболее распространенными источниками данных, поддерживаемыми Po­wer BI, такими как папки, файлы CSV, Excel, наборы и  потоки данных Po­wer BI, SQL Server, SSAS и  каналы OData. Вместе с тем мы рассмотрели некоторые сценарии, касающиеся доступа к этим источникам данных. Далее мы поговорили про сертификацию источников данных и выяснили, почему так важно понимать, с каким именно статусом источника мы имеем дело в тот или иной момент. После этого мы коснулись режимов подключения и  хранения, а  также поговорили о  различиях между ними. Стоит лишний раз упомянуть о  важности понимания этих нюансов, поскольку они напрямую влияют на вопросы моделирования данных и архитектуру вашего решения Po­wer BI в целом. В следующей главе мы обсудим основные шаги первоначальной обработки данных в редакторе Po­wer Query на примере конкретных сценариев.

Глава

5 Общие шаги по подготовке данных

В предыдущей главе мы перечислили некоторые популярные источники данных для Po­wer BI. Мы также поговорили о сертификации источников и различиях между режимами подключения, хранения и наборов данных. В этой главе речь пойдет о  распространенных действиях, которые зачастую приходится выполнять с данными в процессе их подготовки к анализу, включая манипуляции с таб­ли­ца­ми, текстом, датами и часовыми поясами. Как и всегда, мы рассмотрим все перечисленные темы на реальных примерах, которые помогут вам лучше понять процесс предварительной подготовки данных. В редакторе Po­wer Query все часто используемые операции с данными сосредоточены на трех следующих вкладках. 1. Главная (Home). Здесь собраны основные операции, такие как создание нового запроса, создание и управление параметрами запросов и выполнение распространенных действий вроде разделения и группировки столбцов и прочего. 2. Преобразование (Transform). На этой вкладке представлены вспомогательные функции по преобразованию данных, которые можно выполнить при помощи интерфейса пользователя. 3. Добавление столбца (Add Column). Здесь собраны операции, совмес­ тимые с созданием нового столбца в таб­ли­це. Перечисленные вкладки со всеми инструментами представлены на рис. 5.1.

Рис. 5.1    Функционал по подготовке данных в редакторе Po­wer Query

Изменение типов данных    179

В следующих нескольких разделах мы рассмотрим действия по манипулированию данными, доступные из этих и других вкладок редактора Po­wer Query. На протяжении этой главы мы будем использовать файл Chapter 5, Common Data Preparation Steps.pbix, если не указано иное. Для применения этого файла откройте его в  Po­wer BI Desktop и  измените значения следующих параметров:   Adventure Works DW Excel path;   Internet Sales in Time Excel path;   Approved Subcategories List path. Оригинальные файлы, использующиеся в книге, можно загрузить с GitHub по адресу https://github.com/PacktPublishing/Expert-Data-Modeling-with-Po­wer-BI. В Po­wer BI вы можете получать данные из самых разных источников в различных форматах. Вне зависимости от формата конкретного источника вы должны ставить во главу угла качество используемых данных. Бывают случаи, когда вы работаете с уже преобразованными данными, но в большинстве ситуаций вам необходимо выполнять всю подготовительную обработку данных самостоятельно, перед тем как загрузить их в модель. Часто исходная информация содержится в файлах Excel или CSV в сведенном формате. Ваша задача состоит в том, чтобы выполнить все необходимые манипуляции с полученными данными и подготовить их для дальнейшего анализа. В этой главе мы рассмотрим наиболее популярные действия по преобразованию исходных данных, включая следующие:   изменение типов данных;   разделение столбцов по разделителю;   объединение столбцов;   создание настраиваемого столбца;   создание столбца из примеров;   создание дубликата столбца;   фильтрация строк;   группирование данных;   добавление запросов;   объединение запросов;   создание дубликата запроса и ссылки на запрос;   замена значений;   извлечение чисел из текста;   работа с датой, временем и часовыми поясами. Давайте пройдемся по этим операциям и обсудим их более подробно.

Изменение типов данных Преобразование типов данных  – одна из самых распространенных задач, которые выполняются при подготовке данных в  Po­wer Query. Правильно установить типы данных (data type) для столбцов очень важно, но зачастую с  этим возникают сложности. Одно из удобств Po­wer BI состоит в том, что этот инструмент может автоматически преобразовывать типы данных, если

180    Общие шаги по подготовке данных ему это позволить. И хотя зачастую это бывает действительно удобно, иног­да такой автоматизм становится причиной серьезных проблем, которые бывает трудно обнаружить. Здесь очень важно пояснить, как именно Po­wer BI определяет типы данных столбцов. А делает он это на основании сведений о первых нескольких сотнях строк. Часто в том, что далеко не все данные берутся в расчет, и кроется причина возникающих в дальнейшем ошибок. В большинстве случаев мы имеем дело с преобразованием типов данных в табличных значениях. Используем ли мы интерфейс редактора Po­wer Query или пишем код вручную, в любом случае мы прибегаем к помощи следующей функции: Table.TransformColumnTypes(Table as table, TypeTransformations as list, optional Culture as nullable text)

В качестве параметров функция Table.TransformColumnTypes() принимает следующие аргументы:   Table – обычно это результат выполнения предыдущего шага;   TypeTransformations – список имен столбцов с  соответствующими им типами данных. Мы уже касались темы типов данных в главе 3. В табл. 5.1 представлены все существующие типы с указанием двух вариантов синтаксиса их записи. Таб­ли­ца 5.1. Типы данных в Po­wer Query, их представление и синтаксис Тип данных Binary Date Datetime datetimezone Duration List Logical Null Number

Record Text Time Type Function Table Any None

Представление типа Binary / Двоичный Date / Дата Date/Time / Дата и время Date/Time/Zone / Дата, время и часовой пояс Duration / Продолжительность List / Список Logical / Истина/Ложь Null Whole Number / Целое число Decimal Number / Десятичное число Fixed Decimal Number / Десятичное число с фиксированной запятой Percentage / Процент Record / Запись Text / Текст Time / Время Type Function Table Any None

Синтаксис 1 type binary type date type datetime type datetimezone

Синтаксис 2 Binary.Type Date.Type DateTime.Type DateTimeZone.Type

type duration type list type logical type null – type number

Duration.Type List.Type Logical.Type Null.Type Int64.Type Int64.Type



Currency.Type

– type record type text type time type type type function type table type any type none

Percentage.Type Record.Type Text.Type Time.Type Type.Type Function.Type Table.Type Any.Type None.Type

Изменение типов данных    181

Давайте присмотримся к  этой таб­ли­це внимательнее. Работать будем с файлом Chapter 5, Common Data Preparation Steps.pbix. 1. Откройте редактор Po­wer Query и выберите таб­ли­цу Geography на панели Запросы (Queries). 2. При создании файла с примерами мы не устанавливали для столбцов типы данных. Так что последний шаг, который вы видите, – Измененный тип (Changed Type) – был создан автоматически, и типы данных были определены без нашего участия. 3. Прокрутите область предварительного просмотра данных вправо. Возможно, вы увидите под заголовком столбца PostCode красную линию качества данных, указывающую на наличие ошибок в первой тысяче представленных строк (если ошибок нет, вы можете смоделировать их, установив для столбца числовой тип данных. – Прим. перев.) 4. Прокрутите вниз, чтобы найти ошибочные значения. Щелкните по ячейке с ошибкой, чтобы увидеть текст сообщения. 5. Как видно на рис.  5.2, причиной ошибки является неправильно выбранный тип данных.

Рис. 5.2    Ошибки вызваны неверным преобразованием типов

Исправить эти ошибки, как вы понимаете, довольно просто. Для этого надо установить для столбца PostCode тип данных Текст (Text), лучше отражающий содержимое колонки. 6. Щелкните по иконке с типом данных слева от заголовка столбца. 7. Выберите тип Текст (Text). 8. В диалоговом окне Изменить тип столбца (Change Data Type) нажмите на кнопку Заменить текущее (Replace current), как показано на рис. 5.3.

182    Общие шаги по подготовке данных

Рис. 5.3    Изменение типа данных столбца

В результате ни одного нового шага добавлено не будет, а  проблема исчезнет. На рис.  5.4 видно, что в  области распределения столбцов никаких ошибок нет.

Рис. 5.4    Ошибка преобразования типа данных устранена

В предыдущем примере мы очень быстро обнаружили и исправили ошибку. Но зачастую ошибки, связанные с неправильным выбором типа данных, найти бывает не так легко, даже если автоматическое преобразование типов не используется. Давайте продолжим использовать наш файл с  примером и загрузим его содержимое в модель данных, заранее установив правильный тип данных для столбца PostCode. Разместим на странице отчета визуальный элемент с  таблицей и  перенесем в нее столбец Date из одноименной таб­ли­цы. В результате возникнет

Изменение типов данных    183

ошибка при расчете меры Internet Sales. Как видно по рис. 5.5, продажи оказались некорректно разбиты по датам.

Рис. 5.5    Мера Internet Sales рассчитана только для одного элемента поля Date

В таких случаях могут начать появляться ошибки в самых разных визуализациях. Нам нужно разобраться, что пошло не так, и исправить возникшую проблему. Вот что для этого нужно сделать:   откройте на левой панели вкладку Модель, чтобы проверить корректность образованных связей;   обратите внимание на наличие отсутствующих значений в связанных столбцах;   убедитесь, что для связанных столбцов выбраны правильные типы данных. Мы знаем, что между таб­ли­ца­ми Date и Internet Sales существует связь по столбцам Date и OrderDateTime, показанная на рис. 5.6.

Рис. 5.6    Связь между таб­ли­ца­ми Date и Internet Sales

В обоих столбцах присутствуют даты, но, как видно по рис. 5.7, в таб­ли­це Date они прописаны без учета времени, а в таб­ли­це Internet Sales – с учетом.

184    Общие шаги по подготовке данных

Рис. 5.7    Содержимое столбцов Date из таб­ли­цы Date и OrderDateTime из таб­ли­цы Internet Sales

И правда, для столбца Date в календаре у нас задан тип данных Дата (Date), а  для столбца OrderDateTime в  таб­ли­це Internet Sales – Дата и  время (DateTime). С  точки зрения модели данных эти типы совместимы. При этом в  столбце OrderDateTime содержится время, тогда как в  календаре его нет. В  результате связь корректно отработала только по тем датам из столбца OrderDateTime, в которых время установлено на полночь. Убедиться в этом очень просто. Давайте выведем на страницу отчета три таб­ли­цы:   таб­ли­ца 1 (Table 1): с выводом столбца Date из таб­ли­цы Date;   таб­ли­ца 2 (Table 2): с выводом столбца OrderDateTime из таб­ли­цы Internet Sales;   таб­ли­ца 3 (Table 3): с выводом столбца Date из таб­ли­цы Date и OrderDateTime из таб­ли­цы Internet Sales.

Изменение типов данных    185

Эти таб­ли­цы показаны на рис. 5.8.

Рис. 5.8    Столбцы Date и OrderDateTime не совпадают

Как видите, нашлось лишь одно совпадение между содержимым двух этих столбцов. Теперь, когда мы разобрались с сутью проблемы, нужно ее решить, изменив тип данных в столбце OrderDateTime с Дата и время (DateTime) на Дата (Date). 1. Откройте редактор Po­wer Query и  выберите таб­ли­цу Internet Sales на панели Запросы (Queries). 2. Щелкните правой кнопкой мыши по заголовку столбца OrderDateTime. 3. Выберите тип Дата (Date) в подменю Изменить тип (Change Type). 4. В диалоговом окне Изменить тип столбца (Change Data Type) нажмите на кнопку Заменить текущее (Replace current), как показано на рис. 5.9.

Рис. 5.9    Изменение типа данных в столбце

Теперь переключитесь на вкладку Отчет. Как видно по рис. 5.10, проблема исчезла.

186    Общие шаги по подготовке данных

Рис. 5.10    После изменения типа данных столбца OrderDateTime проблема решилась

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

Разделение столбцов по разделителю Одной из самых распространенных операций в процессе подготовки данных для анализа является разделение столбцов по разделителю (split column by delimiter). Например, часто требуется разбивать на составляющие полные имена в  столбце. Давайте рассмотрим пример. В  предыдущем разделе мы преобразовали столбце OrderDateTime к типу данных Дата. А что, если нам понадобится анализировать продажи как по датам, так и по времени? Можно реализовать эту потребность разными способами, например так:   создайте новую таб­ли­цу Time либо с использованием языка DAX (как мы показывали в главе 2), либо в редакторе Po­wer Query;   разделите столбец OrderDateTime на два: Date и Time;   создайте связь между таб­ли­ца­ми Time и Internet Sales. Мы подробно рассмотрим только второй пункт этого сценария, состоящий в разделении столбца. Но ранее мы уже преобразовали тип данных столбца OrderDateTime в Дата, так что для начала нам необходимо вернуть все, как было. После этого можно приступать к новой задаче. 1. Откройте редактор Po­wer Query и  выберите таб­ли­цу Internet Sales на панели Запросы. 2. Выделите столбец OrderDateTime. 3. Нажмите на выпадающую кнопку Разделить столбец (Split Column) на вкладке Преобразование (Transform). Это откроет вам доступ к семи разным вариантам разделения столбца. 4. Выберите пункт По разделителю (By Delimiter).

Разделение столбцов по разделителю    187

5. Укажите Пробел (Space) в выпадающем списке Выберите или введите разделитель (Select or enter delimiter). 6. Установите переключатель в положение Самый левый разделитель (Left-most delimiter). 7. Нажмите на кнопку OK. Эти действия схематически показаны на рис. 5.11.

Рис. 5.11    Разделение столбца по разделителю

В результате в списке шагов добавится новый шаг Разделить столбец по разделителю (Split Column by Delimiter), а колонка OrderDateTime окажется разбита на две с именами по умолчанию OrderDateTime.1 и OrderDateTime.2, что видно по рис. 5.12.

Рис. 5.12    Разделение столбца привело к образованию двух новых колонок с именами OrderDateTime.1 и OrderDateTime.2

188    Общие шаги по подготовке данных Мы могли бы переименовать эти столбцы в отдельном шаге. СОВЕТ  Избегайте создания лишних шагов в Po­wer Query. Чем больше шагов, тем больше времени будет уходить на обработку данных и тем большая нагрузка ляжет на движок Po­wer Query.

С учетом сказанного мы не будем переименовывать созданные столбцы в отдельном шаге. Вместо этого мы поправим код существующего шага Разделить столбец по разделителю. Есть два способа сделать это. Первый способ заключается в  изменении кода запроса в  расширенном редакторе, как показано на рис. 5.13. Для этого сделайте следующее. 1. Нажмите на кнопку Расширенный редактор (Advanced Editor) на вкладке Главная (Home). 2. Найдите в тексте шаг с именем #»Разделить столбец по разделителю» (#»Split Column by Delimiter»). 3. Прокрутите окно вправо. 4. Измените в тексте имена столбцов на нужные. 5. Нажмите на кнопку Готово (Done).

Рис. 5.13    Изменение имен столбцов после разделения в расширенном редакторе

Второй способ состоит в  изменении имен столбцов непосредственно в  строке формул (Formula Bar), как показано на рис.  5.14. Для этого нужно сделать следующее. 1. Выделите шаг Разделить столбец по разделителю (Split Column by Delimiter) в списке примененных шагов.

Объединение столбцов    189

2. Щелкните по строке формул, чтобы раскрыть ее. 3. Измените имена столбцов в тексте запроса. 4. Нажмите на кнопку подтверждения с галочкой слева от строки формул.

Рис. 5.14    Изменение имен столбцов после разделения в строке формул

Последнее, что нужно сделать, – это изменить тип данных столбца OrderDate на Дата (Date), а столбца OrderTime – на Время (Time).

Объединение столбцов Довольно типичной операцией на этапе подготовки данных для анализа является объединение столбцов. Встречается немало ситуаций, в которых нам просто необходимо совместить содержимое разных колонок для образования новых качественных данных. Например, это могут быть те же составные имена людей или объединение адресов, разбитых на несколько столбцов. Еще один распространенный случай относится к  созданию уникального идентификатора в  отдельном столбце. Давайте продолжим работать с  файлом Chapter 5, Common Data Preparation Steps.pbix. 1. Откройте редактор Po­wer Query и выберите таб­ли­цу Customer на панели Запросы. 2. Выделите столбцы First Name, Middle Name и Last Name. 3. Щелкните правой кнопкой мыши по заголовку любого из выбранных столбцов и  выберите пункт Объединить столбцы (Merge Columns). Также можно нажать на кнопку Объединить столбцы (Merge Co­ lumns) на вкладке Преобразование (Transform), показанную желтым на рис. 5.15. 4. Выберите Пробел (Space) в выпадающем списке Разделитель (Separator). 5. В поле Новое имя столбца введите Full Name. 6. Нажмите на кнопку OK.

190    Общие шаги по подготовке данных

Рис. 5.15    Объединение столбцов

После объединения трех столбцов в один область предпросмотра должна выглядеть так, как на рис. 5.16.

Рис. 5.16    Три колонки объединились в одну с именем Full Name

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

Создание настраиваемого столбца    191

использования алгоритмов машинного обучения (machine learning – ML) и искусственного интеллекта (artificial intelligence – AI). Вы легко можете придумать огромное множество сценариев для создания новых столбцов в наборе данных. Используем ли мы интерфейс Po­wer Query или пишем выражения на языке M вручную, функция, на которой основывается добавление столбцов, выглядит так: Table.AddColumn(Table as table, NewColumnName as text, ColumnGenerator as function, optional ColumnType as nullable type)

Давайте посмотрим, что передается в функцию Table.AddColumn() в качест­ ве параметров:   Table: входное табличное значение, которое может быть как результатом выполнения предыдущего шага, так и любым другим запросом, предлагающим табличный вывод;   NewColumnName: здесь все понятно из названия  – это имя нового столбца;   ColumnGenerator: выражения, используемые для создания нового столбца;   ColumnType: используется для задания типа создаваемой колонки. Это необязательный параметр, но очень полезный. Подробнее мы расскажем о нем далее в этом разделе. Продолжим работать с  файлом Chapter 5, Common Data Preparation Steps. pbix и представим, что нам необходимо добавить в таб­ли­цу Customer новый столбец для хранения информации о том, превышает ли его годовой доход величину среднего годового дохода клиентов. Для начала нам нужно вычислить этот показатель. У  нас в таб­ли­це есть поле с  именем YearlyIncome, в котором хранится годовой доход клиента. Для вычисления среднего годового дохода нам необходимо сослаться на столбец YearlyIncome и применить агрегацию. Сослаться на столбец внутри текущей таб­ли­цы можно, указав имя шага и имя столбца. В нашем случае выражение будет выглядеть следующим образом: List.Average(#"Merged Columns"[YearlyIncome])

В этом выражении #"Merged Columns" является именем предыдущего шага. В результате ссылки на целый столбец мы получаем список представленных в нем значений, а функция List.Average() позволяет вычислить среднее значение в списке. В нашем случае это будет итог по столбцу YearlyIncome. Давайте добавим новый столбец следующим образом. 1. Откройте редактор Po­wer Query и выберите таб­ли­цу Customer на панели Запросы. 2. Нажмите на кнопку Настраиваемый столбец (Custom Column) на вкладке Добавление столбца (Add Column). 3. Введите имя нового столбца. 4. Введите выражение, показанное ниже: if [YearlyIncome] 30 then [Description] else "", each Text.Start([Description], 30) & "...", Replacer. ReplaceText,{"Description"})

Результат замены значений показан на рис. 5.42.

Рис. 5.42    Обрезание описаний товаров длиннее 30 символов

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

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

Извлечение чисел из текста    213

  Flat Number – поле на основании столбца AddressLine1, в котором будет содержаться номер дома;   Street Name – оставшаяся часть адреса. Как видно на рис. 5.43, номер дома может располагаться в самых разных частях адреса, так что отслеживание смены текста на цифры и обратно здесь не сработает.

Рис. 5.43    Номера домов в адресах

Чтобы получить номера домов, мы воспользуемся операцией извлечения чисел из текста. Для этого подойдет функция Text.Select(Text as nullable text, SelectChars as any). Выполните следующие действия. 1. Нажмите на кнопку Настраиваемый столбец (Custom Column) на вкладке Добавление столбца (Add Column). 2. Введите Flat Number в поле Имя нового столбца (New column name). 3. В поле с формулой введите следующий текст: Text.Select([AddressLine1], {"0".."9"})

4. Нажмите на кнопку OK. На рис. 5.44 показаны приведенные выше действия. Далее мы используем ту же функцию для получения названия улицы из адреса. 1. Снова нажмите на кнопку Настраиваемый столбец (Custom Column) на вкладке Добавление столбца (Add Column). 2. Введите Street Name в поле Имя нового столбца (New column name). 3. На этот раз в поле с формулой используйте следующий текст: Text.Select([AddressLine1], {"a".."z", "A".."Z", " ", "."})

4. Нажмите на кнопку OK.

214    Общие шаги по подготовке данных

Рис. 5.44    Извлечение номера дома из адреса

Это позволит оставить из всего адреса все буквы, включая заглавные, пробелы и точки, а все остальные символы будут удалены. На рис. 5.45 показан результат.

Рис. 5.45    Номера домов и названия улиц по адресам

Работа с датой, временем и часовыми поясами    215

Работа с датой, временем и часовыми поясами Создание и  поддержка значений с датами, временем и  часовыми поясами в Po­wer Query выполняются довольно просто и интуитивно понятно. Достаточно освоить три функции, которые мы приведем ниже. Первая из них служит для создания значений с датами: #date(year as number, month as number, day as number)

Чтобы значение содержало не только дату, но и время, можно воспользоваться следующей функцией: #datetime(year as number, month as number, day as number, hour as number, minute as number, second as

Ну а для поддержки часовых поясов подойдет функция, показанная ниже: #datetimezone(year as number, month as number, day as number, hour as number, minute as number, second as number, offsetHours as number, offsetMinutes as number)

Следующая формула сгенерирует запись, состоящую из полей Date, DateTime и DateTimeZone: let Source = [Date = #date(2020, 8, 9) , DateTime = #datetime(2020, 8, 9, 17, 0, 0) , DateTimeZone = #datetimezone(2020, 8, 9, 17, 0, 0, 12, 0)] in Source

Результат выполнения этой формулы показан на рис. 5.46.

Рис. 5.46    Создание значений с датой, временем и часовым поясом

216    Общие шаги по подготовке данных Но в  большинстве случаев приходится решать более сложные задачи с учас­тием даты и времени. Например, зачастую необходимо извлекать дату из ключевых идентификаторов дат и наоборот. ПРИМЕЧАНИЕ  Ключевой идентификатор дат являет собой целочисленное представление значений на основе дат. В таком виде даты часто представлены в хранилищах данных с  целью экономии места на диске и  в  памяти. Например, целочисленное значение 20200809 можно интерпретировать как 2020/08/09 (9 августа 2020 го­да). Таким образом, если ваши исходные данные берут свои истоки в хранилище данных, вполне вероятно, что даты в ваших таб­ли­цах будут представлены именно в таком виде.

Давайте на примере таб­ли­цы Internet Sales попробуем преобразовать даты из столбца OrderDate в соответствующие им целочисленные ключевые идентификаторы. Для этого добавим в таб­ли­цу новый столбец. 1. Откройте таб­ли­цу Internet Sales и добавьте в нее новый настраиваемый столбец. 2. Назовите столбец OrderDateKey. 3. Введите следующую формулу: Int64.From(Date.ToText([OrderDate], "yyyyMMdd"))

4. Нажмите на кнопку OK. 5. Добавьте Int64.Type в  качестве необязательного операнда функции Table.AddColumn(), как показано на рис. 5.47.

Рис. 5.47    Добавление ключевого идентификатора дат в виде новой колонки

Еще одной распространенной задачей является отображение дат со сдвигом по часовым поясам. Давайте рассмотрим такой пример.

Работа с датой, временем и часовыми поясами    217

В таб­ли­це Internet Sales Date Time даты в  столбце OrderDateTime хранятся с  часовым поясом Новой Зеландии. Нам необходимо добавить столбец, в котором даты будут представлены в соответствии с форматом Всемирного координированного времени (Universal Time Coordinate – UTC). Для этого мы добавим новый настраиваемый столбец в таб­ли­цу и в формуле вложим функцию DateTimeZone.ToUtc(DateTimeZone as nullable datetimezone) в привычную нам функцию Table.AddColumn, как показано ниже: Table.AddColumn(#"Changed Type", "OrderDateTimeUTC", each DateTimeZone.ToUtc(DateTimeZone. From([OrderDateTime])), DateTimeZone.Type)

На рис. 5.48 показано содержимое новой колонки.

Рис. 5.48    Настраиваемый столбец OrderDateTimeUTC

Обратите внимание на подсвеченные значения на рис. 5.48. Разница между этими двумя столбцами составляет 13 часов. Если присмотреться внимательнее, можно заметить, что в столбце OrderDateTimeUTC учтены настройки перехода на летнее время моего компьютера. Поскольку я живу в Новой Зеландии, разница между моим местным временем и UTC может составлять 12 или 13 часов в зависимости от даты. При использовании функции DateTimeZone.ToUtc() без указания часового пояса значение будет сконвертировано в тип Дата, время и часовой пояс (DateTimeZone), после чего функция DateTimeZone.ToUtc() переведет значения в часовой пояс UTC. А что, если даты у нас хранятся в формате UTC, а нам нужно выводить их с  учетом местного времени? Для этого можно воспользоваться функцией DateTimeZone.ToLocal(dateTimeZone as nullable datetimezone). Например, чтобы добавить колонку с отображением местного времени на основании значений в формате UTC, можно применить следующую формулу: Table.AddColumn(#"Added OrderDateTimeUTC", "OrderDateTimeLocal", each DateTimeZone. ToLocal([OrderDateTimeUTC]), type datetimezone)

Результат выполнения этой формулы показан на рис. 5.49.

218    Общие шаги по подготовке данных

Рис. 5.49    Отображение даты и времени в формате UTC с учетом местного часового пояса

Заключение В этой главе мы поговорили о том, какие действия зачастую приходится выполнять на этапе предварительной подготовки данных для анализа. Мы научились разделять значения в столбцах, объединять колонки, добавлять настраиваемые столбцы и фильтровать данные в строках. Мы также затронули тему группировки данных с целью создания агрегированных таб­лиц. Кроме того, была освещена важная тема добавления и объединения запросов. Наконец, мы сделали первые шаги на пути освоения работы с датой и временем. Полученных знаний будет достаточно, чтобы уверенно двинуться дальше. В следующей главе мы займемся подготовкой модели данных в виде звезды в редакторе Po­wer Query.

Глава

6 Подготовка данных в Power Query для схемы «звезда»

В предыдущей главе вы освоили наиболее распространенные операции, выполняющиеся на этапе предварительной подготовки данных, включая преобразование типов данных, разделение столбцов, их объединение, добавление настраиваемого столбца и фильтрацию строк. Вы также узнали, как можно создавать агрегированные таб­ли­цы при помощи группировки данных, добавлять таб­ли­цы друг к другу по вертикали и объединять их по горизонтали. В этой главе мы воспользуемся всеми приобретенными в предыдущих главах навыками и научимся создавать схему «звезда» (Star Schema) в редакторе Po­wer Query. Моделирование в  Po­wer BI начинается именно с  подготовки схемы «звезда». Мы будем использовать плоские данные из файла Chapter 6, Sales Data.xlsx. Рассмотрим сценарий, с  которым очень часто приходится сталкиваться на практике, – у нас есть набор файлов с данными, импортированными из некого источника, и нам необходимо построить на их основании отчет для ответа на бизнес-вопросы. Здесь нам пригодятся навыки построе­ ния «звезды» на базе плоских таб­лиц. В этой главе мы подробно рассмотрим следующие темы:   выявление измерений и фактов;   создание таб­лиц измерений;   создание таб­лиц фактов.

Выявление измерений и фактов Говоря о  схеме «звезда», мы автоматически подразумеваем присутствие в модели данных таб­лиц измерений и фактов. Традиционно мы храним все числовые показатели в таб­ли­цах фактов, а описательные – в измерениях. Но это не значит, что все без исключения числовые значения в модели должны находиться в  таб­ли­цах фактов. Яркий пример – поле с  ценой товара (Unit Price). Если нам необходимо производить какие-то расчеты на основании этой цены, вполне вероятно, что ей найдется место в  таб­ли­це фактов. Но

220    Подготовка данных в Power Query для схемы «звезда» в случаях, когда мы собираемся использовать цену в качестве фильтра или основания для группировки данных, этому полю более комфортно будет в таб­ли­це измерения. Разработка схемы «звезда» невозможна без хорошего понимания имеющихся у  вас данных. В  этой главе мы будем преобразовывать в  «звезду» данные из файла Chapter 6, Sales Data.xlsx. Как мы уже упомянули, для создания схемы в виде звезды нам необходимо пристально приглядеться к имеющимся у нас данным и определиться с тем, какие из них должны относиться к измерениям, а какие – к фактам. И в этом разделе мы как раз этим и займемся. Попутно мы обсудим, стоит ли выделять измерения в отдельные таб­ли­цы, и если да, то почему. Перед тем как продолжить, давайте взглянем на наши данные в редакторе Po­wer Query, как показано на рис. 6.1. Ранее мы уже научились импортировать данные из файлов Excel, так что здесь мы не будем на этом останавливаться.

Рис. 6.1    Данные из файла Chapter 6, Sales Data.xlsx, загруженные в редактор Po­wer Query

Глядя на загруженные данные, мы должны задуматься о следующих вещах:   количество таб­лиц в источнике данных;   связи между существующими таб­ли­ца­ми;   наименьшая требуемая гранулярность полей с датой и временем. Это ключевые вопросы, на которые нам надо ответить на этапе исследования данных. Ответы на эти вопросы помогут нам оценить масштаб и сложность предстоящих работ. В следующих разделах мы более детально разберем поставленные вопросы.

Количество таблиц в источнике данных Наш исходный файл Excel содержит два рабочих листа, данные с  которых будут транслированы в  две базовые таб­ли­цы (base table) Sales и  Customer

Выявление измерений и фактов    221

в редакторе Po­wer Query. Мы использовали слово базовые, поскольку намереваемся извлечь из таб­лиц измерения и факты, а не загружать их в модель данных в исходном виде. На этом этапе также необходимо определиться со связями между таб­ли­ца­ми, которые обязательно должны присутствовать в модели данных. Имена таб­лиц показаны на рис. 6.2.

Рис. 6.2    Файл Excel с двумя листами, представляющими две базовые таб­ли­цы в редакторе Po­wer Query

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

Связи между существующими таблицами Давайте перечислим все столбцы в представленных базовых таб­ли­цах:   Sales: SalesTerritoryRegion, SalesTerritoryCountry, SalesTerritoryGroup, CustomerKey, SalesOrderNumber, SalesOrderLineNumber, OrderQuantity, ExtendedAmount, TotalProductCost, SalesAmount, TaxAmt, Freight, OrderDate, DueDate, ShipDate, Product, ProductCategory, ProductSubcategory, Currency;   Customer: CustomerKey, Title, FirstName, MiddleName, LastName, NameStyle, BirthDate, MaritalStatus, Suffix, Gender, EmailAddress, YearlyIncome, TotalChildren, NumberChildrenAtHome, EnglishEducation, EnglishOccupation, HouseOwnerFlag, NumberCarsOwned, AddressLine1, AddressLine2, Phone, DateFirstPurchase, CommuteDistance, City, StateProvinceCode, State­ ProvinceName, CountryRegionCode, EnglishCountryRegionName, Postal­Code, SalesRegion, SalesCountry, SalesContinent. Глядя на эти таб­ли­цы, мы понимаем, что поле CustomerKey является очевидным ключом для связи между ними. Но есть еще кое-что, что можно отметить:   связь по географическим данным с такими полями, как Region, Country, Territory Group, State/Province, City, Address и Postal Code;   связь по данным о товарах с  полями Product Category, Product Subcategory и Product;   связь по данным о продажах: Sales Order и Sales Order Line;   связь по полям с датой и временем: Order Date, Due Date и Ship Date.

222    Подготовка данных в Power Query для схемы «звезда»

Наименьшая требуемая гранулярность полей с датой и временем В большинстве реальных задач, если не во всех, нам необходимо анализировать данные в разрезе дат, времени или обоих измерений сразу. Рассмотрим последний вариант. Для начала нам необходимо выяснить, какой уровень детализации по дате и  времени будет удовлетворять нашим требованиям. Внимательно изучив данные, мы обнаружили, что обе таб­ли­цы – Sales и Customer – содержат поля с датами и временем. В таб­ли­це Sales присутствуют три столбца с типом данных Дата и время (DateTime), которые были определены в  редакторе Po­wer Query автоматически. Присмотревшись к  содержимому этих столбцов, мы обнаруживаем, что в столбцах DueDate и ShipDate временная составляющая представляет значение 12:00:00, а значит, тип данных для них должен быть установлен в Дата (Date), а не Дата и  время (DateTime). Единственная колонка, в  которой время имеет значение, – это OrderDate. На рис.  6.3 видно, что данные в  этом столбце хранятся с  детализацией до секунды.

Рис. 6.3    Колонки с датой и временем в таб­ли­це Sales

Итак, мы выяснили, что в  поле OrderDate данные представлены с  точ­ ностью до секунды. Позже, в разговоре с заказчиками, необходимо уточнить значимость этого факта. Теперь обратимся к таб­ли­це Customer. Здесь у нас есть два поля с типом Дата (Date) – BirthDate и DateFirstPurchase, – что видно по рис. 6.4. Нам нужно выяснить у заказчика, какая информация в отношении дат для него имеет значение. Вопросы, которые необходимо задать в этой связи:   будет ли он анализировать данные по дате рождения клиентов, т. е. по полю BirthDate?

Выявление измерений и фактов    223

  нужно ли хранить даты на других уровнях, таких как год, квартал, месяц и т. д.?   нужно ли анализировать данные по полю DateFirstPurchase?   необходимо ли показывать данные по полю DateFirstPurchase на различных уровнях детализации?

Рис. 6.4    Колонки с датами в базовой таб­ли­це Customer

В нашем вымышленном примере допустим, что заказчику нет нужды анализировать данные по дням рождения и датам первой покупки. Также мы выяснили, что в поле OrderDate из таб­ли­цы Sales нам достаточно детализации до дней и  минут. Поля DueDate и  ShipDate из таб­ли­цы Sales будут хранить данные в разрезе дней. Таким образом, нам понадобится создать измерение дат и измерение времени. Теперь необходимо определиться с другими измерениями, их гранулярностью и фактами.

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

224    Подготовка данных в Power Query для схемы «звезда»   на вопрос «что?» можно ответить товар, деталь, услуга и т. д.;   в ответе на вопрос «когда?» должно быть упомянуто, нужно ли и как именно учитывать даты и время с требуемой детализацией;   в качестве ответа на вопрос «где?» можно указать физическое расположение склада или хранилища, географические координаты и т. д. С помощью этих вопросов мы пытаемся понять, как устроен бизнес изнут­ ри и как сам он себя позиционирует. Предположим, мы провели несколько совещаний с заказчиком и выяснили, какие именно показатели необходимо анализировать. Среди числовых показателей мы выделили следующие:   объем продаж;   количество проданных товаров;   затраты (налоги, стоимость перевозки и т. д.). Анализировать данные нужно в показанных ниже разрезах:   география;   номера заказов;   товары;   валюта;   клиенты;   демография продаж;   даты на уровне дней;   время на уровне минут. Пришло время определяться с измерениями и фактами.

Выявление возможных измерений В поиске измерений мы должны обращать внимание в  первую очередь на описательные данные. Опираясь на информацию, полученную во время переговоров с заказчиком, можно предположить, что наши базовые таб­ли­цы Sales и Customer содержат в себе измерения, приведенные в табл. 6.1. Таб­ли­ца 6.1. Потенциальные измерения на основе базовых таб­лиц Измерение

Исходная Атрибуты измерения таб­ли­ца Geography Sales SalesTerritoryRegion, SalesTerritoryCountry, SalesTerritoryGroup Sales Order Sales SalesOrderNumber, SalesOrderLineNumber Product Sales ProductCategory, ProductSubcategory, Product Currency Sales Currency Customer Customer CustomerKey, Title, FirstName, MiddleName, LastName, NameStyle, BirthDate, MaritalStatus, Suffix, Gender, EmailAddress, YearlyIncome, TotalChildren, NumberChildrenAtHome, EnglishEducation, EnglishOccupation, HouseOwnerFlag, NumberCarsOwned, AddressLine1, AddressLine2, Phone, DateFirstPurchase, CommuteDistance Sales Demographic Customer City, StateProvinceCode, StateProvinceName, CountryRegionCode, EnglishCountryRegionName, PostalCode, SalesRegion, SalesCountry, SalesContinent

Выявление измерений и фактов    225

Выявление возможных фактов Для определения потенциальных фактов мы снова должны обратиться к результатам совещаний с заказчиком. Мы уже немного понимаем внутреннее устройство компании и знаем в общих чертах их требования. Давайте откроем редактор Po­wer Query и поищем колонки с числовым типом данных. Но не думайте, что все они автоматически будут приняты в качестве фактов. К выбору фактов необходимо подходить очень избирательно. В  наших данных мы видим единственного кандидата на эту роль, приведенного в табл. 6.2. Таб­ли­ца 6.2. Потенциальные факты на основе базовых таб­лиц Факт Sales

Исходная таб­ли­ца Атрибуты факта Sales OrderQuantity, ExtendedAmount, TotalProductCost, SalesAmount, TaxAmt, Freight

ПРИМЕЧАНИЕ  В реальных проектах выявление будущих измерений и фактов стоит производить после консультаций с  экспертом в  конкретной предметной области. Также заказчики часто предоставляют исходные файлы и просят на их основании создать аналитические отчеты.

Определившись с кандидатами на роль измерений и фактов, можно двигаться дальше в сторону схемы «звезда». Но перед этим необходимо выполнить некоторые важные действия. Как мы уже упоминали ранее, мы не собираемся загружать базовые таб­ ли­цы Sales и Customer в модель данных в их исходном виде. В связи с этим давайте отключим загрузку для этих таб­лиц, что показано на рис. 6.5. Как это сделать, мы подробно рассказывали в главе 1.

Таблицы выгружены

Рис. 6.5    Для таб­лиц Sales и Customer загрузка отключена

226    Подготовка данных в Power Query для схемы «звезда» Также нам нужно определиться с типами данных столбцов. Если шаг с изменением типов был автоматически добавлен в примененные шаги, необходимо проверить его на корректность определения типов. Если в настройках не установлена опция Никогда не определять типы и заголовки столбцов для неструктурированных источников (Never detect column types and headers for unstructured sources), Po­wer Query будет автоматически пытаться угадывать типы данных, что будет отражено в шаге Измененный тип (Changed Type) в каждой таб­ли­це. Эта настройка располагается в редакторе Query Editor (или Po­wer BI) в пункте Параметры и  настройки (Options and settings) ⇒ Параметры (Options) ⇒ Определение типов (Type Detection). Автоматическое определение типов может быть установлено в Po­wer Query как на уровне глобальных настроек, так и на уровне текущего файла. В первом случае необходимо выполнить следующие действия. 1. Перейдите на вкладку Файл (File). 2. В открывшемся меню выберите выпадающий пункт Параметры и настройки (Options and settings). 3. Выберите пункт Параметры (Options). 4. В разделе Глобальные (Global) откройте секцию Загрузка данных (Data Load). 5. Под заголовком Определение типов (Type Detection) вам будет предоставлен следующий выбор, как показано на рис. 6.6.

Рис. 6.6    Определение типов данных на глобальном уровне

Создание таблиц измерений    227

5.1. Всегда определять типы и заголовки столбцов для неструктурированных источников (Always detect column types and headers for unstructured sources). 5.2. Определять типы и заголовки столбцов для неструктурированных источников согласно параметрам каждого файла (Detect column types and headers for unstructured sources according to each file’s settings). 5.3. Никогда не определять типы и  заголовки столбцов для неструктурированных источников (Never detect column types and headers for unstructured sources). 6. Для определения типов на уровне файла выберите пункт Загрузка данных (Data Load) в разделе Текущий файл (Current File). 7. Установите или снимите флажок Определять типы и  заголовки столбцов для неструктурированных источников (Detect column types and headers for unstructured sources), как показано на рис. 6.7.

Рис. 6.7    Определение типов данных на уровне текущего файла

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

Создание таблиц измерений На данный момент у  вас уже должен быть загружен файл Chapter 6, Sales Data.xlsx в редактор Po­wer Query. Сейчас нам надо проанализировать наши измерения с точки зрения бизнеса и создать те из них, которые потребуются.

228    Подготовка данных в Power Query для схемы «звезда»

Geography Исходя из требований заказчика, мы поняли, что нам потребуется измерение, хранящее географические данные. В базовой таб­ли­це Sales присутствуют необходимые географические сведения. Мы можем создать отдельное измерение Geography на основе таб­ли­цы Sales. Но этого может оказаться недостаточно. Давайте еще раз взглянем на таб­ли­цу с  потенциальными измерениями и обратим внимание, что в таб­ли­це Customer также присутствуют поля, отражающие географические данные. Нам нужно найти сходства в  данных, чтобы объединить колонки из разных таб­лиц в одно измерение Geography. Использование инструмента распределения столбцов позволило нам понять, что столбец CustomerKey представляет собой первичный ключ (primary key) в таб­ли­це Customer, как показано на рис. 6.8.

Рис. 6.8    Определение первичного ключа в таб­ли­це

Описание и принципы работы инструмента распределения столбцов были приведены в главе 3. Итак, давайте присмотримся к характеристикам столбцов SalesContinent, SalesCountry и SalesRegion из таб­ли­цы Customer и столбцов SalesTerritoryGroup, SalesTerritoryCountry и SalesTerritoryRegion из таб­ли­цы Sales. Как видите, количество отдельных (distinct) значений в каждом из выбранных столбцов из таб­ли­цы Customers в точности совпадает с этим же показателем для соответствующих столбцов из таб­ли­цы Sales. Это показано на рис. 6.9. Выполните следующие действия, чтобы убедиться в  том, что содержимое столбцов SalesContinent, SalesCountry и SalesRegion из таб­ли­цы Customer и  Sales­TerritoryGroup, SalesTerritoryCountry и  SalesTerritoryRegion из таб­ли­цы Sales полностью совпадает. 1. Создайте ссылку на таб­ли­цу Customer. 2. Переименуйте созданную таб­ли­цу в CustomerGeoTest. 3. Отмените для этой таб­ли­цы загрузку в модель данных.

Создание таблиц измерений    229

4. Сохраните в таб­ли­це только колонки SalesContinent, SalesCountry и SalesRegion, воспользовавшись инструментом Удалить другие столбцы (Remove Other Columns). 5. Щелкните на иконке с  изображением таб­ли­цы слева от заголовков столбцов и в выпадающем списке выберите пункт Удалить дубликаты (Remove Duplicates). Эти шаги показаны на рис. 6.10.

Рис. 6.9    Сравнение характеристик распределения географических данных в таб­ли­цах Customer и Sales

Рис. 6.10    Создание ссылки на таб­ли­цу Customer и удаление дубликатов

230    Подготовка данных в Power Query для схемы «звезда» В результате мы получим таб­ли­цу, показанную на рис. 6.11.

Рис. 6.11    Результат создания ссылки на таб­ли­цу Customer и удаления дубликатов

Теперь необходимо проделать те же операции с целью удаления дубликатов в столбцах SalesTerritoryGroup, SalesTerritoryCountry и SalesTerritoryRegion в таб­ли­це Sales. На рис. 6.12 одна под другой показаны таб­ли­цы CustomerGeoTest и SalesGeoTest с удаленными повторами. Как видите, единственным отличием между таб­ли­ца­ми является их сортировка, что не имеет значения. В результате проведенного исследования мы можем сделать вывод о том, что нам нет никакой необходимости создавать измерение Geography, поскольку столбцы SalesTerritoryGroup, SalesTerritoryCountry и  SalesTerritoryRegion из таб­ли­цы Sales являются абсолютно избыточными в сравнении со столбцами SalesContinent, SalesCountry и SalesRegion из таб­ли­цы Customer, притом что колонки с  географическими сведениями в таб­ли­це Customer обеспечивают больший уровень детализации.

Sales Order В таб­ли­це Sales содержатся два столбца с описательными данными о заказах: SalesOrderNumber и SalesOrderLineNumber. Давайте зададим себе вопрос: зачем нам нужно измерение по этим столбцам? Взглянем на данные. 1. Измените профилирование столбцов таким образом, чтобы оно основывалось на всем наборе данных. О том, как это сделать, мы говорили в главе 3. 2. Посмотрите на данные о  распределении наших столбцов. В  столбце SalesOrderNumber находится 27 659 отдельных значений, а  в  столбце SalesOrderLineNumber – лишь восемь, что видно на рис. 6.13.

Создание таблиц измерений    231

Рис. 6.12    Сравнение содержимого таб­лиц CustomerGeoTest и SalesGeoTest

Рис. 6.13    Распределение столбцов показало большое количество неповторяющихся значений в колонке SalesOrderNumber

232    Подготовка данных в Power Query для схемы «звезда» Наличие большого количества отдельных значений в столбце SalesOrderNumber снижает потенциальную пользу от измерения Sales Order. Давайте поищем еще поводы не создавать его. Если объединить два столбца, можно узнать, какое количество строк будет в нашем измерении, если мы все-таки решим его создать. 3. Выделите столбцы SalesOrderNumber и SalesOrderLineNumber. 4. Щелкните правой кнопкой мыши по заголовку одного из столбцов и выберите пункт Объединить столбцы (Merge Columns). 5. В открывшемся диалоговом окне Объединить столбцы (Merge Co­ lumns) оставьте настройки по умолчанию и нажмите на кнопку OK, как показано на рис. 6.14.

Рис. 6.14    Объединение колонок SalesOrderNumber и SalesOrderLineNumber

Появится новый столбец с именем Сведено (Merged) с 60 398 отдельными и таким же количеством уникальных значений. Получается, что объединение столбцов SalesOrderNumber и SalesOrderLineNumber приводит к образованию первичного ключа в таб­ли­це Sales, что видно по рис.  6.15. Таким образом, даже если мы создадим отдельное измерение, мы получим в нем такое же количество строк, как и в таб­ли­це фактов. Кроме того, здесь трудно представить какие-то связи с другими измерениями. А значит, лучше оставить эти два столбца в составе таб­ли­цы Sales. Измерения такого вида не могут быть выделены из таб­ли­цы фактов из-за особенностей их содержимого. Они также не содержат дополнительных атрибутов и  связей с другими измерениями. Такие измерения именуются вырожденными (degenerate dimension). Давайте удалим созданный шаг Объединенные столбцы (Merged Column) на панели примененных шагов.

Создание таблиц измерений    233

Рис. 6.15    Результат объединения колонок

Product Таб­ли­ца Product содержит три описательных столбца и  идеально подходит на роль измерения. Мы можем создать измерение Product путем образования ссылки на таб­ли­цу Sales. После этого нужно будет удалить все столбцы, кроме Product, ProductSubcategory и ProductCategory, и избавиться от дубликатов. Также нам понадобится создать первичный ключ в виде нового столбца ProductKey. После этого останется только объединить таб­ли­цы Sales и Product на этапе создания таб­ли­цы фактов для получения ProductKey. А сейчас переименуем столбцы, чтобы они выглядели получше. Столбец ProductSubcategory мы переименуем в Product Subcategory, а ProductCategory – в Product Category. ПРИМЕЧАНИЕ  В дальнейшем мы будем не раз ссылаться на таб­ли­цу Sales, так что переименуем ее в Sales Base.

Теперь посмотрим, как реализовать наш план в редакторе Po­wer Query. 1. Переименуйте таб­ли­цу Sales в Sales Base, как показано на рис. 6.16.

Рис. 6.16    Переименование исходной таб­ли­цы

2. Создайте ссылку на таб­ли­цу Sales Base, как на рис. 6.17.

234    Подготовка данных в Power Query для схемы «звезда»

Рис. 6.17    Создание ссылки на базовую таб­ли­цу

3. Переименуйте ссылочную таб­ли­цу в Product. 4. Выделите столбцы ProductCategory, ProductSubcategory и Product. 5. Щелкните правой кнопкой мыши по заголовку любого из выбранных столбцов и  выберите пункт Удалить другие столбцы (Remove Other Columns), как показано на рис. 6.18.

Рис. 6.18    Удаление ненужных столбцов

6. Щелкните на иконке с  изображением таб­ли­цы слева от заголовков столбцов. 7. В выпадающем списке выберите пункт Удалить дубликаты (Remove Duplicates), как показано на рис. 6.19.

Создание таблиц измерений    235

Рис. 6.19    Удаление дубликатов

На данный момент в таб­ли­це Product остались только строки с  неповторяющимися сочетаниями значений. Давайте создадим для этой таб­ли­цы уникальный идентификатор. 8. Переключитесь на вкладку Добавление столбца (Add Column). 9. Нажмите на выпадающую кнопку Столбец индекса (Index Column). 10. Выберите пункт От 1 (From 1), как показано на рис. 6.20.

Рис. 6.20    Добавление столбца с индексом, начинающимся с единицы

236    Подготовка данных в Power Query для схемы «звезда» 11. Новый столбец с порядковыми номерами строк создался с именем Индекс (Index), выбранным по умолчанию. Нам нужно переименовать его в ProductKey. Для этого мы можем просто исправить формулу созданного шага Добавлен индекс (Added Index), чтобы не создавать новый шаг с переименованием. 12. Выделите шаг Добавлен индекс (Added Index) на панели примененных шагов, после чего в строке формул замените вхождение Индекс (Index) на ProductKey, как показано на рис. 6.21.

Рис. 6.21    Переименование столбца с индексом

Готово! Мы создали измерение Product.

Currency В столбце Currency из таб­ли­цы Sales Base хранится валюта, в  которой была произведена каждая конкретная транзакция. Так что этот столбец по определению можно назвать измерением. Но давайте зададимся вопросом «зачем?». Чтобы ответить на него, необходимо проанализировать ситуацию более детально. На рис. 6.22 показано, что кратность этого столбца при анализе всех строк в наборе данных очень низкая – в нем насчитывается всего шесть отдельных значений.

Рис. 6.22    Распределение столбца Currency

Создание таблиц измерений    237

Поскольку движок xVelocity с  его колоночными (columnstore) индексами обеспечивает эффективное сжатие данных как раз в столбцах с низкой кратностью, мы вряд ли увидим сильный прирост производительности или добьемся большой экономии ресурсов памяти при создании измерения Currency. К тому же здесь мы не наблюдаем возможности создания значимых связей с другими измерениями. Таким образом, мы можем сохранить столбец Currency в виде вырожденного измерения в таб­ли­це фактов.

Customer Таб­ли­цу с клиентами можно получить на основании исходной таб­ли­цы Customer. Для этого мы переименуем таб­ли­цу Customer в Customer Base. Давайте посмотрим, как каждая строка в таб­ли­це Sales Base соотносится со строками в таб­ли­це Customer Base. Как видно на рис. 6.23, в таб­ли­це Sales Base присутствует столбец CustomerKey. При этом в области качества столбца видно, что в этом столбце нет пустых значений, а значит, ключ клиента заполнен для каждой транзакции в таб­ли­це продаж. Таким образом, каждая строка в таб­ли­це Customer Base описывает строку с продажей с точки зрения клиента.

Рис. 6.23    В столбце CustomerKey отсутствуют пустые значения

В каждой строке содержится описательная информация о клиенте. Следовательно, наличие измерения Customer будет оправдано. Давайте создадим его, выполнив следующие действия. 1. Создайте ссылку на таб­ли­цу Customer Base, как показано на рис. 6.24.

Рис. 6.24    Создание ссылки на таб­ли­цу Customer Base

238    Подготовка данных в Power Query для схемы «звезда» 2. Переименуйте ссылочную таб­ли­цу в Customer. Теперь необходимо оставить в таб­ли­це только перечисленные далее столбцы, удалив остальные: CustomerKey, Title, FirstName, MiddleName, LastName, NameStyle, BirthDate, MaritalStatus, Suffix, Gender, EmailAddress, YearlyIncome, TotalChildren, NumberChildrenAtHome, Education, Occupation, HouseOwnerFlag, NumberCarsOwned, AddressLine1, AddressLine2, Phone, DateFirstPurchase и CommuteDistance. 3. Проще всего можно сделать это, воспользовавшись инструментом Выбор столбцов (Choose Columns) на вкладке Главная (Home). 4. Отметьте флажками только указанные выше поля. 5. Нажмите на кнопку OK. Этот процесс схематически показан на рис. 6.25.

Рис. 6.25    Удаление ненужных столбцов

Итак, мы создали измерение Customer. Поскольку в нем уже присутствует ключ CustomerKey, никаких дополнительных действий нам выполнять нет необходимости. Как видите, мы удалили все географические данные из измерения Customer. Для них мы создадим отдельное измерение.

Sales Demographic Ранее мы рассматривали возможность создания измерения Geography и обнаружили, что географические столбцы из таб­ли­цы Customer Base способны дать нам большую детализацию, которая поможет в создании более точных

Создание таблиц измерений    239

аналитических отчетов с уменьшенной гранулярностью. Давайте создадим измерение Sales Demographic на основе таб­ли­цы Customer Base. 1. Создайте ссылку на таб­ли­цу Customer Base в редакторе Po­wer Query. 2. Переименуйте новую таб­ли­цу в Sales Demographic. 3. Нажмите на кнопку Выбор столбцов (Choose Columns) на вкладке Главная (Home). 4. Отметьте флажками только следующие поля: City, StateProvinceCode, StateProvinceName, CountryRegionCode, CountryRegionName, PostalCode, SalesRegion, SalesCountry и SalesContinent. 5. Нажмите на кнопку OK. Этот процесс продемонстрирован на рис. 6.26.

Рис. 6.26    Создание ссылки на таб­ли­цу Customer Base с сохранением только нужных столбцов

240    Подготовка данных в Power Query для схемы «звезда» Можно заметить, что столбцы CountryRegionName и  SalesCountry содержат одну и ту же информацию. Таким образом, один из них можно удалить, дважды щелкнув по шагу с именем Другие удаленные столбцы (Remove Other Columns) и сняв флажок с поля CountryRegionName. Теперь нам необходимо избавиться от повторяющихся строк. Это позволит нам гарантировать отсутствие дубликатов в измерении в будущем, даже если сейчас повторяющихся строк в нем нет. 6. Щелкните на иконке с  изображением таб­ли­цы слева от заголовков столбцов. 7. В выпадающем списке выберите пункт Удалить дубликаты (Remove Duplicates). Эти шаги показаны на рис. 6.27.

Рис. 6.27    Удаление дубликатов из таб­ли­цы Sales Demographic

Далее добавим столбец с индексом, который будет служить в качестве первичного ключа в измерении Sales Demographic. 8. Нажмите на выпадающую кнопку Столбец индекса (Index Column) на вкладке Добавление столбца (Add Column). 9. Выберите пункт От 1 (From 1), как показано на рис. 6.28. 10. Замените в строке формул название столбца Индекс (Index) на SalesDemographicKey. 11. Нажмите на кнопку подтверждения с галочкой слева от строки формул, как показано на рис. 6.29.

Создание таблиц измерений    241

Рис. 6.28    Добавление индекса в таб­ли­цу Sales Demographic

Заменить Индекс (Index) на SalesDemographicKey

Рис. 6.29    Переименование столбца с индексом

На данный момент мы создали все нужные нам измерения на основе базовых таб­лиц Sales Base и Customer Base. Но ранее в этой главе мы говорили, что нам также понадобятся измерения для хранения дат и времени – Date и Time соответственно. Давайте займемся их созданием.

Date По итогам общения с  заказчиком мы поняли, что нам будет не обойтись без измерений с датами и временем из-за необходимости проводить анализ с  учетом хронологии событий. В  главе 2 мы уже говорили, что измерение с датами можно создать при помощи DAX. Там мы также обсуждали преимущества и  недостатки использования функции CALENDARAUTO. На этот раз мы создадим простое измерение с датами непосредственно в редакторе Po­wer Query при помощи настраиваемой функции. Эта функция будет принимать на вход два параметра: Start Year и End Year. На основании них будет создана таб­ли­ца Date с  начальной датой 1 января года, переданной в  переменной Start Year, и конечной датой 31 декабря года из параметра End Year. Таб­ли­ца Date будет заполнена всеми без исключения датами в указанном промежутке, без пропусков. Далее мы покажем, как создать и использовать эту функцию. 1. Скопируйте код, приведенный ниже, который мы используем при создании настраиваемой функции:

242    Подготовка данных в Power Query для схемы «звезда» // GenerateDate (#"Start Year" as number, #"End Year" as number) => let GenerateDates = List.Dates(#date(#"Start Year",1,1), Duration. Days(Duration.From(#date(#"End Year", 12, 31) - #date(#"Start Year" - 1,12,31))), #duration(1,0,0,0) ), #"Converted to Table" = Table.TransformColumnTypes(Table. FromList(GenerateDates, Splitter.SplitByNothing(), {"Date"}), {"Date", Date.Type}), #"Added Custom" = Table.AddColumn(#"Converted to Table", "DateKey", each Int64.From(Text.Combine({Date.ToText([Date], "yyyy"), Date.ToText([Date], "MM"), Date.ToText([Date], "dd")})), Int64.Type), #"Year Column Added" = Table.AddColumn(#"Added Custom", "Year", each Date. Year([Date]), Int64.Type), #"Quarter Column Added" = Table.AddColumn(#"Year Column Added", "Quarter", each "Qtr "&Text.From(Date.QuarterOfYear([Date])) , Text.Type), #"MonthOrder Column Added" = Table.AddColumn(#"Quarter Column Added", "MonthOrder", each Date.ToText([Date], "MM"), Text.Type), #"Short Month Column Added" = Table.AddColumn(#"MonthOrder Column Added", "Month Short", each Date.ToText([Date], "MMM"), Text.Type), #"Month Column Added" = Table.AddColumn(#"Short Month Column Added", "Month", each Date.MonthName([Date]), Text.Type) in #"Month Column Added" ПРИМЕЧАНИЕ  Этот код также содержится в хранилище GitHub по адресу https:// github.com/PacktPublishing/Expert-Data-Modeling-with-Po­wer-BI/blob/master/ Chapter06/Chapter%206%2C%20Generate%20Date%20Dimension.m.

2. Нажмите на выпадающую кнопку Создать источник (New Source). 3. Выберите пункт Пустой запрос (Blank Query), как показано на рис. 6.30.

Рис. 6.30    Создание пустого запроса в редакторе Po­wer Query

Создание таблиц измерений    243

4. Переименуйте созданный запрос в fnGenerateDate. 5. Откройте Расширенный редактор (Advanced Editor). 6. Вставьте запрос, скопированный на шаге 1, в окно расширенного редактора. 7. Нажмите на кнопку Готово (Done). Этот процесс схематически показан на рис. 6.31.

Рис. 6.31    Создание функции fnGenerateDate в редакторе Po­wer Query

Итак, мы создали настраиваемую функцию с именем fnGenerateDate в редакторе Po­wer Query. Теперь необходимо научиться вызывать ее с входными параметрами Start Year и End Year. В реальных сценариях диапазон дат в измерении Date будет диктоваться требованиями бизнес-логики. Вызвать функцию fnGenerateDate с входными параметрами Start Year и End Year, заданными явно, не представляет труда. Но зачастую требуется автоматически находить минимальное и максимальное значения в полях с датами в таб­ли­цах, участвующих в анализе. Это можно сделать разными способами. Вот лишь некоторые из них:   если набор данных невелик, можно определить минимальную и максимальную даты простым просмотром таб­лиц;   можно отсортировать значения в столбцах OrderDate, DueDate и ShipDate по возрастанию для быстрого нахождения нижней границы, а затем по убыванию – для нахождения верхней;   можно воспользоваться функциями List.Min() и List.Max() применительно к указанным столбцам для поиска граничных дат;   найти минимум и максимум можно при помощи языка DAX;

244    Подготовка данных в Power Query для схемы «звезда»   можно использовать для этого профиль столбца в  редакторе Po­wer Query. Каким бы способом вы ни воспользовались, после нахождения значений Start Date и End Date (в нашем случае это 2010 и 2014 соответственно) необходимо вызвать функцию fnGenerateDate, как показано ниже. 1. Выберите функцию fnGenerateDate на панели Запросы (Queries). 2. Введите значения 2010 и 2014 в поля параметров Start Year и End Year. 3. Нажмите на кнопку Вызвать (Invoke), как показано на рис. 6.32.

9 8 10

Рис. 6.32    Вызов функции fnGenerateDate

Вызов функции fnGenerateDate приведет к созданию новой таб­ли­цы с именем Вызванная функция (Invoked Function). Переименуйте ее в Date, как показано на рис. 6.33.

Рис. 6.33    Переименование таб­ли­цы в Date

Создание таблиц измерений    245

Итак, мы создали измерение Date. Теперь приступим к созданию измерения Time.

Time Как мы уже упоминали, в этом сценарии нам потребуется не только измерение дат, но и измерение времени. В главе 2 мы также говорили, что такое измерение можно создать при помощи инструкций языка DAX. Но здесь мы будем создавать это измерение по подобию измерения дат – непосредственно в редакторе Po­wer Query. Причина, по которой нам необходимо это измерение, очень проста. Нам нужно иметь возможность анализировать данные в разрезе разных составляющих времени, а именно в разрезе часов, минут, секунд, или временных диапазонов (time band). Например, нам может понадобиться установить дискретность анализа в виде 5 мин, 15 мин, 30 мин и т. д. Приведенное ниже выражение позволит создать измерение Time с временными диапазонами 5 мин, 15 мин, 30 мин, 45 мин и 60 мин: let Source = Table.FromList({1..86400}, Splitter.SplitByNothing()), #"Renamed Columns" = Table.RenameColumns(Source,{{"Column1", "ID"}}), #"Time Column Added" = Table.AddColumn(#"Renamed Columns", "Time", each Time. From(#datetime(1970,1,1,0,0,0) + #duration(0,0,0,[ID]))), #"Hour Added" = Table.AddColumn(#"Time Column Added", "Hour", each Time.Hour([Time])), #"Minute Added" = Table.AddColumn(#"Hour Added", "Minute", each Time.Minute([Time])), #"5 Min Band Added" = Table.AddColumn(#"Minute Added", "5 Min Band", each Time. From(#datetime(1970,1,1,0,0,0) + #duration(0, 0, Number.RoundDown(Time.Minute([Time])/5) * 5, 0)) + #duration(0, 0, 5, 0)), #"15 Min Band Added" = Table.AddColumn(#"5 Min Band Added", "15 Min Band", each Time. From(#datetime(1970,1,1,0,0,0) + #duration(0, 0, Number.RoundDown(Time.Minute([Time])/15) * 15, 0)) + #duration(0, 0, 15, 0)), #"30 Min Band Added" = Table.AddColumn(#"15 Min Band Added", "30 Min Band", each Time. From(#datetime(1970,1,1,0,0,0) + #duration(0, 0, Number.RoundDown(Time.Minute([Time])/30) * 30, 0)) + #duration(0, 0, 30, 0)), #"45 Min Band Added" = Table.AddColumn(#"30 Min Band Added", "45 Min Band", each Time. From(#datetime(1970,1,1,0,0,0) + #duration(0, 0, Number.RoundDown(Time.Minute([Time])/45) * 45, 0)) + #duration(0, 0, 45, 0)), #"60 Min Band Added" = Table.AddColumn(#"45 Min Band Added", "60 Min Band", each Time. From(#datetime(1970,1,1,0,0,0) + #duration(0, 0, Number.RoundDown(Time.Minute([Time])/60) * 60, 0)) + #duration(0, 0, 60, 0)), #"Removed Other Columns" = Table.SelectColumns(#"60 Min Band Added",{"Time", "Hour", "Minute", "5 Min Band", "15 Min Band", "30 Min Band", "45 Min Band", "60 Min Band"}), #"Changed Type" = Table.TransformColumnTypes(#"Removed Other Columns",{{"Time", type time}, {"Hour", Int64.Type}, {"Minute", Int64.Type}, {"5 Min Band", type time}, {"15 Min Band", type time}, {"30 Min Band", type time}, {"45 Min Band", type time}, {"60 Min Band", type time}}) in #"Changed Type"

246    Подготовка данных в Power Query для схемы «звезда» ПРИМЕЧАНИЕ  Этот код также содержится в хранилище GitHub по адресу https:// github.com/PacktPublishing/Expert-Data-Modeling-with-Po­wer-BI/blob/master/ Chapter06/Chapter%206%2C%20Generate%20Time%20Dimension.m.

Теперь, как и в случае с измерением Date, нам необходимо создать пустой запрос, назвать его Time и скопировать и вставить приведенный выше код в поле расширенного редактора, как показано на рис. 6.34.

Рис. 6.34    Создание измерения Time в редакторе Po­wer Query

В последних двух разделах мы создали измерения Date и Time в редакторе Po­wer Query. Возможно, вам будет интересно, насколько этот процесс отличается от создания этих измерений при помощи инструкций языка DAX. Об этом мы расскажем в следующем разделе.

Создание измерений Date и Time – Power Query против DAX Ранее мы уже рассказали, как можно создать измерения дат и времени с помощью редактора Po­wer Query. В главе 2 мы коснулись темы создания этих измерений в DAX. Сейчас же пришло время поговорить о различиях в данных подходах. Сразу заметим, что после загрузки таб­лиц в модель данных оба сценария ничем не будут отличаться ни в плане обращения с измерениями, ни в плане

Создание таблиц фактов    247

производительности. Но существуют нюансы при создании измерений дат и времени, которые могут склонить вас к тому или иному варианту:   мы можем создать измерения Date и Time в Po­wer Query либо при помощи настраиваемых функций, либо посредством статических запросов. В обоих случаях можно использовать запрос для создания потоков данных Po­wer BI (Po­wer BI Dataflows), которые будут доступны внутри организации. DAX на сегодняшний день такой возможности не предоставляет;   вычисляемые таб­ли­цы, создаваемые в DAX, недоступны в слое Po­wer Query. В связи с этим мы никак не сможем изменить созданные измерения в Po­wer Query, если у нас возникнет такая необходимость;   если нам, допустим, необходимо добавить учет местных праздничных дней в измерении Date, мы всегда можем подключиться к общедоступному сайту и использовать данные с него для корректировки измерения в Po­wer Query. В DAX такой возможности у нас не будет;   с другой стороны, если при расчете граничных дат нам захочется учесть все даты в модели данных, мы это можем легко и просто сделать с помощью функции CALENDARAUTO в  DAX. В  Po­wer Query подобного функ­ ционала пока нет;   фактор глубины познания разработчиком Po­wer Query и  DAX также стоит учитывать при выборе. Кому-то удобнее работать с первым инструментом, кому-то – со вторым.

Создание таблиц фактов Теперь, когда мы создали все нужные нам измерения, пришло время создать таб­ли­цу фактов, содержащую числовые показатели и внешние ключи, соответствующие первичным ключам в измерениях. Если взглянуть на базовые таб­ли­цы Sales Base и Customer Base, легко увидеть, что в таб­ли­це с продажами располагаются транзакции с большим количеством числовых значений. Таким образом, логично будет взять за основу таб­ли­цы фактов, которую мы назовем Sales, именно таб­ли­цу Sales Base. Сделаем это. 1. Создайте ссылку на таб­ли­цу Sales Base и переименуйте созданную таб­ ли­цу в Sales. Теперь нам нужно получить поле ProductKey из таб­ли­цы Product. Для этого мы можем объединить таб­ли­цы Sales и Product. 2. Нажмите на кнопку Объединить запросы (Merge Queries) на вкладке Главная (Home) в группе Объединить (Combine). 3. Последовательно выберите столбцы ProductCategory, ProductSubcategory и Product. 4. Выберите в выпадающем списке таб­ли­цу Product. 5. В нижней таб­ли­це также выберите столбцы ProductCategory, ProductSubcategory и Product. 6. Выберите тип Внешнее соединение слева (все из первой таб­ли­цы, совпадающие из второй) в  выпадающем списке Тип соединения (Join Kind).

248    Подготовка данных в Power Query для схемы «звезда» 7. Нажмите на кнопку OK. На рис. 6.35 показаны описанные действия.

Ссылка на Sales Base

Рис. 6.35    Объединение таб­лиц Sales и Product

8. В результате будет создан новый структурированный столбец Product.1 и шаг на панели примененных шагов. По умолчанию шаг будет назван Объединенные запросы (Merged Queries). Переименуйте его в  Merged Sales with Product. 9. Разверните столбец Product.1. 10. Установите флажок только напротив поля ProductKey, остальные оставьте неактивными. 11. Снимите флажок Использовать исходное имя столбца как префикс (Use original column name as prefix). 12. Нажмите на кнопку OK. Эта последовательность действий показана схематически на рис. 6.36.

Рис. 6.36    Разворачивание структурированного столбца Product.1

Создание таблиц фактов    249

Теперь извлечем ключ SalesDemographicKey из таб­ли­цы Sales Demographic. Столбцы, составляющие уникальную комбинацию для каждой строки в таб­ли­це Sales Demographic, – это SalesCountry, City, StateProvinceName и PostalCode. Но в таб­ли­це Sales нет всех этих столбцов. Кроме того, таб­ли­ца Sales Demographic была получена на основании таб­ли­цы Customer Base. Таким образом, нам необходимо объединить таб­ли­цы Sales и  Customer Base по столбцу CustomerKey, а  уже затем выполнять объединение с  таблицей Sales Demographic, чтобы добраться до поля SalesDemographicKey. 13. Нажмите на кнопку Объединить запросы (Merge Queries) на вкладке Главная (Home) в группе Объединить (Combine). 14. Выберите столбец CustomerKey в секции Sales. 15. В выпадающем списке выберите таб­ли­цу Customer Base. 16. В нижней таб­ли­це также выберите столбец CustomerKey. 17. Выберите тип Внешнее соединение слева (все из первой таб­ли­цы, совпадающие из второй) в  выпадающем списке Тип соединения (Join Kind). 18. Нажмите на кнопку OK. На рис. 6.37 показаны эти действия.

Рис. 6.37    Объединение таб­лиц Sales и Customer Base

В результате будет создан новый структурированный столбец с именем Customer Base и шаг на панели примененных шагов. 19. Переименуйте шаг в Merged Sales with Customer Base. 20. Разверните столбец Customer Base. 21. Установите флажки напротив полей SalesCountry, City, StateProvinceName и PostalCode, остальные оставьте неактивными.

250    Подготовка данных в Power Query для схемы «звезда» 22. Снимите флажок Использовать исходное имя столбца как префикс (Use original column name as prefix). 23. Нажмите на кнопку OK. Эти действия схематически показаны на рис. 6.38.

Рис. 6.38    Разворачивание структурированного столбца Customer Base

Теперь необходимо объединить результат с таблицей Sales Demographic для получения поля SalesDemographicKey. 24. Снова нажмите на кнопку объединения запросов и на этот раз выберите столбцы SalesCountry, City, StateProvinceName и PostalCode. 25. Из выпадающего списка выберите таб­ли­цу Sales Demographic. 26. В нижней области также выберите столбцы SalesCountry, City, StatePro­ vinceName и PostalCode. Помните о важности очередности выделения. 27. Выберите тип Внешнее соединение слева в выпадающем списке Тип соединения (Join Kind). 28. Нажмите на кнопку OK. Эти действия показаны на рис. 6.39. В результате будет создан структурированный столбец Sales Demographic и новый шаг Объединенные запросы (Merged Queries). 29. Переименуйте созданный шаг в Merged Sales with Sales Demographic. 30. Разверните структурированный столбец Sales Demographic. 31. Установите флажок только напротив поля SalesDemographicKey. 32. Снимите флажок Использовать исходное имя столбца как префикс (Use original column name as prefix). 33. Нажмите на кнопку OK. Эти шаги показаны на рис. 6.40.

Создание таблиц фактов    251

Рис. 6.39    Объединение таб­лиц Sales и Sales Demographic

Рис. 6.40    Объединение таб­лиц Sales и Sales Demographic

252    Подготовка данных в Power Query для схемы «звезда» Теперь, когда мы добавили столбец SalesDemographicKey в таб­ли­цу Sales, пришло время присмотреться к столбцам в таб­ли­це Sales с типами данных Дата (Date) и Дата и время (DateTime). Таких столбцов в таб­ли­це три, и  все они имеют тип данных Дата и  время (DateTime), хотя на самом деле временная составляющая важна только в столбце OrderDate, тогда как в двух других колонках время неизменно и установлено по умолчанию на 12:00:00. Следовательно, будет лучше преобразовать эти поля в тип данных Дата (Date). Что касается столбца OrderDate, то нам необходимо хранить дату и время из него отдельно, чтобы можно было использовать эти поля в связях. Давайте разделим столбец OrderDate на два отдельных столбца с именами Order Date и Order Time. Для этого выполните следующие действия. 34. Выделите столбец OrderDate. 35. Нажмите на выпадающую кнопку Разделить столбец (Split Column) на вкладке Главная (Home). 36. Выберите пункт По разделителю (By Delimiter). 37. Укажите Пробел (Space) в качестве разделителя. 38. Установите переключатель в положение Самый левый разделитель (Left-most delimiter). 39. Нажмите на кнопку OK. Эти действия схематически показаны на рис. 6.41.

Рис. 6.41    Разделение столбца OrderDate по пробелам

40. Переименуйте созданный шаг Разделить столбец по разделителю (Split Column by Delimiter) в Split OrderDate by Delimiter. 41. В строке формул замените OrderDate.1 на Order Date, а OrderDate.2 – на Order Time, как показано на рис. 6.42, и подтвердите действие.

Создание таблиц фактов    253

Изменено с OrderDate.1 на Order Date

Изменено с OrderDate.2 на Order Time

Рис. 6.42    Изменение имен разделенных столбцов в строке формул

Если в  настройках установлено автоматическое определение типов данных для столбцов, будет добавлен шаг Измененный тип (Changed Type). Оставьте его. Теперь нам нужно изменить тип данных для столбцов DueDate и ShipDate с Дата и время (DateTime) на Дата (Date). 42. Выделите созданный шаг Измененный тип (Changed Type). 43. Выделите столбцы DueDate и ShipDate. 44. Нажмите на выпадающую кнопку Тип данных (Data Type) на вкладке Главная (Home). 45. Выберите тип Дата (Date), как показано на рис. 6.43.

Рис. 6.43    Изменение типов данных столбцов DueDate и ShipDate

На данный момент мы добавили из измерений в таб­ли­цу фактов все ключевые столбцы, которые будут использоваться в модели данных для создания связей. Осталось лишь почистить таб­ли­цу Sales, избавившись от ненужных столбцов.

254    Подготовка данных в Power Query для схемы «звезда» 46. Нажмите на кнопку Выбор столбцов (Choose Columns) на вкладке Главная (Home). 47. Отметьте флажками только указанные поля: CustomerKey, SalesOrderNumber, SalesOrderLineNumber, OrderQuantity, ExtendedAmount, TotalProductCost, SalesAmount, TaxAmt, Freight, Order Date, Order Time, DueDate, ShipDate, Currency и ProductKey. 48. Нажмите на кнопку OK. Эти действия показаны на рис. 6.44.

Рис. 6.44    Удаление ненужных столбцов из таб­ли­цы фактов

После всех произведенных действий давайте посмотрим, что из себя представляет таб­ли­ца фактов Sales. В ней присутствуют:   числовые показатели OrderQuantity, ExtendedAmount, TotalProductCost, SalesAmount, TaxAmt, Freight, которые и являются фактами;   поля CustomerKey, Order Date, Order Time, DueDate, ShipDate, ProductKey и  SalesDemographicKey  – это внешние ключи, которые мы будем использовать в модели данных для создания связей между таблицей Sales и измерениями;   столбцы SalesOrderNumber, SalesOrderLineNumber и Currency, представляющие вырожденные измерения.

Заключение В этой главе мы подготовили данные для схемы «звезда» и оптимизировали их для проведения анализа и формирования отчетов. Мы выделили потен-

Заключение    255

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

Глава

7

Эффективные методики подготовки данных В предыдущей главе мы прошли путь от плоского источника данных до схемы «звезда» путем выделения измерений и фактов. В этой главе мы освоим техники, которые позволят значительно повысить эффективность запросов, улучшить их организацию и облегчить поддержку. Мы познакомимся с таким важным аспектом моделирования данных, как свертывание запросов. Также мы акцентируем ваше внимание на важности выбора подходящих типов данных, что поможет избежать ненужных преобразований данных в модели. Кроме того, мы затронем некоторые техники, позволяющие уменьшить размер запросов. И наконец, мы уделим внимание соглашению о наименованиях, следуя которому, вы сможете сделать свой код легко читаемым. Основные темы этой главы:   общие рекомендации по подготовке данных;   преобразование типов;   оптимизация размера запросов;   соглашение о наименованиях.

Общие рекомендации по подготовке данных В этом разделе мы поговорим об эффективных методиках подготовки данных в Po­wer Query. Следуя приведенным ниже рекомендациям, вы сможете избежать проблем при моделировании данных, которые бывает непросто обнаружить и дорого решать.

При работе с источником OData используйте частичную загрузку данных Протокол OData (Open Data Protocol) был разработан компанией Microsoft и до сих пор является распространенной технологией, используемой в сервисах REST API и других приложениях для обмена информацией. При загрузке данных в  Po­wer BI посредством подключения OData очень важно уделять

Общие рекомендации по подготовке данных    257

особое внимание объему передаваемой информации. Зачастую в этих случаях передаются очень объемные широкие таб­ли­цы с большим количеством столбцов, содержащих метаданные, в которых нет необходимости. Одним из основных требований при подготовке данных, вне зависимости от источника, является сохранение только тех столбцов, которые действительно нужны в  модели. А  при работе с  протоколом OData это требование становится еще более важным. Я встречался на практике с отчетами в Po­wer BI, которые подвешивали систему при попытке разработчика загрузить все данные из широкой таб­ли­цы, насчитывающей более 200 столбцов. Говоря о частичной загрузке данных, мы в первую очередь имеем в виду ограничение исходного набора данных столбцами, которые нам действительно необходимы. Но иногда речь может также идти о фильтрации данных по строкам для загрузки только той части информации, которая представляет интерес для бизнеса. Здесь вам также могут понадобиться консультации с экспертом в конкретной предметной области. Обычно бизнес сам определяет разрезы, в которых необходимо анализировать данные. Чтобы предварительно понимать, с каким количеством таб­лиц, колонок и строк мы будем иметь дело при загрузке данных из источника OData, полезно бывает провести эксперимент в редакторе Po­wer Query при помощи следующей функции: //fnODataFeedAnalysis (ODataFeed as text) => let Source = OData.Feed(ODataFeed), FilterTables = Table.SelectRows(Source, each Type.Is(Value.Type([Data]), Table.Type) = true), #"TableColumnCount Added" = Table.AddColumn(FilterTables, "Table Column Count", each Table.ColumnCount([Data]), Int64.Type), #"TableCountRows Added" = Table.AddColumn(#"TableColumnCount Added", "Table Row Count", each Table.RowCount([Data]), Int64.Type), #"NumberOfDecimalColumns Added" = Table.AddColumn(#"TableCountRows Added", "Number of Decimal Columns", each List.Count(Table.ColumnsOfType([Data], {Decimal.Type})), Int64. Type), #"ListOfDecimalColumns Added" = Table.AddColumn(#"NumberOfDecimalColumns Added", "List of Decimal Columns", each if [Number of Decimal Columns] = 0 then null else Table. ColumnsOfType([Data], {Decimal.Type})), #"NumberOfTextColumns Added" = Table.AddColumn(#"ListOfDecimalColumns Added", "Number of Text Columns", each List.Count(Table.ColumnsOfType([Data], {Text.Type})), Int64.Type), #"ListOfTextColumns Added" = Table.AddColumn(#"NumberOfTextColumns Added", "List of Text Columns", each if [Number of Text Columns] = 0 then null else Table. ColumnsOfType([Data], {Text.Type})), #"Sorted Rows" = Table.Sort(#"ListOfTextColumns Added",{{"Table Column Count", Order. Descending}, {"Table Row Count", Order.Descending}}), #"Removed Other Columns" = Table.SelectColumns(#"Sorted Rows",{"Name", "Table Column Count", "Table Row Count", "Number of Decimal Columns", "List of Decimal Columns", "Number of Text Columns", "List of Text Columns"}) in #"Removed Other Columns"

258    Эффективные методики подготовки данных Для вызова этой функции необходимо передать ей в качестве параметра ссылку на источник данных OData. В результате должен быть получен ответ, подобный тому, что показан на рис. 7.1.

Рис. 7.1    Результат вызова настраиваемой функции fnODataFeedAnalysis ПРИМЕЧАНИЕ  Для проверки созданной функции вы можете использовать ссылку на источник OData для доступа к базе данных Northwind: https://services.odata.org/ Northwind/Northwind.svc/.

Мы запустили функцию fnODataFeedAnalysis со ссылкой на источник OData для проекта Microsoft Project Online. В результате мы получили следующую информацию о содержимом таб­лиц в источнике:   Name: имена таб­лиц. Как видно на рис. 7.1, источник OData, к которому мы обратились, насчитывает 40 таб­лиц;   Table Column Count: показывает количество столбцов в  источнике данных. Это бывает очень удобно, когда вам нужно быстро понять, какие из представленных таб­лиц обладают достаточной шириной, чтобы присмотреться к  ним внимательнее. В  источнике, показанном на рис. 7.1, три таб­ли­цы с наибольшим количеством столбцов – это Projects (131 столбец), Tasks (113 столбцов) и Assignments (84 столбца);

Общие рекомендации по подготовке данных    259

  Table Row Count: показывает количество строк в таб­ли­цах. В нашем случае лидеры по этому показателю – таб­ли­цы TaskBaselineTimephasedDataSet (195 727 строк), TaskTimephasedDataSet (160 154 строки) и AssignmentBaselineTimephasedDataSet (75 475 строк);   Number of Decimal Columns: количество столбцов с  типом данных Десятичное число (Decimal);   List of Decimal Columns: список столбцов с типом данных Десятичное число (Decimal). Для просмотра списка достаточно щелкнуть по ячейке;   Number of Text Columns: количество столбцов с типом данных Текст (Text);   List of Text Columns: список столбцов с типом данных Текст (Text). Последние колонки очень важны для анализа данных. Они показывают количество столбцов с типами данных Десятичное число (Decimal), Текст (Text) и Дата, время и часовой пояс (DateTimeZone), которые при неправильном обращении могут занимать довольно много места в  памяти. Глядя на результат вызванной функции, можно быстро узнать, какие таб­ли­цы требуют повышенного внимания из-за наличия большого количества строк и столбцов. ПРИМЕЧАНИЕ  Если в вашем источнике данных есть таб­ли­ца, насчитывающая миллионы строк, шаг #"TableCountRows Added" может выполняться очень долго. В этом случае вы можете просто удалить его, сохранив остальные шаги. Иногда из источников OData данные возвращаются в виде записей (record). Для их обработки потребуется внести определенные изменения в функцию fnODataFeedAna­ lysis. Но в представленном виде эта функция будет корректно работать с большинством источников.

После нахождения таб­лиц, представляющих наибольший интерес в плане эффективности их загрузки, можно сделать следующее:   удалить из загрузки ненужные столбцы;   отфильтровать данные, уменьшив количество загружаемых строк;   рассмотреть вариант изменения гранулярности данных путем агрегирования числовых показателей;   внимательнее отнестись к типам данным в этих таб­ли­цах. Этой теме мы посвятим отдельный раздел в данной главе.

Не забывайте о регистрозависимости Power Query Как мы уже упоминали ранее, Po­wer Query является регистрозависимым инструментом. И  это свойство распространяется не только на синтаксис функций, но и на работу с данными. Зачастую нам приходится иметь дело с первичными или внешними ключами в таб­ли­цах в виде глобальных уникальных идентификаторов (globally unique identifier – GUID). И если вы захотите сравнить GUID, написанные в разных регистрах, у вас ничего не получится. К  примеру, в  Po­wer Query следующие два значения не будут равны между собой:

260    Эффективные методики подготовки данных C54FF8C6-4E51-E711-80D4-00155D38270C c54ff8c6-4e51-e711-80d4-00155d38270c

Таким образом, если мы будем объединять таб­ли­цы на основе этого ключа, то получим весьма странные результаты. То же касается создания связей в модели данных по ключам с разными регистрами. Для решения этой проб­ лемы рекомендуется всегда приводить строки к одному регистру в редакторе Po­wer Query с помощью функций Text.Upper() или Text.Lower().

Помните о свертывании запросов и его влиянии на обновление данных При моделировании данных необходимо уделять особое внимание свертыванию запросов (query folding). Этот аспект не только оказывает влияние на эффективность обновления данных, но и отвечает за использование ресурсов во время обновления. Свертывание запросов также важно для выполнения добавочной (инкрементной) загрузки данных (incremental data load). Эта операция будет недоступна, если обновление будет затягиваться из-за невозможности выполнить свертывание запросов. Кроме того, свертывание запросов критически важно при использовании режимов хранения данных DirectQuery и  Dual, поскольку в  этом случае все шаги в  запросах должны обладать возможностью для свертывания. Теперь, когда вы знаете, какую важную роль играет свертывание запросов, давайте посмотрим, что оно из себя представляет.

Понятие свертывания запросов Свертывание запроса – это способность движка Po­wer Query транслировать шаги запроса на родной для источника язык. Таким образом, в зависимости от шагов запроса в нем может выполняться полное или частичное свертывание. Допустим, мы производим подключение к  SQL Server и  выполняем какие-то шаги преобразования извлеченных данных. Движок Po­wer Query пытается транслировать все наши шаги в соответствующие инструкции языка запросов T-SQL. Если ему это удается, мы говорим, что произошло полное свертывание запроса. В случае если какой-то шаг напрямую не транслируется в  язык источника, свертывание этого шага и  всех последующих в  запросе выполнено не будет, так что для запроса будет выполнено лишь частичное свертывание. Для чего это делается? Если запрос может быть полностью свернут, Po­wer Query переадресует все действия составляющих его шагов источнику данных и просто ждет ответа. При частичном свертывании запроса источнику будут отправлены только те шаги, которые могут быть транслированы в его язык запросов, а остальные действия Po­wer Query будет выполнять на локальном компьютере собственными силами. Если ни один шаг запроса не может быть свернут, движок Po­wer Query будет вынужден производить все действия самостоятельно.

Общие рекомендации по подготовке данных    261

Свертывание запросов и режимы хранения DirectQuery и Dual Концепция свертывания запросов в  области программирования относится к  клиент-серверной обработке данных. Запросы, в  которых может быть выполнено полное свертывание, целиком обрабатываются на сервере, что обеспечивает гораздо большую эффективность по сравнению с полной или частичной обработкой шагов на локальном компьютере. Запросы с  режимом хранения DirectQuery или Двойной (Dual) должны обладать возможностью полного свертывания. Иными словами, все их шаги должны свободно преобразовываться в инструкции языка запросов источника данных. В противном случае будет отображаться предупреждение, показанное на рис. 7.2.

Рис. 7.2    В результате этого шага образуется запрос, не поддерживаемый в режиме DirectQuery. Переключите все таб­ли­цы в режим Import

Свертывание запросов и источники данных Большинство источников данных, в которых есть язык запросов, поддерживают операцию свертывания запросов. Среди них следующие:   реляционные СУБД, поддерживаемые в Po­wer BI;   каналы OData;   списки SharePoint, по сути представляющие каналы OData;   Microsoft Exchange;   Active Directory;   Microsoft Access. В то же время большинство источников данных на основе плоских файлов, файлов Excel, больших двоичных объектов и веб-ресурсов операцию свертывания запросов не поддерживают.

Индикация свертывания запросов Теперь, когда вы знаете, что из себя представляет свертывание запросов, неплохо было бы научиться определять, применяется оно к тому или иному шагу или нет. Хорошие новости заключаются в том, что определенная индикация свертывания запросов существует, и в зависимости от режима хранения и  применяемых шагов преобразования она может быть более или менее значимой. Иногда может понадобиться прибегнуть к дополнительным действиям, чтобы понять, применяется ли на самом деле свертывание запроса и когда именно. Как мы уже упоминали, при использовании режимов хранения DirectQuery и Dual все запросы должны успешно сворачиваться. В противном случае вы получите предупреждение с настоятельной просьбой перевести все таб­

262    Эффективные методики подготовки данных ли­цы в режим импорта. Это само по себе укажет вам на то, что свертывание запроса выполнить не удалось. Если же вы и так используете режим импорта в запросе, его шаги могут успешно сворачиваться, а могут и нет. Говоря в общем, все шаги, которые можно без потери функционала транслировать в язык запросов источника, могут быть успешно свернуты. Применительно к языку SQL это означает, что шаги, которые при транслировании преобразуются в  запросы, использующие инструкции SELECT, WHERE, GROUP BY, все типы оператора JOIN, псевдонимы (переименование столбцов) и UNION ALL (с тем же источником), спокойно могут быть свернуты. Чтобы узнать, выполняется ли свертывание того или иного шага запроса, достаточно щелкнуть по нему правой кнопкой мыши и в контекстном меню проверить, является ли активным пункт Просмотреть машинный запрос (View Native Query). Если это так, значит, этот шаг и все предыдущие были успешно свернуты в машинные запросы. В противном случае на шаге, на котором вы располагаетесь, или на одном из предыдущих шагов цепочка свертывания, скорее всего, прервалась. На рис. 7.3 показан запрос к SQL Server, который успешно прошел процедуру свертывания. При этом вы можете выбрать в контекстном меню пункт Просмотреть машинный запрос, чтобы увидеть запрос на языке T-SQL, в который был преобразован наш исходный запрос в Po­wer Query.

Кликните правой клавишей мыши

Рис. 7.3    Просмотр машинного запроса в редакторе Po­wer Query

Общие рекомендации по подготовке данных    263

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

Используйте инструкцию SQL при подключении к SQL Server При подключении к  SQL Server мы можем написать инструкцию на языке запросов T-SQL с простым оператором SELECT или вызовом хранимой процедуры. На рис. 7.4 показано, где можно это сделать.

Откройте расширенные параметры

Введите инструкцию SQL

Рис. 7.4    Использование инструкции T-SQL при подключении к SQL Server

Это очень удобная возможность, но при ее использовании необходимо понимать, что в этом случае свертывание запроса выполняться не будет. Это наглядно показано на рис. 7.5. В связи с  этим необходимо выполнить максимально возможное коли­ чество преобразований данных непосредственно в запросе T-SQL. В идеале мы должны получить всего один примененный шаг в редакторе Po­wer Query. На рис. 7.6 показан пример заключения в инструкцию T-SQL всех шагов, которые были применены к запросу на рис. 7.5.

264    Эффективные методики подготовки данных

Рис. 7.5    При написании инструкции на языке T-SQL свертывание запросов будет недоступно

Рис. 7.6    Все трансформации выполняются непосредственно в инструкции T-SQL

Также никогда не используйте инструкцию SELECT *.

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

Общие рекомендации по подготовке данных    265

Например, при подключении к SQL Server желательно заранее позаботиться о  создании необходимых представлений (view), хранимых процедур (stored procedure) и таб­лиц, заполняемых при помощи инструментов ETL, таких как SQL Server Integration Services (SSIS) или Azure Data Factory.

Отключенный просмотр машинного запроса еще не означает, что свертывание запроса не выполняется Проверка того, выполняется ли свертывание запроса, иногда может приводить в замешательство. Ранее мы упомянули, что индикатором свертывания может служить пункт Просмотреть машинный запрос в контекстном меню шага запроса. Но это не всегда так при подключении к реляционным базам данных. Некоторые шаги не предусматривают активизации этого пункта в  контекстном меню, тогда как запрос на самом деле транслируется в  машинный и передается для выполнения источнику. На рис. 7.7 показан запрос, подключенный к SQL Server. Мы добавили простой шаг Сохраненные первые строки (Keep First Rows), чтобы оставить в  наборе данных только первые десять строк. При щелчке правой кнопкой мыши по этому шагу вы увидите, что пункт с просмотром машинного запроса в контекстном меню неактивен. В то же время мы знаем, что в  языке запросов T-SQL присутствует функция TOP, а значит, мы вполне можем ожидать успешной трансляции нашего запроса в машинный.

Рис. 7.7    Пункт просмотра машинного запроса неактивен

Неактивный статус пункта в меню еще не говорит о том, что свертывание запроса выполнено не было. Мы можем использовать инструмент диагнос­ тики, встроенный в Po­wer Query, чтобы понять, было ли на самом деле вы-

266    Эффективные методики подготовки данных полнено свертывание запроса. В данном случае нам необходимо выполнить диагностику на уровне шага. Для этого щелкните правой кнопкой мыши по шагу Сохраненные первые строки (Keep First Rows) и  выберите пункт Диагностика (Diagnose), как показано на рис. 7.8.

Рис. 7.8    Инструмент диагностики в редакторе Po­wer Query

В результате на панели Запросы (Queries) будет создана папка Диагнос­ тика (Diagnostics) с несколькими диагностическими запросами. Как видно на рис. 7.9, здесь присутствуют запросы с пометками Detailed и Aggregated, в моем случае второй запрос имеет полное имя DimCustomer_Kept First Rows_ Aggregated. Для нашего примера запрос с пометкой Aggregated покажет всю необходимую информацию. Выбрав запрос DimCustomer_Kept First Rows_Aggregated, вы увидите диагностические данные, показанные на рис. 7.9.

Рис. 7.9    Агрегированный диагностический запрос

В выводе запроса содержится очень много информации. Нас же интересуют только значения в  столбце Data Source Query, в  которых содержатся

Общие рекомендации по подготовке данных    267

сами запросы на языке T-SQL, посылаемые от Po­wer Query к SQL Server. Нам необходимо найти последний запрос T-SQL в столбце Data Source Query. На рис. 7.10 видно, что этот запрос начинается с инструкции select top 10, а это означает, что шаг Сохраненные первые строки (Keep First Rows) был успешно свернут и  отправлен для выполнения в  SQL Server. Такие проверки крайне необходимы с точки зрения моделирования данных, ведь они помогают обес­печить эффективный процесс подготовки данных в слое Po­wer Query.

Рис. 7.10    Запрос успешно свернут, хотя соответствующий пункт меню был неактивен

Организуйте запросы в редакторе Power Query Одним из важнейших аспектов разработки любого программного обеспечения является удобная организация кода и сопутствующих объектов. Разработка модели данных в Po­wer BI – не исключение. И хотя эта рекомендация не относится к процессу моделирования напрямую, с точки зрения поддержки вашего продукта очень важно организовывать запросы наиболее удобным способом. Сделать это можно очень просто. Для этого достаточно проделать следующие действия. 1. Выделите несколько запросов на панели Запросы (Queries). 2. Щелкните правой кнопкой мыши по любому из запросов, перейдите в выпадающее меню Переместить в группу (Move to Group) и выберите пункт Создать группу (New Group). 3. Введите имя для группы в соответствующем поле. 4. Укажите описание для группы запросов. 5. Нажмите на кнопку OK. Эти шаги схематически показаны на рис. 7.11.

268    Эффективные методики подготовки данных

Рис. 7.11    Объединение запросов в группу в редакторе Po­wer Query

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

Преобразование типов В главе 3 мы уже обсуждали разные типы данных, представленные в  Po­ wer Query. Также мы говорили, что преобразование типов является одной из самых распространенных операций при подготовке данных. Как специа­ листу в  области моделирования данных вам крайне необходимо понимать всю важность преобразования типов. В этом разделе мы подробно поговорим о  том, как типы данных в  Po­wer Query могут оказывать влияние на моделирование.

Рис. 7.12    Организация запросов в редакторе Po­wer Query

Преобразование типов    269

Преобразование типов и влияние на моделирование данных Чтобы подчеркнуть важность понимания типов данных в Po­wer Query, стоит отчасти повторить то, о чем мы говорили в предыдущих главах. Итак, в Po­wer Query есть только один числовой тип данных – number. Однако если взглянуть на вкладку Главная (Home), можно увидеть выпадающий список Тип данных (Data Type) с четырьмя числовыми типами, как показано на рис. 7.13.

Рис. 7.13    Представление типов данных в Po­wer Query

В языке формул Po­wer Query действительно предусмотрен только один числовой тип данных – number. В синтаксисе формул он прописывается как type number или Number.Type. Что касается типов данных из выпадающего списка на рис. 7.13, то это вовсе не типы данных, а их представления – так называемые аспекты типов (datatype facet). В то же время в движке обработки данных Po­wer Query все эти типы объединены в один – number. Давайте рассмотрим пример, чтобы лучше понять, что это значит. Представленное ниже выражение создает таб­ли­цу с разными числовыми значениями: #table({"Value"} , { {100} , {65565} , {-100000} , {-999.9999} , {0.001} , {10000000.0000001} , {999999999999999999.9999999999999999 99} })

270    Эффективные методики подготовки данных На рис. 7.14 показан результат выполнения этого выражения.

Рис. 7.14    Числовые значения в Po­wer Query

Теперь давайте добавим столбец, в котором будет отображаться тип данных для каждого значения. Для этого можно воспользоваться функцией Va­ lue.Type([Value]), которая вернет тип данных для каждого значения в столбце Value. Результат выполнения этой функции показан на рис. 7.15.

Рис. 7.15    Получение типов данных значений в столбце

Преобразование типов    271

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

Рис. 7.16    Щелкните по ячейке, чтобы увидеть тип данных

И хотя щелкать по каждой ячейке не так удобно, в Po­wer Query пока нет функции для преобразования типа данных в текст. Но мы можем воспользоваться специальным трюком с использованием функции Table.Schema(table as table), возвращающей метаданные для таб­ли­цы. Выводом функции будет таб­ли­ца со служебной информацией об исходной таб­ли­це, включая имена столбцов, типы данных и т. д. Нам необходимо извлечь поле TypeName для каждого значения из таб­ли­цы, показанной на рис.  7.15. Для этого нужно преобразовать значения в  таб­ли­цу, что можно сделать при помощи функции Table.FromValue(value as any). После этого мы извлечем значения столбца TypeName из вывода функции Table.Schema(). Итак, давайте добавим столбец для получения текстового эквивалента из столбца TypeName. Назовем столбец Datatypes, а формула в нем будет следующая: Table.AddColumn(#"Value Type Added" , "Datatypes" , each Table.Schema( Table.FromValue([Value]) )[TypeName]{0} )

Результат создания столбца показан на рис. 7.17.

272    Эффективные методики подготовки данных

Рис. 7.17    В Po­wer Query действительно есть лишь один числовой тип Number.Type

Как видите, с  точки зрения Po­wer Query все представленные числовые типы данных сводятся к одному общему типу Number.Type, а уже отображение значений в редакторе выполняется в зависимости от выбранного аспекта типа, что никак не влияет на обработку этих значений в движке Po­wer Query. В этом заключается очень важный момент. Что происходит после загрузки данных в модель? Po­wer BI подключает внутренний движок xVelocity для обработки данных. Этот движок использует колоночные индексы для сжатия данных на основе кратности столбцов. Здесь важно понимать, что хотя Po­wer Query воспринимает все числовые значения как тип number, сжимаются они совсем по-разному – в зависимости от кратности столбца после загрузки данных в модель Po­wer BI. Этим обуслов­ лена важность установки правильного аспекта типа для каждого столбца. Числовой тип данных – один из наиболее распространенных в Po­wer BI. Давайте рассмотрим еще один пример, в  котором будут видны различия между четырьмя разными аспектами типа. Запустите приведенное ниже выражение в пустом запросе в редакторе Po­wer Query: // Decimal Numbers with 6 Decimal let Source = List.Generate(()=> 0.000001, each _ = 100000 ) ; 'Product'[ProductKey] ; 'Date'[Year-Month] ; 'Customer'[CustomerKey] ) ; "Sales" ; [Sales Amount] )

На рис. 8.10 показан результат выполнения этой формулы. Как видно на рисунке, в нашей вычисляемой таб­ли­це содержится четыре столбца: ProductKey, Year-month, CustomerKey и Sales. При создании вычисляемой таб­ли­цы на основе других таб­лиц в  модели данных существует риск возникновения ошибок, связанных с циклическими зависимостями (circular dependency), если не уделить должное внимание используемым функциям. В этом случае вы не сможете создать связи между вычисляемой таблицей и таб­ли­ца­ми-источниками, если не поправите формулу. ПРИМЕЧАНИЕ  Вычисляемые таб­ли­цы для операций преобразования данных создавать не рекомендуется. Это связано с тем, что все преобразования необходимо стремиться переносить на сторону источника данных. В противном случае они будут выполняться силами Po­wer Query на клиенте.

Итак, теперь мы можем связать созданную вычисляемую таб­ли­цу с таб­ли­ ца­ми Product и Customer, как показано на рис. 8.11.

Введение в таблицы    291

Рис. 8.10    Вычисляемая таб­ли­ца с продажами товаров клиентам с годовым доходом более $100 000

Рис. 8.11    Создание связей между вычисляемой таблицей и измерениями

292    Элементы моделирования данных После создания связей мы можем анализировать продажи по любым атрибутам из таб­лиц Product и Customer, но только для тех клиентов, годовой доход которых превышает $100 000. Подобные приемы можно применять, если вам необходимо проводить выборочный анализ и  смотреть, на что тратят свои деньги клиенты, принадлежащие определенной группе.

Введение в поля Поля (field) в Po­wer BI делятся на столбцы и меры. Говоря о полях, мы обычно имеем в  виду что-то, что подходит как столбцам, так и  мерам. К  примеру, когда мы упоминаем типы данных полей, мы подразумеваем корректные типы данных, подходящие для мер и столбцов. Термин поля употребляется в Po­wer BI Desktop повсеместно, а панель с таким названием присутствует на всех трех левых вкладках: Отчет, Данные и Модель.

Типы данных При импорте данных в модель происходит преобразование типов в столбцах с приведением их в соответствие с табличной моделью (Tabular Model). Затем, когда мы используем данные из нашей модели в расчетах, они на период выполнения вычисления конвертируются в типы данных, совместимые с DAX. Типы данных в модели отличаются от типов в Po­wer Query. К примеру, в Po­ wer Query есть тип Дата, время и часовой пояс (DateTimeZone). Но в модели данных аналогичного типа не существует, в связи с чем данные при загрузке в модель преобразуются в тип Дата и время (DateTime). В табл. 8.2 показаны различные типы данных, поддерживаемые в модели данных и DAX. Таб­ли­ца 8.2. Типы данных в модели данных и DAX Тип данных Тип данных в модели в DAX Whole Number / Int64 Целое число Decimal Number / Double Десятичное число

True/false / Истина/Ложь Text / Текст Date / Дата

Boolean String DateTime

Описание Целые числа между –9 223 372 036 854 775 808 (–2 ^ 63) и 9 223 372 036 854 775 807 (2 ^ 63-1) Вещественные числа в отрицательном диапазоне от –1,79E+308 до –2,23E-308 и положительном от 2,23E-308 до 1,79E+308. Количество знаков после запятой ограничено семнадцатью True или False Строка из символов Unicode в текстовом формате Показывает часть, относящуюся к дате, из входного значения. По умолчанию самая ранняя дата в DAX относится к 30 декабря 1899 года, хотя официально начальной датой в расчетах считается 1 марта 1900 года

Введение в поля    293

Таблица 8.2 (окончание) Тип данных в модели Time / Время

Тип данных Описание в DAX DateTime Показывает часть, относящуюся ко времени, из входного значения. Если часть с датой в источнике не указана, по умолчанию будет браться 1 декабря 1899 года DateTime Показывает полное значение даты и времени

Date/time / Дата и время Fixed Decimal Decimal Number / Десятичное число с фиксированной запятой N/A Blank

Валютный тип данных в диапазоне от –922 337 203 685 477,5808 до 922 337 203 685 477,5807 с четырьмя фиксированными знаками после запятой Пустое значение в DAX (Blank) аналогично значению NULL в SQL. Мы можем создать пустое значение в DAX, используя функцию BLANK(). Для проверки на пустое значение применяется функция ISBLANK()

В Po­wer BI Desktop типы данных для столбцов показываются на дополнительной вкладке Средства работы со столбцами (Column tools) при нахождении в левой вкладке Данные или Отчет. На рис. 8.12 показаны типы данных из выпадающего списка.

Рис. 8.12    Типы данных в Po­wer BI Desktop ПРИМЕЧАНИЕ  Хотя в списке доступных типов данных в Po­wer BI присутствует тип Двоичный (Binary), в моделях данных он не поддерживается. Таким образом, если попытаться преобразовать данные в столбце в двоичный тип, возникнет ошибка.

294    Элементы моделирования данных Po­wer BI Desktop по умолчанию исключает колонки с двоичными данными. Так что вам лучше избавиться от них в редакторе Po­wer Query. При этом сам Po­wer Query поддерживает тип данных Двоичный (Binary). Если вам нужно сохранить столбцы, вы можете преобразовать их в один из поддерживаемых типов табличной модели. Для столбцов можно определять типы данных неявным образом. Типы данных для мер автоматически определяются функциями, использующимися в выражениях DAX. При использовании табличных функций DAX результат будет иметь тип Table. Мы используем этот тип данных при создании виртуальных или вычисляемых таб­лиц. Хотя Po­wer Query и поддерживает тип Дата, время и часовой пояс (DateTimeZone), при загрузке в модель он преобразуется в Дата и время (DateTime) без изменения часовых поясов. Таким образом, о  часовых поясах вам необходимо позаботиться в редакторе Po­wer Query перед загрузкой данных. Также Po­wer Query поддерживает тип Продолжительность (Duration), но при загрузке в модель он приводится к десятичному числу. Кроме того, допустимо применять сложение и вычитание к типу данных Дата и время (DateTime) без боязни спровоцировать возникновение ошибки. Например, можно выполнить следующее выражение: DATE(2010, 1, 1) + 0.04167 = 1/01/2010 1:00:00 AM.

Пользовательское форматирование Форматирование (formatting) представляет собой способ отображения значений. Мы форматируем значения, чтобы облегчить их восприятие. При этом изменение формата значения никак не влияет на его тип данных. А следовательно, не меняется ни занимаемое значением место в памяти, ни производительность при его использовании в расчетах. Некоторые типы данных поддерживают пользовательское форматирование (custom formatting). В табл. 8.3 приведены примеры форматирования для различных типов данных. Таб­ли­ца 8.3. Примеры пользовательского форматирования Тип Символ данных DateTime d

Значение День месяца без ведущего нуля

dd

День месяца с ведущим нулем

w

Номер недели без ведущего нуля

ww

Номер недели с ведущим нулем

m

Номер месяца без ведущего нуля

mm

Номер месяца с ведущим нулем

mmm

Сокращение названия месяца

mmmm

Полное название месяца

yy

Последние две цифры номера года

yyyy

Четыре цифры номера года

h

Часы без ведущего нуля (без am/pm 24-часовой формат, с am/pm – 12-часовой)

hh

Часы с ведущим нулем (без am/pm 24-часовой формат, с am/pm – 12-часовой)

n

Минуты без ведущего нуля

nn

Минуты с ведущим нулем

Пример FORMAT(CONVERT("2020/12/31 3:45:55"; DATETIME); "dddd, mmm d yyyy h:mm:ss am/pm") возвращает Thursday, Dec 31 2020 3:45:55 A.M.

Введение в поля    295

Таблица 8.3 (окончание) Тип Символ данных

Значение

m

Минуты без ведущего нуля, если идет следом за h или hh

mm

Минуты с ведущим нулем, если идет следом за h или hh

s

Секунды без ведущего нуля

ss

Секунды с ведущим нулем

Пример

A.M./P.M. Включает форматирование в 12-часовом виде Numeric

0

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

FORMAT(0, "0,0") возвращает 00 FORMAT(0.1153, "0.00") возвращает 0.12 FORMAT(35.1113, "0,00.00") возвращает 035.11

#

Работает как 0, но отображает цифру или пропуск

FORMAT(0, "#,#") возвращает пустоту FORMAT(0.1153, "#.##") возвращает .12 FORMAT(35.1113, "#,##.##") возвращает 35.11

%

Отображает значение в процентах, умножая его на 100 и добавляя знак процента там, где он располагается в строке форматирования

FORMAT(0.351156, "#,##.##0 %") возвращает 35.116 %

$

Отображает знак доллара там, где он располагается в строке форматирования

FORMAT(–35.1156, "$#,##.##0") возвращает $35.116

;

Разделитель секций в строке форматирования. В строке форматирования допустимо присутствие четырех секций, разделенных точкой с запятой. Если в строке есть лишь одна секция, она будет применена ко всему значению в целом. В противном случае первая секция будет применена к положительным значениям, вторая – к отрицательным, третья – к нулевым, а четвертая – к пустым (Null)

FORMAT(0.015, "$#,#.#0;;\Z\e\ r\o") возвращает $.02 FORMAT(-0.015, "$#,0.#0;($#,0.#0);\Z\e\r\o") возвращает ($0.02) FORMAT(-0.015, "$#,0.0;($#,0.0);\Z\e\r\o") возвращает Zero

()+-

Отображает символьные знаки. Обычно используется для вывода положительных и отрицательных значений

FORMAT(–0.05, "$#,0.0;($#,0.0)") возвращает ($0.1)

\

Представляет собой символ экранирования в строке форматирования. Позволяет отобразить следующий за ним символ в буквальном выражении

FORMAT(-0.01, "$#,0.0;($#,0.0);\n\i\l") возвращает nil

Столбцы В Po­wer BI таб­ли­цы представляют собой наборы столбцов. Это могут быть как физические столбцы, пришедшие непосредственно из источника данных, так и созданные разработчиком или самой Po­wer BI Desktop. В этом разделе мы подробно остановимся на различных типах и свойствах столбцов на вкладке Модель в Po­wer BI Desktop.

Вычисляемые столбцы Вычисляемые столбцы (calculated column) – это столбцы, отсутствующие в источнике данных. Вычисляемый столбец можно создать в  модели данных с использованием языка DAX. В Po­wer BI используется движок xVelocity, разработанный компанией Mic­ rosoft с целью выполнения обработки больших массивов данных в памяти. В  движке xVelocity применяется технология индексации по столбцам, что

296    Элементы моделирования данных позволяет очень эффективно сжимать данные в колонках на основании их кратности. При обновлении данных в  таб­ли­це движок выполняет сжатие всех столбцов и один раз загружает их в память. Этот процесс выполняется в отношении физических столбцов, присутствующих в таб­ли­цах. Вычисляемый столбец рассчитывается в Po­wer BI после этапа загрузки данных в таб­ ли­це, которой он принадлежит. При обновлении таб­ли­цы в модель данных загружаются обновленные сведения, в  связи с  чем теряется актуальность информации в вычисляемых столбцах. В результате движок вынужден пересчитывать все вычисляемые столбцы из этой таб­ли­цы, причем делает он это последовательно. Таким образом, можно сделать вывод, что вычисляемые столбцы не являются столь же оптимизированными и способными к сжатию, как физические.

Группирование данных в столбцах и разделение их на ячейки В Po­wer BI Desktop можно выполнять группировку (grouping) содержимого применительно к столбцам любого типа, тогда как разделение данных на ячейки (binning) выполняется только с числовыми столбцами. Оба приема служат для группировки значений в столбцах в ручном режиме и применяются для разделения содержимого в столбцах нужным вам образом. В данный момент операции группировки и разделения данных на ячейки недоступны на вкладке Модель, так что для их выполнения необходимо переключиться на вкладку Отчет или Данные. После этого нужно щелкнуть правой кнопкой мыши по столбцу, с которым вы хотите произвести манипуляции, и в контекстном меню выбрать пункт Создать группу (New group). К примеру, если взглянуть в нашем файле с примером на содержимое столбца ProductCategory в  таб­ли­це Product, можно выделить следующие категории товаров: Accessories, Bikes и Clothing. Представьте, что вам понадобилось анализировать продажи только по двум группам: Bikes и Другие. Реализовать это можно разными способами, вплоть до создания нового столбца в редакторе Po­wer Query. Но мы осуществим задуманное непосредственно в модели данных. Для этого выполните следующие действия. 1. Перейдите на вкладку Данные. 2. Щелкните правой кнопкой мыши по столбцу ProductCategory в таб­ли­це Product. 3. Выберите пункт Создать группу (New group). 4. Введите Bike Category в поле Имя (Name). 5. Выберите категорию Bikes в  списке Несгруппированные значения (Ungrouped values). 6. Нажмите на кнопку Группировать (Group). 7. Установите переключатель Включить другую группу (Include Other group). 8. Нажмите на кнопку OK. На рис. 8.13 схематически показаны эти шаги.

Введение в поля    297

Рис. 8.13    Создание новой группы

В результате будет создан новый столбец с группами данных, как показано на рис. 8.14.

Рис. 8.14    Созданная группа

298    Элементы моделирования данных Созданный столбец можно использовать при построении визуализаций точно так же, как и другие столбцы. Аналогично тому, как мы создали группу для столбца с категориями товаров, можно осуществить разделение данных на ячейки для числовых столбцов. Допустим, нам потребовалось сгруппировать значения в  столбце Sales­ Amount из таб­ли­цы Sales таким образом, чтобы размер ячейки (группы) составлял $1000. Выполните следующие действия для разделения содержимого столбца с продажами на ячейки. 1. Щелкните правой кнопкой мыши по столбцу SalesAmount в  таб­ли­це Sales и выберите пункт Создать группу (New group). 2. Введите Sales Amount Bins в поле Имя (Name). 3. В выпадающем списке Тип группы (Group type) выберите Ячейка (Bin). 4. В выпадающем списке Тип ячейки (Bin Type) выберите Размер ячеек (Size of bins). 5. В поле Размер ячейки (Bin size) введите 1000. 6. Нажмите на кнопку OK. На рис. 8.15 показаны эти действия.

Рис. 8.15    Создание группы путем объединения данных в ячейки

В результате будет создана группа данных без итогов.

Введение в поля    299

На рис. 8.16 видно, как можно при помощи групп и ячеек рассказать историю о данных на визуализации.

Рис. 8.16    Использование групп данных при построении визуализации

На приведенном выше рисунке пользователь решил проанализировать продажи для сделок, сумма которых не превышает $1000. Для этого он щелк­ нул по отметке 0 (ноль) на правой кольцевой диаграмме. Давайте посмот­ рим, какие любопытные выводы можно сделать, выполнив столь простое действие:   на правой кольцевой диаграмме видно, что сделки с  общей суммой ниже $1000 составляют 12,09 % от общих продаж;   на левой кольцевой диаграмме заметно, что из этих 12,09 % продажа велосипедов (Bikes) составляет 70,67 %, а на остальные категории товаров приходится 29,33 %;   столбчатая диаграмма в нижней части визуализации также показывает любопытную информацию. К  примеру, среди подкатегорий товаров, которые участвовали в  сделках с  общей суммой ниже $1000, присутствуют Road Bikes, Mountain Bikes и Touring Bikes. При этом на шоссейные велосипеды (Road bikes) пришлось 40,15 % всех сделок с  суммой до $1000.

300    Элементы моделирования данных

Свойства столбцов К свойствам столбцов можно обратиться, находясь на вкладке Модель. Для этого нужно щелкнуть по нужному столбцу на панели Свойства (Properties). В зависимости от типа данных выбранного столбца будут отображены разные свойства на панели. К примеру, для столбца Date из одноименной таб­ли­цы будут выведены свойства, показанные на рис. 8.17.

Рис. 8.17    Свойства столбца на вкладке Модель

Можно менять свойства одновременно для нескольких столбцов в модели данных. Для этого необходимо выделить их с зажатой клавишей Ctrl. На панели свойств будут показаны свойства, общие для выбранных столбцов.

Введение в поля    301

К свойствам столбцов в общем случае относятся следующие. 1. Секция Общий (General): в  этот раздел включены общие свойства столбцов, такие как: a) Имя (Name). Содержит название столбца. Переименовать столбец можно, изменив содержимое этого поля; b) Описание (Description). В  это поле можно ввести краткое описание столбца. Оно будет отображаться при наведении на столбец на панели Поля (Fields) в Po­wer BI Desktop, а также в службе Po­wer BI в режиме редактирования отчета; c) Синонимы (Synonyms). Здесь можно ввести дополнительные имена для поля для облегчения работы инструменту Вопросы и ответы (Q&A); d) Папка отображения (Display folder). Это свойство также доступно для мер и позволяет организовать близкие по смыслу поля по папкам. Можно объединить все ключевые (с упоминанием key) столбцы в папку отображения, выполнив следующие действия: •• введите в поле поиска на вкладке Модель слово key; •• с помощью клавиши Ctrl выделите нужные вам столбцы; •• введите текст Key Columns в поле Папка отображения (Display folder) на панели Свойства (Properties). Эти шаги показаны на рис. 8.18.

Рис. 8.18    Группирование столбцов по папкам отображения

В результате будут созданы папки отображения во всех таб­ли­цах, как видно на рис. 8.19.

302    Элементы моделирования данных

Рис. 8.19    Созданные в таб­ли­цах папки отображения

Допустимо также создавать вложенные папки отображения, указывая их в формате Родитель\Потомок. На рис. 8.20 показан пример создания вложенных папок;

Рис. 8.20    Создание вложенных папок отображения

Введение в поля    303

e) Скрытый (Is hidden). При помощи этого переключателя можно исключить столбец из списка отображаемых. 2. Секция Форматирование (Formatting): включает в себя свойства, относящиеся к внешнему отображению столбцов. Наполнение этой секции зависит от типа выбранного столбца. Здесь можно найти следующие обязательные свойства: a) Тип данных (Data type). В этом выпадающем списке можно выбрать желаемый тип данных для столбца; b) Формат (Format). Формат столбца может варьироваться в зависимости от выбранного типа данных, и  вы можете установить наиболее подходящие вам параметры. О  правилах пользовательского форматирования мы подробно говорили ранее в этой главе. 3. Секция Дополнительно (Advanced): в  этом разделе находятся свойства, не вошедшие в другие группы, а именно: a) Сортировать по столбцу (Sort by column). При помощи этого свойства можно установить упорядочивание столбца на основании другого столбца. Например, мы можем сортировать столбец Month из таб­ли­цы Date по столбцу MonthOrder; b) Категория данных (Data category). Это свойство позволяет устанавливать определенную категорию для столбца. Это поможет Po­wer BI более логично отображать поля на визуализациях. Например, для столбца City из таб­ли­цы Sales Demographic мы бы могли указать категорию City (Город); c) Суммировать по (Summarize by). Это свойство позволяет задать неявную агрегацию, которая будет использоваться для столбца в  элементах визуализации. К  примеру, мы могли бы для столбца ProductKey установить агрегацию по Количеству (COUNT). Это можно сделать в DAX, а можно и непосредственно в модели данных. В этом случае на визуализациях будет автоматически показано общее количество ключей товаров. На рис. 8.21 показана карточка с выводом агрегации столбца ProductKey, для которого в поле Суммировать по выбрано количество;

Рис. 8.21    Количество элементов в столбце ProductKey

d) Допускает значение NULL (Is nullable). Можно деактивировать этот переключатель для столбцов, в которых не могут быть представлены пустые значения, таких как первичные ключи. Но помни-

304    Элементы моделирования данных те, что это не позволит вам и в будущем вставить пустое значение в этот столбец – в подобном случае возникнет ошибка при обновлении данных.

Иерархии Иерархии (hierarchy) представляют собой абстрактные объекты в  модели данных, показывающие отношения между столбцами с точки зрения наследования. Иерархии можно создавать на всех трех вкладках: Отчет, Данные и Модель. Для создания календарной иерархии в таб­ли­це Date на вкладке Модель выполните следующие действия. 1. Щелкните правой кнопкой мыши по полю Year. 2. Выберите в контекстном меню пункт Создать иерархию (Create hierar­ chy). 3. На панели Свойства (Properties) введите Calendar Hierarchy в поле Имя (Name). 4. В секции Иерархия (Hierarchy) выберите из выпадающего списка поля Month и Date. 5. Нажмите на кнопку Применить изменения уровней (Apply Level Changes). На рис. 8.22 схематически показаны эти действия.

Рис. 8.22    Создание иерархии на вкладке Модель

Введение в поля    305

Как видно на рисунке, некоторые общие свойства столбцов также доступны и для иерархий, так что мы не будем подробно на них останавливаться.

Меры Мерами (measure) в области моделирования данных называются вычисления, помогающие нам выполнять анализ. При этом результат вычислений будет меняться в процессе взаимодействия с мерами. Эти взаимодействия могут происходить в слое визуализации данных, когда мы используем меры в визуальных элементах, или в самой модели, когда мы используем меру в процессе создания других табличных объектов, таких как вычисляемые таб­ли­ цы. Меры можно создавать как на вкладке Отчет, так и на вкладке Данные. После создания меры можно установить ее свойства на вкладке Модель. Свойства мер очень схожи со свойствами столбцов, так что мы не будем подробно на них останавливаться. В Po­wer BI существует два типа меры: явная и неявная. Давайте разберем их более детально.

Неявные меры Неявные меры (implicit measure) представляют собой абстрактные меры, создаваемые при использовании столбца в элементе визуализации. Po­wer BI автоматически определяет необходимость создания неявной меры по числовому типу используемого столбца. Эти меры легко идентифицировать на панели Поля (Fields) по стоящей рядом с  ними иконке в  виде символа суммы (∑). Если для числового столбца установлено свойство Суммировать по (Summarize by), о котором мы говорили ранее, его можно использовать в визуальных элементах. По умолчанию будет применяться агрегация, выбранная в  поле суммирования. Например, если мы выбрали в этом поле способ агрегирования данных по количеству, в неявной мере автоматически будет использован этот тип агрегации. Иными словами, неявные меры – это такие меры, которые мы не создаем при помощи выражений DAX. Они создаются при использовании столбца в визуальных элементах. На рис. 8.23 поле Year определяется как неявная мера. Таким образом, при вынесении ее в табличный визуальный элемент Po­wer BI рассчитывает сумму по этому столбцу, что явно неправильно. Хотя использовать неявные меры довольно просто, мы не рекомендуем это делать. Существует масса причин для этого, и в их числе следующие:   зачастую в  столбцах, идентифицированных в  качестве неявных мер, значения не являются аддитивными, а значит, суммирование в качест­ ве способа агрегирования для них не подходит, что вы видели в приведенном выше примере;   неявные меры нельзя использовать повторно. Они создаются в  слое визуализации и могут быть использованы только на этом уровне;   мы не можем корректировать выражения, использующиеся в  основе неявных мер;   неявные меры часто сбивают с толку, и их трудно поддерживать;   неявные меры несовместимы с некоторыми техниками моделирования данных, например с группами вычислений (calculation groups).

306    Элементы моделирования данных

Рис. 8.23    Столбец Year из таб­ли­цы Date был определен в виде неявной меры

Есть два способа отказаться от создания неявных мер в  Po­wer BI. Вопервых, вы можете в свойстве Суммировать по выбрать пункт Нет (None). Это можно сделать, выполнив следующие действия на вкладке Модель. 1. Выберите таб­ли­цу на панели Поля (Fields) или в представлении модели. 2. Нажмите сочетание клавиш Ctrl+A. 3. Щелкните правой кнопкой мыши по любой таб­ли­це. 4. Выберите в  контекстном меню пункт Выбрать столбцы (Select columns). 5. Откройте секцию Дополнительно (Advanced) на панели Свойства (Properties). 6. Выберите в свойстве Суммировать по пункт Нет (None). На рис. 8.24 показаны эти действия. Также вы можете отменить создание неявных мер в модели данных при помощи инструмента Tabular Editor. Этот способ позволит избавиться от создания неявных мер во всей модели, и если в будущем вы добавите в модель новые таб­ли­цы, для них также не будут автоматически создаваться неявные меры. Tabular Editor  – это инструмент, популярный среди разработчиков моделей данных. На момент написания книги в Po­wer BI Desktop подобный функционал отсутствует, а чтобы открыть Tabular Editor и осуществить намеченное, необходимо сделать следующее. 1. В Po­wer BI Desktop перейдите на вкладку Внешние инструменты (External Tools). 2. Если вы установили последнюю версию Tabular Editor, соответствующая иконка будет отображаться на вкладке. Нажмите на нее. 3. В открывшемся окне Tabular Editor раскройте модель. 4. Установите опцию Discourage Implicit Measures в значение True. 5. Нажмите на кнопку Save, чтобы сохранить изменения в модели. Эти действия показаны на рис. 8.25.

Введение в поля    307

Нажмите Ctrl+A на клавиатуре

Щелкните правой клавишей мыши

Рис. 8.24    Отмена агрегирования для всех столбцов в модели данных

Рис. 8.25    Запрещение создания неявных мер в Tabular Editor

Теперь, когда мы сохранили изменения, можно вернуться в Po­wer BI Desktop, закрыть Tabular Editor и обновить модель для отображения изменений.

308    Элементы моделирования данных

Явные меры Явными мерами (explicit measure) называются меры, созданные с  использованием функций DAX. Меры можно использовать повсеместно. Можно создавать их для ответа на простые вопросы, касающиеся агрегации показателей, а также использовать для осуществления сложных расчетов с участием даты и времени или нарастающих итогов. Кроме того, допустимо создавать текстовые меры, которые могут использоваться для придания динамики визуальным заголовкам. Помимо этого, меры можно применять совместно с условным форматированием для удобства отображения информации.

Текстовые меры Текстовые меры (textual measure) помогают в решении множества задач в области визуализации данных. К примеру, вы отображаете продажи по товарам при помощи столбчатой диаграммы, и вам может понадобиться сменить цвет столбца на красный в случае, если сумма продажи в конкретной точке данных оказывается ниже среднего значения. Для решения подобного сценария мы могли бы создать простую текстовую меру со следующей формулой: Sales by Product Column Chart Colour = var avgSales = AVERAGEX( ALL('Product'[Product]) ; [Sales Amount] ) return IF([Sales Amount] < avgSales; "Red")

Осталось добавить на страницу отчета столбчатую диаграмму и выполнить следующие действия. 1. Перенесите столбец Product из таб­ли­цы Product на область Ось (Axis). 2. Вынесите меру Sales Amount на область Значения (Values). 3. Перейдите на вкладку форматирования на панели Визуализации (Visualizations). 4. Раскройте область, отвечающую за цвета данных. 5. Нажмите на кнопку fx. 6. Выберите в выпадающем стиле форматирования пункт Значение поля (Field value). 7. Выберите меру Sales by Product Column Chart Color. 8. Нажмите на кнопку OK. Эти шаги показаны на рис. 8.26.

Введение в поля    309

Рис. 8.26    Использование текстовых мер для динамической установки цвета данных

На рис. 8.27 показан итоговый элемент визуализации.

Рис. 8.27    Условное форматирование данных с использованием текстовой меры

310    Элементы моделирования данных

Использование связей Связи (relationship) при моделировании реляционных данных служат для описания отношений между таб­ли­ца­ми. Возьмем, к  примеру, связь между таб­ли­ца­ми Customer и Sales из нашего сценария. У клиента может быть сразу несколько транзакций в таб­ли­це Sales. Для создания связи между таб­ли­ца­ ми Customer и  Sales необходимо объединить их по столбцам CustomerKey, присутствующим в обеих таб­ли­цах. Эта связь дает Po­wer BI понять, что для каждой строки из таб­ли­цы Customer может быть одна или несколько строк в таб­ли­це Sales. Для создания связей можно воспользоваться вкладкой Модель, позволяющей перетаскивать столбцы из разных таб­лиц друг на друга, а  можно нажать на кнопку Управление связями (Manage relationships) на ленте. Эта кнопка присутствует сразу на нескольких вкладках. На рис.  8.28 показано, где ее можно найти.

Рис. 8.28    Управление связями в Po­wer BI Desktop

При создании связей между таб­ли­ца­ми они отображаются на вкладке Модель в виде сплошных или пунктирных линий. Сплошная линия характеризует активную связь (active relationship), а пунктирная – неактивную (inactive relationship). На рис. 8.29 графически показаны связи между таб­ли­ца­ми Date и Sales.

Использование связей    311

Рис. 8.29    Активные и неактивные связи

В зависимости от кратности связи (relationship cardinality) на ее концах отображаются символы звездочка (*) или единица (1). Также каждая связь характеризуется стрелкой, располагающейся посередине линии. Направление стрелки отражает направление распространения фильтра (filter propagation). В следующих нескольких разделах мы более подробно поговорим о кратности связей и распространении фильтров.

Первичные и внешние ключи В реляционной модели данных в  таб­ли­цах могут присутствовать столбцы (один или несколько), значения в которых гарантируют уникальность строк. Если строки в таб­ли­це не уникальны, т. е. присутствуют дубликаты, необходимо избавиться от них либо в источнике данных, либо на стадии преобразования данных в редакторе Po­wer Query. Колонка, в которой гарантирована уникальность значений в каждой строке таб­ли­цы, именуется первичным ключом (primary key). Первичный ключ не может содержать пустых значений. Будучи представленным в  другой таб­ли­це, первичный ключ обретает имя внешний ключ (foreign key), но только в случае эквивалентности типов данных этих столбцов. В Po­wer BI Desktop на момент написания книги такое строгое требование к типам данных связываемых столбцов не реализовано, в связи с чем следует соблюдать особую осторожность при объединении таб­лиц.

Управление составными ключами Как мы уже упоминали ранее, уникальность в таб­ли­це может обеспечиваться не одним, а сразу несколькими столбцами в совокупности. В этом случае эти столбцы будут образовывать так называемый составной ключ (composite key). Во многих реляционных СУБД, включая SQL Server, можно объединять таб­ли­

312    Элементы моделирования данных цы одновременно по нескольким столбцам, входящим в составной ключ. В то же время в Po­wer BI Desktop и других продуктах от Microsoft, использующих движок Tabular, это недопустимо. Чтобы обойти данное ограничение, можно объединить колонки, входящие в составной ключ, в один столбец, по которому будет гарантирована уникальность в рамках таб­ли­цы. Для этого можно воспользоваться редактором Po­wer Query, а можно и создать вычисляемый столбец при помощи DAX. При этом первый способ является предпочтительным. Если вы прочитали главу 6, то уже знаете, как это делать. Давайте еще раз повторим последовательность действий, чтобы вам было лучше понятно, как это связано с  управлением составными ключами. 1. Мы создали измерение Product путем извлечения всех описательных свойств товаров из таб­ли­цы Sales Base. 2. Избавились от дубликатов. 3. Определили столбцы, уникально определяющие строки в таб­ли­це Pro­ duct. Ими оказались столбцы ProductCategory, ProductSubcategory и Pro­ duct. 4. Добавили столбец с индексом, значения в котором начинаются с единицы. Если бы мы не добавили индекс, нам пришлось бы думать о том, как поступать в дальнейшем в отношении составного ключа. Напомним, что в составной ключ у нас входят столбцы ProductCategory, Pro­ ductSubcategory и  Product, а  новый столбец с  именем ProductKey стал первичным ключом таб­ли­цы Product. 5. При создании впоследствии таб­ли­цы фактов мы использовали столбцы ProductCategory, ProductSubcategory и  Product из таб­ли­цы Product для слияния этой таб­ли­цы с  таблицей Sales. После этого мы развернули структурированный столбец Product из таб­ли­цы Sales, импортировав столбец ProductKey. Этот столбец в таб­ли­це Sales стал внешним ключом. Вы видите, насколько важно выполнить правильные действия на этапе подготовки данных. Здесь мы сделали все для построения канонической схемы «звезда», избавив себя от необходимости поддержки составных ключей. Это был способ с использованием редактора Po­wer Query, а теперь давайте посмотрим, как можно управлять составными ключами на вкладке Модель в  Po­wer BI. Для этого мы воспользуемся подходящим примером из файла Adventure Works DW (with Exchange Rates).pbix, который можно загрузить по адресу https://github.com/PacktPublishing/Expert-Data-Modeling-with-Po­wer-BI/ blob/master/Adventure%20Works%20DW%20(with%20Exchange%20Rates).pbix. Итак, у нас есть таб­ли­ца Internet Sales с данными о продажах (Sales Amount) в разных валютах. Но руководству хотелось бы видеть продажи в долларах (USD). На рис. 8.30 показана модель данных на макете Internet Sales. Мы уже решали эту задачу в главе 2, когда говорили о виртуальных таб­ ли­цах. Здесь мы реализуем решение при помощи связи между таб­ли­ца­ми Exchange Rates и Internet Sales.

Использование связей    313

Рис. 8.30    Макет Internet Sales на вкладке Модель

Если взглянуть на таб­ли­цу Exchange Rates, можно обнаружить, что столбец CurrencyKey в ней не является первичным ключом, поскольку содержит массу дубликатов. На рис. 8.31 видно, что в таб­ли­це Exchange Rates содержится 14 264 строки, тогда как уникальных значений в столбце CurrencyKey всего 14.

Рис. 8.31    Столбец CurrencyKey не является первичным ключом в таб­ли­це Exchange Rates

314    Элементы моделирования данных Столбец Date также не является первичным ключом таб­ли­цы Exchange Rates. В то же время комбинация этих двух столбцов даст нам большую кратность. Объединив воедино столбцы CurrencyKey и Date, мы получим требуемый первичный ключ для таб­ли­цы Exchange Rates. Воспользуемся следующим выражением на языке DAX для создания в  таб­ли­це Exchange Rates нового вычисляемого столбца с именем ExchKey: ExchKey = VALUE('Exchange Rates'[CurrencyKey] & FORMAT('Exchange Rates'[Date]; "yyyymmdd"))

На рис. 8.32 показана кратность столбца ExchKey.

Рис. 8.32    Добавление первичного ключа в таб­ли­цу Exchange Rates

Также мы должны создать соответствующий внешний ключ в таб­ли­це Internet Sales. Для этого можно воспользоваться следующим выражением DAX: ExchKey = VALUE('Internet Sales'[CurrencyKey] & 'Internet Sales'[OrderDateKey])

Теперь создадим связь между таб­ли­ца­ми Exchange Rates и Internet Sales по ключу ExchKey. В присутствии этой связи можно создать меру с использованием гораздо более простого по сравнению с примером из главы 2 выражения DAX, приведенного ниже: Internet Sales in USD = SUMX( RELATEDTABLE('Exchange Rates') ; [Internet Sales] * 'Exchange Rates'[AverageRate] )

При выводе мер Internet Sales и  Internet Sales in USD в таб­ли­це бок о  бок результат будет таким, как показано на рис. 8.33.

Использование связей    315

Рис. 8.33    Новая версия меры Internet Sales in USD

Этот пример ярко демонстрирует, насколько правильные методы моделирования данных могут облегчить выражения, которые вы будете использовать в вычислениях в дальнейшем. Давайте просто вспомним, какую меру нам пришлось писать в главе 2 в отсутствие связи между таб­ли­ца­ми Exchange Rates и Internet Sales: Internet Sales USD = SUMX( NATURALINNERJOIN ( SELECTCOLUMNS( 'Internet Sales' ; "CurrencyKeyJoin"; 'Internet Sales'[CurrencyKey] * 1 ; "DateJoin"; 'Internet Sales'[OrderDate] + 0 ; "ProductKey"; 'Internet Sales'[ProductKey] ; "SalesOrderLineNumber"; 'Internet Sales'[SalesOrderLineNumber] ; "SalesOrderNumber"; 'Internet Sales'[SalesOrderNumber] ; "SalesAmount"; 'Internet Sales'[SalesAmount] ) ; SELECTCOLUMNS ( 'Exchange Rates' ; "CurrencyKeyJoin"; 'Exchange Rates'[CurrencyKey] * 1 ; "DateJoin"; 'Exchange Rates'[Date] + 0 ; "AverageRate"; 'Exchange Rates'[AverageRate] ) ) ; [AverageRate] * [SalesAmount] )

316    Элементы моделирования данных В Po­wer BI мы можем объединять две таб­ли­цы путем создания связи от столбца из одной таб­ли­цы к  столбцу из другой. При этом в  реляционных моделях данных используется три вида кратностей связей: «один к одному», «один ко многим» и «многие ко многим». В следующих разделах мы кратко обсудим все виды кратности по отдельности.

Связь «один к одному» Связью «один к  одному» (one-to-one relationship) называется объединение таб­лиц по первичным ключам с обеих сторон. В этом случае каждой строке из первой таб­ли­цы будет соответствовать ноль или одна строка из второй. По этой причине фильтрация в таких связях в Po­wer BI всегда будет двунаправленной. При наличии между таб­ли­ца­ми связи типа «один к одному» мы потенциально можем объединить содержащиеся в  них данные в  одну таб­ ли­цу, если это не противоречит бизнес-логике. Мы обычно не рекомендуем создавать связи такого типа без особой необходимости.

Связь «один ко многим» Связь «один ко многим» (one-to-many relationship) является наиболее распространенной при моделировании данных. В  этом случае одной строке в  первой таб­ли­це может соответствовать несколько строк во второй. Для индикации такого типа связей в Po­wer BI Desktop используются символы 1 и * на разных концах линии.

Связь «многие ко многим» Связь «многие ко многим» (many-to-many relationship) характеризует ситуацию, в которой одной строке из первой таб­ли­цы может соответствовать несколько строк из второй и наоборот. И хотя в классической схеме «звезда» все связи между измерениями и таблицей фактов должны обладать кратностью «один ко многим», связи типа «многие ко многим» также можно создавать средствами Po­wer BI. При этом в случае создания такой связи отпадает необходимость обозначать одну из участвующих в  объединении таб­лиц как первичную. Связь «многие ко многим» по умолчанию предполагает двунаправленное распространение фильтрации, но мы можем изменить это поведение при помощи специфических настроек. Для индикации такого типа связей в Po­wer BI Desktop применяются символы * на обоих концах линии. Блестящий пример применения связей типа «многие ко многим» содержится в  файле Chapter 8, Data Modelling and Star Schema.pbix. Здесь мы отталкиваемся от требования бизнес-логики, состоящего в  необходимости формировать аналитические отчеты по агрегированной таб­ли­це Customers with Yearly Income Greater Than $100,000 на более высоких уровнях гранулярности, таких как квартал (Quarter) или год (Year). Для удовлетворения этого требования нам необходимо создать связь между таб­ли­ца­ми Sales for

Использование связей    317

Customers with Yearly Income Greater Than $100,000 и Date с использованием столбца Year-Month в обеих таб­ли­цах. При этом в выпадающем списке Направление кросс-фильтрации (Cross filter direction) мы выбираем вариант Один (Single), чтобы таб­ли­ца Date фильтровала таб­ли­цу Sales for Customers with Yearly Income Greater Than $100,000. На рис.  8.34 показано, как должно выглядеть диалоговое окно Создание связи (Create relationship) при объединении таб­лиц.

Рис. 8.34    Создание связи «многие ко многим»

На рис.  8.34 видно предупреждение, сообщающее о  том, что связь типа «многие ко многим» может быть использована в случае отсутствия гарантии уникальности использующихся для объединения столбцов. Таким образом, при создании связей такого типа нужно быть очень осторожными и точно понимать, что и для чего мы делаем. На рис. 8.35 показан пример отображения данных после создания связи.

318    Элементы моделирования данных

Рис. 8.35    Визуализация данных на основе связи «многие ко многим»

Здесь важно отметить гранулярность представленных данных. Как видно на рис. 8.35, мы можем анализировать данные на уровне Year и Month. Но если спуститься на один уровень ниже, данные по-прежнему будут представлены на уровне Year-Month. Таким образом, очень важно выбрать подходящие уровни гранулярности в  отчетах для пользователей, чтобы не сбивать их с толку неожиданными значениями. ПРИМЕЧАНИЕ  В общем случае мы не советуем использовать связи «многие ко многим» из-за чрезвычайного повышения уровня сложности модели данных, особенно если объединенные таким образом таб­ли­цы связаны и с другими таб­ли­ца­ми в модели. Ситуация может усугубиться, если в  списке Направление кросс-фильтрации (Cross filter direction) для связи выбрать вариант Двунаправленная (Both). Это может повлечь за собой необходимость написания очень сложных выражений на языке DAX, что, в  свою очередь, негативно скажется на быстродействии модели. Вместо этого лучше создавать связи типа «многие ко многим» с использованием промежуточных таб­лиц-мостов. Подробно об этом мы будем говорить в главе 9.

Распространение фильтров Распространение фильтров (filter propagation) представляет собой одну из важнейших концепций при проектировании моделей данных в  Po­wer BI Desktop. Создавая связь между двумя таб­ли­ца­ми, мы одновременно выполняем фильтрацию данных в  одной таб­ли­це в  соответствии с  данными во второй. На вкладке Модель можно увидеть направление распространения фильтра для каждой из присутствующих связей. На рис. 8.36 показана связь между таб­ли­ца­ми Product и Sales, а также направление фильтрации. По связи, показанной на рис. 8.36, можно сказать следующее:   каждая строка в таб­ли­це Product (сторона связи «один») соотносится с несколькими строками в таб­ли­це Sales (сторона связи «многие»);   при установке фильтра в таб­ли­це Product он распространится по связи от этой таб­ли­цы на таб­ли­цу Sales.

Использование связей    319

Направление распространения фильтра

Рис. 8.36    Направление распространения фильтра для связи

На рис. 8.37 показано, как фильтр распространяется с таб­ли­цы Product на таб­ли­цу Sales по связи.

ProductKey = 57

Фильтр: ProductKey = 57

Рис. 8.37    Распространение фильтра по связи

Как видно на рис.  8.37, при выборе в  таб­ли­це Product строки, в  которой атрибут ProductKey равен 57, мы автоматически фильтруем таб­ли­цу Product, а с ней и таб­ли­цу Sales (по связи). Таким образом, в таб­ли­це Sales останутся только данные с  атрибутом ProductKey, равным 57. И хотя фильтр по полю ProductKey распространился с таб­ли­цы Product на таб­ли­цу Sales, дальше он не пошел. Причина в том, что таб­ли­ца Sales не объединена с другими таб­ли­ ца­ми связями, по которым фильтр из нее может распространиться далее. На рис. 8.38 показано, как фильтрация на таб­ли­цу Sales распространяется сразу из двух таб­лиц. По рис. 8.38 видно, что хотя фильтры и распространяются с таб­лиц Product и Date на таб­ли­цу Sales, в обратном направлении они не идут. Следовательно, выбор строк в таб­ли­це Sales не может повлиять на фильтрацию таб­ли­цы Date с таким образом настроенной связью.

320    Элементы моделирования данных

Таблица Product фильтрует таблицу Sales

Таблица Date фильтрует таблицу Sales

Рис. 8.38    Распространение фильтра по двум связям

Двунаправленные связи Теперь, когда мы знаем, что из себя представляет распространение фильт­ра, нам будет несложно понять, что такое двунаправленные связи (bidirectional relationship) и  как они влияют на процесс моделирования данных. Связь становится двунаправленной при выборе в  выпадающем списке Направление кросс-фильтрации (Cross filter direction) в  ее свойствах варианта Двунаправленная (Both). Пользу от возможности направить фильтрацию данных в  обе стороны трудно переоценить, поскольку она позволяет разрешать определенные трудности при визуализации. Характерным примером является использование двух срезов на странице отчета: один из них фильтрует данные по столбцу ProductCategory, второй – по Full Name (срез Customer Name). Пользователь ожидает, что при выполнении фильтрации в обоих срезах будут отображаться только нужные данные. На рис. 8.39 показан описываемый сценарий.

Рис. 8.39    Срез Customer Name фильтрует таб­ли­цу Sales, но не затрагивает срез Product Category

Использование связей    321

Как видно на рис. 8.39, при выборе определенного элемента в срезе Customer Name фильтр распространяется с  таб­ли­цы Customer на таб­ли­цу Sales по связи, настроенной между ними. В результате на визуальном элементе, отражающем продажи, остается только нужная нам информация. В  нашем примере это позволяет нам быстро определить, что Аарон Кэмпбелл (Aaron Campbell) приобретал у  нас только товары из групп Accessories и  Bikes. Но в срезе Product Category по-прежнему отображаются все категории товаров, доступные в нашей модели данных. На рис. 8.40 показано, как между собой связаны таб­ли­цы Product, Customer и Sales.

Рис. 8.40    Связи между таб­ли­ца­ми Product, Customer и Sales

Пользователь ожидает, что при выполнении той фильтрации, которую мы сделали, в  срезе Product Category останутся только категории Accessories и Bikes. Одним из способов решения этой проблемы является настройка двунаправленной связи между таб­ли­ца­ми Sales и Product. Чтобы сделать это, выполните следующие действия. 1. Переключитесь на вкладку Модель. 2. Дважды щелкните мышью по связи между таб­ли­ца­ми Product и Sales. 3. Выберите в  выпадающем списке Направление кросс-фильтрации (Cross filter direction) вариант Двунаправленная (Both). 4. Нажмите на кнопку OK. На рис. 8.41 показаны эти действия.

322    Элементы моделирования данных

Двойной щелчок

Рис. 8.41    Создание двунаправленной связи

На рис. 8.42 видно, как изменится внешний вид связи на вкладке Модель.

Рис. 8.42    Визуальное представление двунаправленной связи

Теперь, вернувшись на вкладку Отчет, вы увидите, что изменение типа связи на двунаправленную позволило решить проблему. На рис. 8.43 показан обновленный отчет.

Заключение    323

Рис. 8.43    Теперь срез Customer Name фильтрует как данные из таб­ли­цы Sales, так и второй срез Product Category

А что, если пользователь выберет не покупателя, а  категорию товара? В этом случае фильтр распространится по связи на таб­ли­цу Sales, но дальше – к таб­ли­це Customer – не пойдет, поскольку связь между таб­ли­ца­ми Sales и Customer носит однонаправленный характер. Эту проблему можно решить, если и ее сделать двунаправленной. В связи со всем сказанным выше возникает резонный вопрос: а не сделать ли нам все связи в модели данных двунаправленными? Но мы спешим вас предостеречь от этого шага. Использование двунаправленных связей может негативно сказываться на производительности моделей, особенно когда речь идет о  больших объемах данных и  наличии сложных связей между таб­ли­ ца­ми. Кроме того, присутствие в модели большого числа двунаправленных связей непременно скажется и на сложности выражений DAX. В общем случае рекомендуется избегать создания таких связей везде, где это возможно. Сценарии, подобные тому, что мы рассмотрели в этой главе, можно решать и с помощью других техник, без использования двунаправленных связей. Но об этом речь пойдет в главе 9.

Заключение В этой главе мы познакомились с элементами моделирования данных в Po­ wer BI Desktop. Мы узнали, какие свойства есть у  таб­лиц и  столбцов, как определять рекомендуемые таб­ли­цы и  делать их доступными для других сотрудников организации. Также мы научились создавать агрегированные вычисляемые таб­ли­цы с помощью выражений DAX. После этого погрузились в одну из важнейших областей моделирования данных, связанную с объединением таб­лиц. Мы поговорили о типах связей, узнали, как распространяются фильтры, а также познакомились с концепцией двунаправленных связей. В следующей главе мы более подробно поговорим о техниках и приемах, с которыми вы встретились при прочтении этой главы.

Глава

9 Схема «звезда» и распространенные техники при моделировании данных

В предыдущей главе мы много узнали о составляющих элементах моделирования данных в Po­wer BI Desktop, а в этой обратимся к наиболее популярным приемам и техникам при работе со схемой «звезда». Основные темы, которые мы затронем в главе:   работа со связями типа «многие ко многим»;   повышенная бдительность при использовании двунаправленных связей;   работа с неактивными связями;   использование конфигурационных таб­лиц;   минусы создания вычисляемых столбцов;   организация модели данных;   уменьшение размера модели путем отказа от автоматических таб­лиц с датами и временем. На протяжении этой главы мы будем работать с  файлом Chapter 9, Star Schema and Data Modelling Common Best Practices.pbix.

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

Работа со связями типа «многие ко многим»    325

таб­лиц по неключевым полям. И хотя создание таких связей может быть оправдано в небольших по объему моделях данных, в более сложных примерах это может стать серьезной проблемой, особенно если вы не до конца понимаете, что и зачем делаете. Допустим, у вас могут неправильно считаться итоги, появляться пропущенные значения или страдать производительность в  объемных моделях данных. Но при правильном использовании ничего такого может и не быть. Основной посыл состоит в том, чтобы использовать связи типа «многие ко многим» только при исключительной необходимости, для удовлетворения требований бизнес-логики. В предыдущей главе мы рассмотрели сценарий, в котором кратность связи «многие ко многим» сработала идеально. Если помните, в том примере мы строили отчеты о продажах по агрегированной таб­ли­це Customers with Yearly Income Greater Than $100,000. Мы создали вычисляемую таб­ли­цу на уровне гранулярности Customer, Product и  Year-Month. Для удовлетворения требований бизнес-логики мы связали таб­ли­цы Sales for Customers with Yearly Income Greater Than $100,000 и  Date по полю Year-Month. На рис. 9.1 показана диаграмма со связью «многие ко многим» между этими таб­ли­ца­ми.

Рис. 9.1    Связь с кратностью «многие ко многим»

В представленной модели данных столбец Year-Month не является ключевым ни в одной из связанных таб­лиц, а значит, в этом поле могут содержаться дублирующиеся значения. При объединении таб­лиц по неключевым полям создается связь с кратностью (cardinality) «многие ко многим». Мы настаиваем на использовании термина кратность для данного вида связи, чтобы вы не путали его с классической связью «многие ко многим». Факти-

326    Схема «звезда» и распространенные техники при моделировании данных чески в реляционных моделях данных связь «многие ко многим» существует лишь в  виде концепции соединения двух таб­л иц посредством таб­л и­ц ымоста (bridge table). На самом деле в  классической реляционной модели мы не можем создать физическую связь «многие ко многим» между двумя таб­ли­ца­ми. Вместо этого мы обязаны основывать связи на первичном ключе на стороне «один» и  внешнем  – на стороне «многие». Таким образом, в реляционной модели допустимо создавать только связи типа «один к одному» и  «один ко многим». А  связей типа «многие ко многим» просто не существует. Несмотря на это, во многих сценариях наличие таких связей крайне необходимо. К примеру, один клиент банка может владеть несколькими счетами, а  к  одному счету может быть прикреплено несколько клиентов, если речь идет об общем счете. Или у одного студента может быть несколько учителей, так же, как у одного учителя может быть несколько студентов. Давайте рассмотрим сценарий из файла Chapter 9, Star Schema and Data Modelling Common Best Practices.pbix. Нам требуется изучить покупательское поведение потребителей по количеству проданных товаров и источнику информации, благодаря которому покупатель узнал о нас. Назовем это причиной продажи и будем хранить в таб­ли­це Sales Reasons. На рис. 9.2 представлена модель данных, с которой мы начнем работать.

Рис. 9.2    Анализ таб­ли­цы Internet Sales по таб­ли­це Sales Reasons

Работа со связями типа «многие ко многим»    327

Как видите, у  нас есть таб­ли­ца Sales Reasons с  описательными данными по причинам продаж и таб­ли­ца Internet Sales Reasons, объединенная с таб­ лицей Sales Reasons связью «один ко многим». Если присмотреться к  таб­ ли­це Internet Sales Reasons внимательнее, можно обнаружить, что она не содержит никаких транзакций. Вместо этого она насчитывает три столбца: SalesOrderLineNumber, SalesOrderNumber и  SalesReasonKey. Также у  нас есть таб­ли­ца Customer, объединенная с таблицей Internet Sales связью типа «один ко многим». Все транзакции собраны в таб­ли­це Internet Sales, уникальность строк в которой обеспечивается совокупностью столбцов SalesOrderLineNumber и  SalesOrderNumber. Обратите внимание, что таб­ли­цы Customer и  Sales Reasons в  данный момент не связаны. У  каждого покупателя может быть множество причин для покупки товаров в нашем магазине, и одна причина может относиться к разным покупателям. Таким образом, между таб­ли­ца­ми Customer и Sales Reason концептуально должна присутствовать связь «многие ко многим». А теперь вернемся к классическому типу связи «многие ко многим» в реляционной модели данных. Как мы уже говорили ранее, в ней, в отличие от Po­wer BI, связи «многие ко многим» допустимо создавать только с использованием таб­ли­цы-моста.

Связи «многие ко многим» с использованием таблицы-моста В классической реляционной модели данных для образования связи «многие ко многим» мы собираем первичные ключи из обеих таб­лиц в новой таб­ли­це, именуемой мостом (bridge table). Такие таб­ли­цы обычно бывают доступны в транзакционных источниках данных. К примеру, почти всегда в источнике присутствует связь «многие ко многим» между покупателями и товарами. Один покупатель может приобретать разные товары, и  один товар может быть приобретен разными покупателями. Что происходит в магазине, когда мы покупаем товары? Кассир сканирует все товары из нашей тележки, и информация о том, какой покупатель приобрел какие товары, заносится в систему. При использовании концепции «звезда» мы делим все таб­ли­цы в хранилище на измерения и факты. Таким образом, в модели данных продаж (хранилище продаж) всегда присутствуют связи типа «многие ко многим» между измерениями, окружающими факты, с использованием самих таб­лиц фактов. Итак, в нашей схеме «звезда» есть таб­ли­цы Customer и Product, содержащие описательные данные о покупателях и товарах. С точки зрения модели данных эти таб­ли­цы являются измерениями. Также у нас есть таб­ли­ца Internet Sales, в которой присутствуют внешние ключи для таб­лиц Customer и Product. Помимо этого, таб­ли­ца Internet Sales еще содержит числовые показатели, относящиеся к  транзакциям, такие как сумма продажи, величина налога, количество и т. д. С точки зрения схемы «звезда» таб­ли­ца Internet Sales является таблицей фактов. Между таб­ли­ца­ми Customer, Product и Internet Sales есть связи, которые показаны на рис. 9.3.

328    Схема «звезда» и распространенные техники при моделировании данных

Рис. 9.3    Связи между таб­ли­ца­ми Customer, Product и Internet Sales

В представленной модели созданы следующие связи:   связь «один ко многим» между таб­ли­ца­ми Customer и Internet Sales;   связь «один ко многим» между таб­ли­ца­ми Product и Internet Sales;   связь «многие ко многим» между таб­ли­ца­ми Customer и  Product (посредством Internet Sales). Первые две связи можно легко увидеть в модели, тогда как третья является, по сути, концептуальной связью с использованием промежуточной таб­ли­цы Internet Sales. С точки зрения схемы «звезда» таб­ли­цу Internet Sales нельзя назвать мостом, но в принципе она им является. Теоретически мостом принято называть таб­ли­цу, созданную специально для образования связи «многие ко многим». Такие связи обычно создаются между двумя и  более измерениями. Но бывает, что в связь «многие ко многим» оказываются вовлечены две таб­ли­цы фактов. Таб­ли­цы фактов, содержащие только внешние ключи измерений без других аддитивных показателей, называются фактами без метрик (factless fact). В нашей модели данных присутствует подходящая таб­ли­ца-мост для создания связи «многие ко многим» между таб­ли­ца­ми Customer и Internet Sales Reasons. Нам только нужно связать таб­ли­цы Internet Sales и Internet Sales Reasons (мост). Но мы знаем, что движок xVelocity не поддерживает создание физических связей с участием составных ключей. В связи с этим нам придется добавить дополнительные столбцы в таб­ли­цы Internet Sales и Internet Sales Reasons, объединяющие информацию из столбцов SalesOrderLineNumber и  SalesOrderNumber. Это можно сделать как в  редакторе Po­wer Query, так и при помощи DAX. Для простоты мы выберем второй вариант. Итак, создадим в  таб­ли­це Internet Sales новый вычисляемый столбец со следующим выражением DAX:

Работа со связями типа «многие ко многим»    329 SalesReasonsID = 'Internet Sales'[SalesOrderNumber] & 'Internet Sales'[SalesOrderLineNumber]

Для создания парного столбца в таб­ли­це Internet Sales Reasons воспользуемся следующим выражением DAX: SalesReasonsID = 'Internet Sales Reasons'[SalesOrderNumber] & 'Internet Sales Reasons'[SalesOrderLineNumber]

Теперь, когда мы создали столбец SalesReasonsID в обеих таб­ли­цах, используем его для связки. На рис.  9.4 показано диалоговое окно создания связи «один ко многим» между таб­ли­ца­ми Internet Sales и Internet Sales Reasons.

Рис. 9.4    Создание связи между таб­ли­ца­ми Internet Sales и Internet Sales Reasons

На рис. 9.5 представлена модель данных после создания этой связи. С точки зрения моделирования данных мы создали связь «многие ко многим» между таб­ли­ца­ми Internet Sales и Sales Reasons при помощи моста (таб­ ли­ца Internet Sales Reasons). А  значит, и  между таб­ли­ца­ми Customer и  Sales Reason также образовалась связь «многие ко многим». Давайте визуализируем наши данные и посмотрим, сможем ли мы проанализировать продажи по количеству и причинам, чего требует от нас бизнес-логика. Для вывода данных создадим меру Quantity Sold со следующей формулой DAX: Quantity Sold = SUM('Internet Sales'[OrderQuantity])

330    Схема «звезда» и распространенные техники при моделировании данных

Рис. 9.5    Модель данных после создания связи между таб­ли­ца­ми Internet Sales и Internet Sales Reasons

Выполните следующие действия для создания отчета. 1. Расположите в рабочей области отчета визуальный элемент Матрица (Matrix). 2. Перетащите поле Full Name из таб­ли­цы Customer в  область Строки (Rows). 3. Перетащите поле Sales Reason Name из таб­ли­цы Sales Reasons в область Столбцы (Columns). 4. В область Значения (Values) вынесите меру Quantity Sold. На рис. 9.6 схематически показаны эти действия. При взгляде на этот отчет легко заметить проблему. Значения меры Quantity Sold повторяются для поля Sales Reason Name. Причина такого поведения кроется в распространении действия фильтра: фильтр по Full Name распространяется из таб­ли­цы Customer на таб­ли­цу Internet Sales, поэтому мера Quantity Sold по клиентам считается корректно. В то же время поле Sales Reason Name не может отфильтровать таб­ли­цу Internet Sales, поскольку в данный момент направление кросс-фильтрации для связи между таб­ли­ца­ми Internet Sales и Internet Sales Reasons установлено в значение Однонаправленная (Single). Связь между этими таб­ли­ца­ми имеет кратность «один ко многим» – на стороне «один» располагается таб­ли­ца Internet Sales, а на стороне «многие» – Internet Sales Reasons. Таким образом, фильтр между этими таб­ли­ца­ми распространяется в направлении от таб­ли­цы

Работа со связями типа «многие ко многим»    331

Internet Sales к таб­ли­це Internet Sales Reasons, но не наоборот. Давайте откроем связь между этими таб­ли­ца­ми и установим двунаправленное распространение кросс-фильтрации. На рис. 9.7 показано, как это можно сделать.

Рис. 9.6    Визуализация имени клиента, причины продажи и количества с помощью матрицы

Рис. 9.7    Установка двунаправленной кросс-фильтрации для связи

332    Схема «звезда» и распространенные техники при моделировании данных Вернувшись к матрице, мы обнаружим, что цифры исправились. На рис. 9.8 показан корректный отчет после изменения характеристик связи.

Рис. 9.8    Правильный отчет после установки двунаправленной кросс-фильтрации

Глядя на строку с итогами, можно понять, что цена (Price) является главным мотивирующим фактором для клиентов покупать товары – показатели меры Quantity Sold здесь наибольшие. Но есть в этих данных кое-что, сбивающее с толку, а именно итоговые значения по строкам, не соответствующие значениям в матрице. Взгляните на подсвеченную строку. Итоговое значение по строке равно четырем, хотя, если верить данным в таб­ли­це, должно быть на единицу больше. Причина в  том, что связь между таб­ли­ца­ми Customer и Sales Reasons имеет тип «многие ко многим», а у покупателя может быть больше одной причины для покупки товара. В подсвеченной строке у Аарона Вана (Aaron Wang) было явно больше одной причины. Давайте убедимся в этом. Для этого создадим еще одну матрицу, на этот раз с анализом меры Quantity Sold по данным из таб­лиц Product и Sales Reasons. После этого выделим интересующего нас покупателя в первой матрице и узнаем, что и почему он покупал. 1. Расположите в рабочей области отчета еще один визуальный элемент Матрица (Matrix). 2. Перетащите поле Product Name из таб­ли­цы Product в  область Строки (Rows). 3. Перетащите поле Sales Reason Name из таб­ли­цы Sales Reasons в область Столбцы (Columns). 4. В область Значения (Values) также вынесите меру Quantity Sold. На рис.  9.9 показан отчет с  выделенным покупателем, информация по которому нас так заинтересовала.

Работа со связями типа «многие ко многим»    333

Рис. 9.9    Вывод меры Quantity Sold по таблицам Product и Sales Reasons с фильтрацией по покупателю

Как видно на рис. 9.9, у Аарона было целых две причины (производитель (Manufacturer) и качество (Quality)) для покупки товара Road-150 Red, 52, но при этом он приобрел один товар, что и объясняет единицу в качестве итогового значения в строке. Однако такая математика может сбить с толку не подготовленного к подобной бизнес-логике конечного пользователя. В таком случае у нас есть два варианта: отключить вывод подытогов или изменить код меры Quantity Sold следующим образом: Quantity Sold = IF( HASONEVALUE('Sales Reasons'[SalesReasonKey]) ; SUM('Internet Sales'[OrderQuantity]) ; BLANK() )

Скрытие таблицы-моста После создания в  модели данных связи типа «многие ко многим» бывает удобно скрыть таб­ли­цу-мост, поскольку она нужна исключительно для хранения ключевых столбцов связанных таб­лиц. Скрытие таб­ли­цы-моста также позволяет не вводить в заблуждение пользователей, подключающихся к набору данных для построения отчетов. Чтобы скрыть таб­ли­цу, достаточно переключиться на вкладку Модель и  нажать на кнопку скрытия таб­ли­цы

334    Схема «звезда» и распространенные техники при моделировании данных (с изображением глаза) в правой части ее заголовка. На рис. 9.10 показана модель данных со скрытой таблицей Internet Sales Reasons.

Рис. 9.10    Скрытие таб­ли­цы в модели данных

Повышенная бдительность при использовании двунаправленных связей Одной из особенностей Po­wer BI, которую разработчики часто неправильно понимают и используют, является двунаправленность связей. Нет ничего зазорного в создании двунаправленных связей (bidirectional relationship), если вы хорошо понимаете, что делаете, и  осознаете влияние этих связей на модель данных. Бывает, что разработчики слишком увлекаются созданием связей обоюдной направленности и в результате получают запутанную модель данных и неправильные цифры в вычислениях. А иногда они даже лишаются возможности создания новых связей из-за неоднозначностей в модели данных, причина появления которых кроется в распространении фильтров. В  главе 8 мы познакомились с  концепциями распространения фильтров и двунаправленных связей. Если помните, мы рассмотрели сценарий, в котором нам необходимо было разместить в отчете два среза: один для категории товаров, второй для клиентов. Это один из тех случаев, ког-

Повышенная бдительность при использовании двунаправленных связей    335

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

Рис. 9.11    Модель данных с таблицей Internet Sales

На рис. 9.12 условно показаны требования к отчету. Как видно на рис. 9.12, срез Customer Name фильтрует таб­ли­цу Internet Sales, но при этом не распространяется на второй срез Product Category, поскольку связь между таб­ли­ца­ми Product Category и Internet Sales является однонаправленной. В  результате фильтр распространяется в  направлении от таб­ли­цы Product Category к таб­ли­це Internet Sales, но не наоборот. Давайте попробу-

336    Схема «звезда» и распространенные техники при моделировании данных ем решить эту задачу без физического создания двунаправленных связей. Одним из способов является программная установка двунаправленности связи между таб­ли­ца­ми при помощи функции CROSSFILTER() в  DAX. Ниже представлена модифицированная мера Internet Sales Bidirectional, в которой программно создается двунаправленность связей между таб­ли­ца­ми Product, Internet Sales и Customer: Internet Sales Bidirectional = CALCULATE( SUM('Internet Sales'[SalesAmount]) ; CROSSFILTER(Customer[CustomerKey]; 'Internet Sales'[CustomerKey]; Both) ; CROSSFILTER('Product'[ProductKey]; 'Internet Sales'[ProductKey]; Both) )

Рис. 9.12    Срез Customer Name фильтрует продажи, но не влияет на данные из среза Product Category

Теперь попробуем вынести созданную меру в визуальный элемент Мат­ рица. Кроме того, нам нужно добавить новую меру в раздел Фильтры для этого визуального элемента (Filters on this visual) для обоих срезов, а в выпадающем списке Показывать элементы, когда значение (Show items when the value) выбрать вариант Не является пустым (Is not blank). На рис. 9.13 показано, как это можно сделать.

Выберите срез и переместите меру Internet Sales Bidirectional в визуальный фильтр

Рис. 9.13    Использование меры в качестве фильтра для визуального элемента в срезе

Работа с неактивными связями    337

Как видно на рис. 9.13, теперь срез Customer Name успешно фильтрует срез Product Category и наоборот. Приведенные ниже действия выполняются для среза Customer Name. То же самое происходит и для среза Product Category. 1. Срез получает список всех клиентов из столбца Full Name. 2. Вступает в действие визуальный фильтр. Используемая в фильтре мера Internet Sales Bidirectional при выполнении исключает все пустые значения. 3. Также мера Internet Sales Bidirectional на период своего выполнения делает связи между таб­ли­ца­ми Product, Internet Sales и Customer двунаправленными. Если ничего не выбирать в срезах, в них будут показываться элементы, для которых есть как минимум одна строка в таб­ли­це Internet Sales. Ключевой посыл заключается в  том, что не стоит прибегать к  помощи двунаправленных связей без четкого понимания, что и для чего вы делаете. В отсутствие таких связей выражения DAX могут стать более громоздкими и менее производительными. Вы как разработчик должны сами решить, что будет лучше для вашей конкретной модели данных.

Работа с неактивными связями В реальных сценариях модели данных зачастую бывают достаточно сложными, особенно когда речь идет о  поддержке BI-систем на крупных предприятиях. В таких условиях в  моделях могут появляться неактивные связи (inactive relationship) между таб­ли­ца­ми. В большинстве случаев причина возникновения подобных связей будет одной из следующих:   таб­ли­ца с неактивной связью оказалась доступна по нескольким путям фильтра;   между двумя таб­ли­ца­ми настроено несколько прямых связей. В обоих случаях движок не позволит активировать связь, являющуюся неактивной, чтобы не допустить возникновения неоднозначности (ambiguity) в модели данных.

Доступность таблицы по нескольким путям фильтра Путь фильтра (filter path) образуется в ситуациях, когда две таб­ли­цы связаны между собой посредством других таб­лиц. В этом случае фильтр может распространяться с одной таб­ли­цы на другую в несколько этапов. На рис. 9.14 показана модель данных с одной неактивной связью. Как видно на рис.  9.14, между таб­ли­ца­ми Sales Territory и  Internet Sales уже есть прямая связь. В результате в Po­wer BI возникает ошибка, связанная с тем, что активация связи между таб­ли­ца­ми Geography и Customer вызовет неоднозначность доступа из таб­ли­цы Sales Territory в таб­ли­цу Internet Sales. На рис. 9.15 видно, что в этом случае таб­ли­ца Internet Sales окажется доступна сразу по двум путям.

338    Схема «звезда» и распространенные техники при моделировании данных

Рис. 9.14    Неактивная связь по причине обнаружения нескольких путей фильтра

Рис. 9.15    Таб­ли­ца Internet Sales доступна сразу по двум путям фильтра

Вот что произойдет при установке фильтра на таб­ли­цу Sales Territory. 1. Фильтр распространится на таб­ли­цу Geography посредством связи между таб­ли­ца­ми Sales Territory и Geography. 2. После этого фильтр распространится на таб­ли­цу Customer по связи между таб­ли­ца­ми Geography и Customer. 3. И в  завершение фильтр достигнет таб­ли­цы Internet Sales, поскольку таб­ли­цы Customer и Internet Sales также связаны. Таким образом, таб­ли­цы Sales Territory и Internet Sales оказались связаны посредством других таб­лиц, что образовало один путь фильтра. В то же время эти две таб­ли­цы связаны напрямую (левая нижняя стрелка на рис. 9.15), что вносит неоднозначность в модель данных. Именно это стало причиной деактивации связи между таб­ли­ца­ми Geography и Customer.

Работа с неактивными связями    339

Несколько прямых связей между двумя таблицами Вторая распространенная причина появления в модели данных неактивных связей состоит в создании более одной прямой связи между двумя таб­ли­ца­ ми. Присутствие нескольких связей позволяет использовать каждую из них для выполнения своих аналитических расчетов. На рис. 9.16 показаны таб­ ли­цы Date и Internet Sales, объединенные несколькими связями.

Рис. 9.16    Две таб­ли­цы и несколько связей

Можно открыть диалоговое окно Управление связями (Manage relationships), чтобы лучше разобраться, что из себя представляют эти связи. На рис. 9.17 показано это окно. Мы видим, что со стороны таб­ли­цы Internet Sales в связях участвуют три разных поля, что вполне приемлемо. Каждая связь фильтрует таб­ли­цу с продажами по-своему, при этом в любой момент времени активной может быть лишь одна из них. В настоящее время активной является связь по столбцам OrderDateKey из таб­ли­цы Internet Sales и DateKey из таб­ли­цы Date, и именно по ней распространяются фильтры между этими таб­ли­ца­ми. Это означает, что при использовании столбца Year из таб­ли­цы Date и меры Internet Sales из таб­ли­цы Internet Sales мы будем фильтровать факты по году продажи. А что, если нам понадобится проанализировать продажи по полю Due Date? А по Ship Date? Очевидно, что мы не можем каждый раз физически менять активность связей. Но мы можем решить задачу программно, воспользовавшись функцией USERELATIONSHIP() языка DAX. Функция USERELATIONSHIP() активирует указанную связь на время выполнения расчета меры. Таким образом, для выполнения задуманного необходимо создать две новые меры. Следующее выражение DAX активирует связь DueDateKey ⇒ DateKey: Internet Sales Due = CALCULATE([Internet Sales] ; USERELATIONSHIP('Internet Sales'[DueDateKey]; 'Date'[DateKey]) )

340    Схема «звезда» и распространенные техники при моделировании данных А приведенное ниже выражение активирует связь ShipDateKey ⇒ DateKey: Internet Sales Shipped = CALCULATE([Internet Sales] ; USERELATIONSHIP('Internet Sales'[ShipDateKey]; 'Date'[DateKey]) )

Рис. 9.17    Таб­ли­цы Date и Internet Sales объединены тремя связями

Давайте используем созданные меры совместно с  мерой Internet Sales и столбцом Full Date из таб­ли­цы Date для определения различий. Результат показан на рис. 9.18.

Рис. 9.18    Программная активация неактивных связей

Использование конфигурационных таблиц    341

Использование конфигурационных таблиц Зачастую нам необходимо анализировать данные с разбивкой по кластерам. Допустим, нам может понадобиться рассмотреть продажи в  разрезе диапазонов цен за единицу товара или себестоимости либо проанализировать клиентскую базу по возрастным группам. Во всех этих примерах нас не интересуют конкретные значения. Вместо этого речь идет об анализе показателей по диапазонам значений. Также разбивка значений на группы бывает необходима при визуализации данных. К примеру, мы можем на всех визуальных элементах покрасить красным точки данных, для которых сумма продажи ниже среднего уровня. Это довольно продвинутый анализ, который можно использовать повторно в отчетах, не меняя при этом элементы визуализации. Для реализации описанного функционала нам нужно определить конфигурационные таб­ли­цы (configuration table). В последнем примере вы увидите, как моделирование данных может положительно влиять на их визуализацию.

Сегментирование Как мы уже упоминали, очень часто бизнесу требуется проводить анализ данных по кластерам. Такой вид анализа называется сегментированием (segmentation), поскольку мы разделяем интересующие нас значения на группы или сегменты. Давайте рассмотрим пример. Будем анализировать продажи в таб­ли­це Internet Sales по цене за единицу товара (Unit Price). Для этого сначала разобьем цены на диапазоны:   Low (низкая цена): значение поля UnitPrice в диапазоне от $0 до $50;   Medium (средняя цена): значение поля UnitPrice в диапазоне от $51 до $450;   High (высокая цена): значение поля UnitPrice в диапазоне от $451 до $1500;   Very high (очень высокая цена): значение поля UnitPrice свыше $1500. Вы могли бы подумать, что можно просто добавить вычисляемый столбец в  таб­ли­цу Internet Sales. Это так, но что, если нам в  будущем потребуется менять установленные диапазоны цен? В результате нам придется каждый раз менять вычисляемый столбец, что не очень-то хочется делать. Гораздо лучше будет объединить диапазоны цен по сегментам в отдельную таб­ли­цу. При этом хранить эту таб­ли­цу мы можем в файле Excel, доступном из общей папки OneDrive for Business. Это может быть список SharePoint, данные в котором можно менять по необходимости. Для простоты мы сохраним наши диапазоны с ценами в Po­wer BI при помощи инструмента Введите данные (Enter data). ПРИМЕЧАНИЕ  Мы не советуем подобным образом вводить данные в  реальных сценариях. Если потребуется изменить данные, придется делать это в отчете Po­wer BI Desktop и заново публиковать его в службе Po­wer BI.

342    Схема «звезда» и распространенные техники при моделировании данных На рис. 9.19 показана таб­ли­ца Unit Price Ranges, введенная в Po­wer BI вручную.

Рис. 9.19    Таб­ли­ца Unit Price Ranges

Теперь, когда у нас есть данные для работы в Po­wer BI, нужно создать вычисляемый столбец в таб­ли­це Internet Sales. В нем будет выполняться поиск соответствующего значения Price Range для любого UnitPrice в таб­ли­це Internet Sales. Для этого нужно сравнить значение в столбце UnitPrice для каждой строки в таб­ли­це Internet Sales со значениями столбцов From и To из таб­ли­цы Unit Price Ranges. Ниже приведено соответствующее выражение DAX: Price Range = CALCULATE( VALUES('Unit Price Ranges'[Price Range]) ; FILTER('Unit Price Ranges' ; 'Unit Price Ranges'[From] < 'Internet Sales'[UnitPrice] && 'Unit Price Ranges'[To] >= 'Internet Sales'[UnitPrice] ) )

На рис. 9.20 показано, как можно быстро проанализировать меру Internet Sales по значениям Price Range. Обратите внимание на сортировку данных на линейчатой диаграмме. Они не упорядочены ни по наименованию ценового диапазона, ни по значениям меры Internet Sales. В предыдущей главе мы уже говорили о сортировке столбцов, так что с этим вы справитесь самостоятельно. Вы можете выделить один столбик на диаграмме и посмотреть, какие товары входят в данный ценовой диапазон.

Динамическое условное форматирование с участием мер До сих пор мы уделяли бóльшую часть времени моделированию данных, поскольку решению проблем в этой области и посвящена книга. В этом разделе мы поговорим о важном аспекте визуализации данных – цветовом кодировании (color coding) информации, – и о том, как моделирование данных помогает облегчить подобные задачи. Цветовое кодирование позволяет очень наглядно представить информацию пользователю, что, безусловно, очень важно. И  в  этом разделе мы перекинем мостик от моделирования данных к их визуализации.

Использование конфигурационных таблиц    343

Рис. 9.20    Анализ таб­ли­цы Internet Sales по ценовым диапазонам

Кодировать информацию цветом на элементах визуализации можно было с самого появления Po­wer BI. В то же время условного форматирования многим визуалам пришлось ждать довольно долго. К счастью, сегодня эта функция доступна почти во всех базовых элементах визуализации Po­ wer BI Desktop и  во многих пользовательских. Давайте рассмотрим один сценарий. Руководство компании решило обогатить свои визуализации при помощи цвета, который должен динамически устанавливаться на основе значения меры Sales MoM%. В  этой мере рассчитывается процент изменения суммы продаж по сравнению с предыдущим месяцем. Наша конечная цель – визуа­ лизировать меру Sales MoM% при помощи гистограммы с группировкой. Цвет для каждой точки данных должен быть вычислен автоматически в соответствии с конфигурационной таблицей. На рис. 9.21 показана структура этой таб­ли­цы. 1. Первым делом нам необходимо ввести данные из этой таб­ли­цы в Po­wer BI. Назовем новую таб­ли­цу ConfigColour. На рис. 9.22 показана созданная таб­ли­ца ConfigColour в Po­wer BI Desktop.

344    Схема «звезда» и распространенные техники при моделировании данных

Рис. 9.21    Конфигурационная таб­ли­ца с цветовыми кодами

Рис. 9.22    Таб­ли­ца ConfigColour

2. Теперь нужно создать меру Sales MoM%. Для начала вычислим сумму продаж за предыдущий месяц (мера Sales LM) с помощью следующего выражения DAX: Sales LM = CALCULATE([Internet Sales] ; DATEADD('Date'[Full Date]; -1; MONTH) )

3. Далее нужно вычислить разницу между мерами Internet Sales и  Sales LM. Для этого применим следующее выражение: Sales MoM% = DIVIDE([Internet Sales] - [Sales LM]; [Sales LM])

4. Теперь создадим две текстовые меры. Первая будет извлекать соответствующее значение столбца ColourHex из конфигурационной таб­ли­цы, а вторая – из столбца Status. Обе меры будут в качестве критерия поиска использовать меру Sales MoM%.

Использование конфигурационных таблиц    345

Перед созданием текстовых мер давайте разберемся, как должна работать наша конфигурационная таб­ли­ца ConfigColour. Выделим ключевые моменты:   в таб­ли­це ConfigColour содержится десять строк;   в столбце ColourHex хранятся шестнадцатеричные коды цветов;   в столбце Range% содержатся значения в интервале от 0,1 до 1;   столбец Status хранит текстовое описание цветовых статусов;   в столбце Index находятся порядковые номера статусов. Здесь вроде все должно быть понятно, единственное уточнение можно сделать по поводу содержимого столбца Range%. После форматирования в виде процентов значения в этом столбце предстали в диапазоне от 10 % до 100 %. Но каждое значение здесь представляет не константу, а  целый диапазон. К примеру, значение 10 % означает интервал от 0 % до 10 %. Значение 20 % характеризует диапазон от 11 % до 20 % и т. д. Также стоит отметить, что форматирование в  виде процентов привело значения к  числам, кратным десяти (10, 20, 30 и т. д.). Новые текстовые меры должны извлекать значения столбцов ColourHex или Status на основе значения столбца Range% и  меры Sales MoM%. Таким образом, нам нужно определить диапазоны, в которые входят значения меры Sales MoM%, и сравнить их со значениями в столбце ColourHex. Приведенная ниже формула гарантирует, что значения меры Sales MoM% будут без остатка делиться на 10, что позволит осуществить их поиск в столбце ColourHex: CONVERT([Sales MoM%] * 10; INTEGER)/10

Эта формула работает следующим образом. 1. Сначала мы умножаем значение меры Sales MoM% на 10, чтобы получить результат в виде десятичного числа в диапазоне от 0 до 10 (с ситуациями, когда результат будет меньше нуля или больше десяти, мы справимся отдельно). 2. Затем преобразуем десятичное число в  целое, чтобы избавиться от знаков после запятой. 3. Наконец, делим результат на 10. При форматировании вычисления в виде процентов мы получим значение, кратное 10. При этом все значения ниже 10 % будут приравнены к 10 %, а больше 100 % – к 100 %. Пришло время создать текстовые меры. В результате вычисления следующего выражения DAX мы получим шестнадцатеричное значение цвета. Впоследствии мы будем использовать его в условном форматировании визуального элемента: Sales MoM% Colour = var percentRound = CONVERT([Sales MoM%] * 10; INTEGER)/10 var checkMinValue = IF(percentRound < 0,1; 0,1; percentRound) var checkMaxValue = IF(checkMinValue > 1; 1; checkMinValue) return CALCULATE( VALUES(ConfigColour[ColourHex])

346    Схема «звезда» и распространенные техники при моделировании данных ; FILTER( ConfigColour ; 'ConfigColour'[Range%] = checkMaxValue ) )

Переменные checkMinValue и  checkMaxValue служат для контроля за значе­ ния­ми, выходящими за определенные в конфигурационной таб­ли­це границы. Следующее выражение DAX извлекает статус из таб­ли­цы ConfigColour: Sales MoM% Description = var percentRound = CONVERT([Sales MoM%] * 10; INTEGER)/10 var checkMinValue = IF(percentRound < 0,1; 0,1; percentRound) var checkMaxValue = IF(checkMinValue > 1; 1; checkMinValue) return CALCULATE( VALUES(ConfigColour[Status]) ; FILTER( ConfigColour ; 'ConfigColour'[Range%] = checkMaxValue ) )

Теперь, когда мы создали наши текстовые меры, можно использовать их для условного форматирования визуального элемента (если оно поддерживается). В табл. 9.1 перечислены элементы визуализации, поддерживающие условное форматирование. Таб­ли­ца 9.1. Визуальные элементы Po­wer BI, допускающие условное форматирование Гистограмма с накоплением

Линейчатая диаграмма Гистограмма с группировкой с группировкой

Нормированная линейчатая диаграмма График и гистограмма Ленточная с группировкой диаграмма Диаграмма дерева Датчик Таб­ли­ца Матрица

Нормированная гистограмма Воронка Карточка

График и гистограмма с накоплением Точечная диаграмма Ключевой показатель эффективности

Следующие шаги позволят вам применить условное форматирование к гис­ тограмме с группировкой. 1. Перенесите на страницу отчета гистограмму с группировкой (Clustered column chart). 2. Переместите поле Year-Month из таб­ли­цы Date в область Ось (Axis). 3. Переместите меру Sales MoM% в область Значения (Values). 4. Переместите меру Sales MoM% Description в  область Подсказки (Tooltips). 5. Переключитесь на вкладку Форматирование визуального элемента (Format) на панели Визуализации (Visualizations). 6. Откройте область определения цветов для столбцов. 7. Нажмите на кнопку fx.

Использование конфигурационных таблиц    347

8. Выберите в  выпадающем списке форматирования пункт Значение поля (Field value). 9. Выберите меру Sales MoM% Colour в выпадающем списке. 10. Нажмите на кнопку OK. Эти шаги показаны на рис. 9.23.

Рис. 9.23    Применение условного форматирования к гистограмме с группировкой

На рис. 9.24 показан внешний вид диаграммы после применения условного форматирования.

Рис. 9.24    Гистограмма после применения условного форматирования

348    Схема «звезда» и распространенные техники при моделировании данных С использованием этой техники можно создавать самые разные визуализации, которые позволят быстро сделать выводы о ситуации. На рис. 9.25 показана страница отчета с анализом продаж по датам. Ниже я добавил мат­ рицу по месяцам и дням недели.

Рис. 9.25    Цветной отчет о продажах

Я использовал меру Sales MoM% Colour для цветового кодирования мат­ рицы. Каждая ячейка отражает продажи для конкретного дня недели в указанном месяце. При этом цвет показывает отклонение текущей продажи от продажи в аналогичный день недели месяцем ранее. Конечно, представленную визуализацию нельзя назвать идеальной, но трудно не согласиться с тем, что она позволяет быстрее считать нужную информацию по сравнению с обычной таблицей. В реальном сценарии можно было бы использовать больше цветов для отражения отрицательной динамики. Попробуйте сделать это самостоятельно в качестве домашнего задания.

Минусы создания вычисляемых столбцов Создание вычисляемых столбцов – это одна из наиболее важных возможностей DAX. Значения вычисляемых столбцов, как ясно из названия, рассчитываются на основе формул, а  значит, они недоступны ни в  источнике данных, ни в слое Po­wer Query. Эти значения вычисляются на этапе обновления данных и загрузки их в память. Очень важно отметить, что вычисляемые столбцы занимают место в памяти до момента полной выгрузки всей модели данных, что в случае с Po­wer BI означает закрытие файла в Po­wer BI Desktop или переключение на другое содержимое в службе Po­wer BI. После

Минусы создания вычисляемых столбцов    349

создания вычисляемые столбцы ведут себя точно так же, как и любые другие, на них можно ссылаться в других вычисляемых столбцах и таб­ли­цах, мерах, а также использовать для фильтрации визуальных элементов. Разработчики зачастую используют такие столбцы для упрощения сложных расчетов путем разбиения их на составляющие. В то же время мы настоятельно советуем вам избегать чрезмерного использования вычисляемых столбцов в своих проектах. При их создании вы можете руководствоваться следующими прос­тыми правилами:   создавайте вычисляемые столбцы, если вы собираетесь использовать их в фильтрах;   даже если вы собираетесь использовать вычисляемые столбцы в фильт­ рах, рассмотрите возможность создания необходимых столбцов в слое Po­wer Query;   не создавайте вычисляемый столбец, если для достижения того же эффекта можно обойтись мерой;   при создании вычисляемого столбца всегда держите в голове его кратность. Чем выше кратность, тем ниже будет степень сжатия и тем больше места в памяти будет занимать столбец;   создавайте вычисляемые столбцы только при наличии действительно веских причин для этого, особенно когда речь идет об объемных моделях данных;   используйте инструмент View Metrics в DAX Studio для отслеживания размера вычисляемого столбца, который напрямую связан с занимаемым им местом в памяти. Давайте взглянем на файл примера для этой главы. Перед нами стоит задача посчитать валовую прибыль (Gross Profit). Для этого нам нужно вычесть себестоимость из выручки. Можно создать вычисляемый столбец с  приведенной ниже формулой DAX, в котором будет вычислена валовая прибыль для всех строк в таб­ли­це Internet Sales: Gross Profit = 'Internet Sales'[SalesAmount] - 'Internet Sales'[TotalProductCost]

После этого можно создать меру Total Gross Profit для подсчета суммы по вычисляемому столбцу: Total Gross Profit with Calc Column = SUM('Internet Sales'[Gross Profit])

Давайте посмотрим на созданный вычисляемый столбец в DAX Studio для лучшего понимания происходящего. Выполните следующие действия. 1. В Po­wer BI Desktop перейдите на вкладку Внешние инструменты (External Tools). 2. Нажмите на кнопку DAX Studio. 3. В открывшемся окне DAX Studio перейдите на вкладку Advanced. 4. Нажмите на кнопку View Metrics. 5. Раскройте таб­ли­цу Internet Sales. 6. Найдите столбец Gross Profit. Эти шаги показаны на рис. 9.26.

350    Схема «звезда» и распространенные техники при моделировании данных

Рис. 9.26    Инструмент View Metrics в DAX Studio

На рис. 9.26 видно, что размер столбца Gross Profit составляет 15 480 байт (примерно 15 Кб), при этом его кратность равна 45, а занимает он 0,31 % от общего размера таб­ли­цы. Таб­ли­ца Internet Sales является относительно небольшой и насчитывает всего 60 398 строк. Но вы можете себе представить, как размер столбцов может увеличиваться в более объемных таб­ли­цах. И хотя никто не запрещает вам создавать вычисляемые столбцы, а затем рассчитывать суммы по ним в мерах, это не самый предпочтительный метод. Можно вычислить Total Gross Profit прямо в мере при помощи следующего выражения DAX: Total Gross Profit Measure = SUMX('Internet Sales'; 'Internet Sales'[SalesAmount] 'Internet Sales'[TotalProductCost])

Разница между двумя этими подходами заключается в том, что значения вычисляемого столбца Gross Profit рассчитываются в  момент обновления таб­ли­цы. В  результате столбец целиком помещается в  память, в то время как его оппонент в виде меры рассчитывается тогда, когда мы используем его в визуальном элементе. Таким образом, при вынесении столбца Product Category из таб­ли­цы Product на гистограмму с группировкой и использовании меры Total Gross Profit Measure ее значения будут агрегированы только для категорий товаров, находящихся в памяти. На рис. 9.27 показан расчет меры Total Gross Profit Measure по полю Product Category на гистограмме с группировкой. Как видите, мера Total Gross Profit Measure в данном случае была рассчитана лишь три раза, что положительно сказалось на быстродействии отчета и расходе ресурсов памяти.

Организация модели данных    351

Рис. 9.27    Мера Total Gross Profit Measure, рассчитанная по столбцу Product Category

Организация модели данных В реальных проектах Po­wer BI обычно предусмотрено множество различных ролей. Это и разработчики модели данных, и менеджеры отчетов, и специа­ листы по контролю качества, и  сотрудники службы поддержки… При этом только разработчики модели имеют доступ ко всем данным и делают их доступными для остальных. В связи с этим необходимо поддерживать организацию (organizing) модели на максимально возможном уровне. В этом разделе мы поговорим о способах организации модели данных.

Скрытие второстепенных объектов Одним из наиболее эффективных способов организации модели данных является скрытие объектов, не представляющих первостепенную значимость. Зачастую в модели могут присутствовать объекты, не использующиеся нигде. В то же время удалить их мы не можем, поскольку есть вероятность, что они понадобятся нам в будущем. Такие объекты лучше бывает скрыть до лучших времен – пока они не понадобятся. В  следующих секциях раздела мы рассмотрим главных кандидатов на то, чтобы быть скрытыми.

Скрытие неиспользуемых полей и таблиц Нередко бывает, что некоторые поля, меры, а порой и целые таб­ли­цы оказываются не задействованы в рабочем процессе. Для таких объектов обычно верны следующие утверждения:   они не используются ни в одном визуальном элементе ни на одной из страниц отчетов;   они не присутствуют на панелях фильтрации;   на них не ссылается ни одна мера, вычисляемый столбец, вычисляемая таб­ли­ца или группа вычислений;   они не задействуются ни в одной роли в рамках системы безопасности на уровне строк (RLS).

352    Схема «звезда» и распространенные техники при моделировании данных Если у вас есть таб­ли­цы или поля, для которых выполняются все эти условия, скорее всего, вы имеете дело с кандидатами на скрытие в модели данных. Наша цель – максимально организовать модель, так что вы по своему усмотрению можете скрывать объекты, для которых верны лишь некоторые из перечисленных утверждений. Также можно заметить, что таб­ли­цу можно считать неиспользуемой, если ни одно из ее полей не задействуется в работе модели данных. И хотя рекомендуется скрывать все неиспользуемые поля и таб­ли­цы в модели данных, зачастую на это может потребоваться достаточно времени. В частности, вручную проверить все объекты на их использование в других объектах, а также визуальных элементах бывает непросто. К  счастью, есть сторонние инструменты, способные облегчить эту задачу. К  примеру, вы можете воспользоваться инструментом Po­wer BI Documenter, который может не только найти все не используемые в данный момент объекты в  модели данных, но и скрыть их одним щелчком мыши. На рис. 9.28 показана панель Поля (Fields) до и после скрытия объектов при помощи утилиты Po­wer BI Documenter.

После скрытия неиспользуемых таблиц До скрытия неиспользуемых таблиц

Рис. 9.28    До и после использования инструмента Po­wer BI Documenter

Организация модели данных    353

На рис.  9.29 продемонстрировано содержимое таб­ли­цы Internet Sales до и после использования утилиты Po­wer BI Documenter.

После скрытия неиспользуемых полей

До скрытия неиспользуемых полей

Рис. 9.29    До и после использования инструмента Po­wer BI Documenter

Больше об инструменте Po­wer BI Documenter можно узнать по адресу www. datavizioner.com.

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

354    Схема «звезда» и распространенные техники при моделировании данных

Скрытие неявных мер Также мы спокойно можем убрать из видимости неявные меры. Мы говорили о различиях между явными и неявными мерами в главе 8. Хорошей практикой является создание явных мер для всех неявных мер, необходимых бизнесу, со скрытием последних. Это в том числе позволит избежать неопределенности в вопросе выбора мер для визуализаций со стороны пользователей, не очень хорошо знакомых со структурой модели.

Скрытие столбцов, использующихся в иерархиях, там, где это возможно При создании иерархий лучше скрывать в модели данных столбцы, на которых они основываются. В противном случае наличие одинаковых столбцов (в  исходных таб­л и­ц ах и  в  иерархиях) может вводить пользователей в  заблуждение. Так что их скрытие позволит снизить неопределенность при использовании отчетов для пользователей, подключающихся к нашим данным.

Создание таблиц мер Создание отдельной таб­ли­цы с  мерами в  Po­wer BI – тема довольно противоречивая. Некоторые эксперты советуют выделять меры в  обособленную таб­ли­цу для лучшей организации данных, другие высказывают аргументы против. Лично я  придерживаюсь мнения о  том, что этот прием действительно позволяет навести порядок в  модели данных, но при этом имеет ряд побочных эффектов. В следующем разделе мы поговорим об этом более подробно, а  сейчас просто узнаем, о  чем идет речь. Таб­ли­ца мер (measure table) не является таблицей с данными в нашей модели в привычном смысле, а создается исключительно с целью хранения в ней создаваемых мер. К примеру, в нашем простом отчете мы могли бы перенести все меры из таб­ли­цы Internet Sales в отдельную таб­ли­цу. Po­wer BI легко идентифицирует таб­ли­цы, в  которых хранятся только меры и  нет видимых столбцов, и  помечает их специальной иконкой ( ). Для создания таб­ли­цы мер выполните следующие действия. 1. Нажмите на кнопку Введите данные (Enter data). 2. Оставьте столбец с именем Столбец1 (Column1) как есть, с пустым значением. 3. Назовите таб­ли­цу Internet Sales Metrics. 4. Нажмите на кнопку Загрузить (Load).

Организация модели данных    355

Рис. 9.30    Ввод данных в Po­wer BI Desktop

5. Щелкните правой кнопкой мыши по столбцу Столбец1 (Column1) в таб­ ли­це Internet Sales Metrics. 6. Выберите пункт Скрыть (Hide).

Рис. 9.31    Скрытие столбца

356    Схема «звезда» и распространенные техники при моделировании данных Теперь можно перенести меры из таб­ли­цы Internet Sales в таб­ли­цу Internet Sales Metrics. Для этого сделайте следующее. 7. Откройте вкладку Модель. 8. Щелкните правой кнопкой мыши по таб­ли­це Internet Sales. 9. Выберите пункт Выбрать меры (Select measures) для выделения всех мер в таб­ли­це Internet Sales. На рис. 9.32 показаны предыдущие три шага.

Рис. 9.32    Выбор всех мер в таб­ли­це

10. Перетащите мышью выделенные меры в таб­ли­цу Internet Sales Metrics, как показано на рис. 9.33. 11. Откройте вкладку Отчет. 12. Скройте панель Поля (Fields) и откройте ее снова, как показано на рис. 9.34. Итак, мы создали таб­ли­цу с мерами из таб­ ли­цы Internet Sales. В Po­wer BI Desktop таб­ли­ цы мер отображаются в верхней части панели Поля (Fields). Можно создать отдельные таб­ ли­цы мер для каждой области нашего бизнеса, что позволит объединить вместе близкие по смыслу меры. Такой подход может помочь привести модель данных в порядок и облегчить ее понимание пользователями.

Рассуждения

Рис. 9.33    Перенос мер из одной таб­ли­цы в другую

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

Организация модели данных    357

проблемы наличие в  модели данных таб­ли­цы, использующейся исключительно для хранения мер, то ничего страшного. Но есть и  более серьезная проблема, связанная с  таб­ли­ца­ми мер, и  относится она к  рекомендуемым таблицам (featured table). Как мы уже говорили в  главе 8, любую таб­ли­цу в модели данных Po­wer BI можно перевести в разряд рекомендуемых. В результате поля и меры из таких таб­лиц станут доступны пользователям Excel в  рамках вашей организации. А  при перемещении мер из рекомендуемых таб­лиц в отдельные таб­ли­цы для мер сотрудники автоматически потеряют к ним доступ. Как и всегда, выбор за вами – вы можете применить тот подход, который лучше всего подойдет в вашей конкретной ситуации.

Скройте и откройте

Рис. 9.34    Таб­ли­ца мер, созданная в Po­wer BI Desktop

Использование папок Ещ одним способом организации данных в модели является создание отдельных папок (folder) для столбцов и мер внутри таб­лиц. Этот способ не имеет недостатков, о которых мы говорили в предыдущем разделе, касающемся создания отдельных таб­лиц для мер. Таким образом, вы можете создать столько папок, сколько пожелаете. Создавать новые и  управлять существующими папками можно на вкладке Модель Po­wer BI Desktop. В  этом разделе вы узнаете, как можно использовать организацию данных по папкам наиболее эффективно.

Создание папки в нескольких таблицах в одно действие Существует способ создания папок одновременно в нескольких таб­ли­цах, что бывает крайне удобно. Так вы можете выделить меры в таб­ли­цах в отдельные папки или распределить по папкам определенные столбцы. Выполните следующие действия, чтобы создать папки с мерами сразу в нескольких таб­ ли­цах в модели данных. 1. Перейдите на вкладку Модель. 2. Выберите таб­ли­цу либо на диаграмме, либо на панели Поля, после чего нажмите сочетание клавиш Ctrl+A для выделения всех таб­лиц. 3. Щелкните правой кнопкой мыши по любой из выделенных таб­лиц.

358    Схема «звезда» и распространенные техники при моделировании данных 4. Выберите пункт Выбрать меры (Select measures) для выделения всех мер. На рис. 9.35 показаны приведенные выше действия.

Нажмите Ctrl+A

Рис. 9.35    Выделение всех мер в модели данных

5. Введите имя папки в поле Папка отображения (Display folder) и нажмите на клавишу Enter. Я ввел имя Measures. На рис. 9.36 видно, что в результате во всех таб­ли­цах были созданы папки Measures, в которые были помещены меры.

Рис. 9.36    Перемещение мер в папки одновременно в нескольких таб­ли­цах

Организация модели данных    359

Помещение меры в разные папки Иногда бывает нужно разместить меру сразу в нескольких папках. Например, это может быть удобно для обеспечения доступа к мерам разным службам и отделам. Допустим, нам необходимо, чтобы меры Sales LM и Sales MoM% были видны в папках Measures и Time Intelligence. Это можно сделать, выполнив следующие действия. 1. Выделите меры Sales LM и Sales MoM%. 2. В поле Папка отображения (Display folder) добавьте точку с запятой после слова Measures, введите новое имя папки для отображения и нажмите на клавишу Enter. На рис. 9.37 показаны эти действия и результат.

Рис. 9.37    Доступ к мерам из разных папок

В поле Папка отображения будут перечислены все папки для выбранной меры через точку с запятой, как показано ниже: Measures;Time Intelligence

Создание подпапок Иногда бывает необходимо пойти еще дальше и организовать доступ к столбцам и мерам при помощи вложенных папок. В нашем примере мы могли бы разместить базовые меры в отдельной подпапке. Это можно сделать, выполнив следующие действия. 1. Выделите нужные меры. 2. Используйте при вводе пути в поле Папка отображения символ обратной косой черты (\) для создания иерархии папок, как показано на рис. 9.38.

360    Схема «звезда» и распространенные техники при моделировании данных

Рис. 9.38    Создание подпапок

Уменьшение размера модели путем отказа от автоматических таблицс датами и временем При загрузке данных в модель Po­wer BI автоматически создает календарные таб­ли­цы для поддержки иерархий полей с датами и временем. Это бывает очень удобно, особенно для новичков, которые не знают, как создавать собственный календарь и управлять иерархиями. В то же время такое поведение Po­wer BI может негативно сказываться на производительности модели и занимаемой памяти. При включенной опции автоматического создания календарей Po­wer BI Desktop помещает в создаваемые таб­ли­цы следующие поля:   Date;   Year;   Quarter;   Month;   Day. Последние четыре столбца используются с целью создания иерархий для каждой колонки с датой и временем. Значения в колонке Date начинаются с  1 января минимального года соответствующего столбца в  наших таб­ли­ цах и заканчиваются 31 декабря максимального года. При организации хранилищ данных распространенной практикой является использование даты 10/01/1900 для неизвестных дат в прошлом и 31/12/9999 – для неизвестных дат в будущем. Представьте, что будет, если у нас в данных обнаружится столбец с неизвестной датой. Именно поэтому рекомендуется отключать опцию автоматического создания календарей в Po­wer BI Desktop. Чтобы сделать это, выполните следующие действия.

Уменьшение размера модели путем отказа от автоматических таблиц    361

1. Перейдите на вкладку Файл (File). 2. В открывшемся меню выберите выпадающий пункт Параметры и настройки (Options and settings). 3. Выберите пункт Параметры (Options). На рис. 9.39 показаны эти действия.

Рис. 9.39    Доступ к параметрам в Po­wer BI Desktop

4. В разделе Глобальные (Global) откройте секцию Загрузка данных (Data Load). 5. Снимите флажок Автоматические дата и время для новых файлов (Auto date/time for new files), как показано на рис. 9.40.

Рис. 9.40    Отключение автоматического создания календарей в Po­wer BI Desktop

6. Перейдите в секцию Загрузка данных (Data Load) в разделе Текущий файл (Current File). 7. Снимите флажок Автоматические дата и время (Auto date/time). Это позволит отключить данную опцию для текущего файла. Если вы не

362    Схема «звезда» и распространенные техники при моделировании данных отключили ее в  глобальном разделе, она продолжит действовать для новых файлов. 8. Нажмите на кнопку OK.

Рис. 9.41    Отключение автоматического создания календарей для текущего файла

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

Заключение В этой главе мы рассмотрели некоторые ключевые приемы для работы со схемой «звезда». Мы узнали, как создавать связи типа «многие ко многим», научились использовать двунаправленные связи, а также программным способом активировать и деактивировать их. Кроме того, мы поработали с конфигурационными таб­ли­ца­ми и поняли, как можно их использовать в процессе визуализации данных. После этого мы подробно поговорили о том, почему не стоит увлекаться созданием вычисляемых столбцов в таб­ли­цах, а также порассуждали на тему удобной организации данных в модели. Наконец, мы научились отключать опцию автоматического создания календарей в Po­wer BI Desktop с целью экономии занимаемого моделью данных места. В следующей главе мы обсудим некоторые продвинутые техники моделирования данных, которые помогут вам вывести производительность самых сложных моделей на высочайший уровень.

Часть IV Расширенное моделирование данных

В этой части мы поговорим о продвинутых техниках моделирования данных, которые вы можете не применять на ежедневной основе, но знать о которых просто обязаны. В  числе прочих тем мы рассмотрим работу с  иерархиями типа родитель–потомок, включая проведение вычислений внутри иерархий, научимся использовать агрегации, узнаем, как можно эффективно работать со связями типа «многие ко многим», и  затронем другие темы, связанные с углубленными методами моделирования данных. Для усвоения материала следующих глав необходимо хорошо понимать устройство схемы «звезда» и обладать навыками использования в расчетах языка DAX. Как и в других главах книги, здесь мы будем рассматривать все приемы на примере реальных сценариев. Содержание этой части:   глава 10 «Продвинутые техники моделирования данных»;   глава 11 «Безопасность на уровне строк»;   глава 12 «Дополнительные опции и возможности моделирования данных».

Глава

10

Продвинутые техники моделирования данных В предыдущей главе мы рассмотрели несколько важных аспектов моделирования данных, включая связи типа «многие ко многим» с использованием таб­лиц-мостов и  неактивные связи между таб­ли­ца­ми с  возможностью их программного активирования. Мы также поговорили об использовании конфигурационных таб­лиц, организации модели данных и уменьшении ее размера с помощью отказа от автоматического создания таб­лиц с календарями в Po­wer BI Desktop. В этой главе мы обсудим более продвинутые концепции моделирования данных, которые помогут повысить эффективность при работе со сложными сценариями. Некоторые из этих возможностей раньше были доступны только при наличии премиумной лицензии, но сегодня ими можно воспользоваться и в лицензии Pro. Основные темы, которые мы затронем в главе:   использование агрегаций;   добавочное обновление;   иерархии типа родитель–потомок;   ролевые измерения;   использование групп вычислений. Как ясно из названия главы, большую часть времени мы посвятим описанию углубленных концепций, а на более базовых вещах останавливаться не будем.

Использование агрегаций С точки зрения анализа данных концепция агрегированных таб­лиц (aggregation table), или таб­лиц агрегатов, известна довольно давно. В частности, она широко использовалась в многомерных хранилищах SQL Server Analysis Services. Агрегированные таб­ли­цы работают очень просто: мы собираем данные на определенном уровне гранулярности и делаем их доступными в модели данных. За счет использования заранее рассчитанных показателей агрегирование данных обычно способствует повышению производительности вычислений. Получается, что в процессе агрегирования (aggregation) мы не-

Использование агрегаций    365

минуемо меняем гранулярность исходной таб­ли­цы. А что, если при анализе данных нам потребуется спуститься на более низкий уровень гранулярности? Ответ прост: нам необходимо хранить исходные данные в неизменном виде. Для этого мы все агрегации производим в новых таб­ли­цах, после чего реализуем механизм отслеживания уровня гранулярности, на котором находится пользователь. Если нужные нам данные доступны на определенном уровне агрегации, мы будем извлекать их из агрегированной таб­ли­цы. При перемещении пользователя на более низкий уровень гранулярности вычисления автоматически перенесутся в исходную таб­ли­цу. Такой подход использовать бывает очень непросто, но при правильной реализации он работает превосходно. Агрегирование данных может быть успешно применено почти к  любой модели, но максимальная польза от него может быть получена при работе с большими данными (big data). К примеру, в службе аналитики Azure Synapse Analytics могут храниться миллиарды строк информации, и мы просто физически не сможем загрузить их все в модель данных Po­wer BI Desktop. В таких случаях использование агрегированных таб­лиц просто неизбежно. Хорошая новость состоит в том, что в Po­wer BI Desktop предусмотрен инструмент под названием Управление агрегированием (Manage aggregations), предназначенный для работы с таб­ли­ца­ми агрегатов. Для использования этого инструмента необходимо, чтобы источник данных исходной таб­ли­цы поддерживал режим хранения DirectQuery. ПРИМЕЧАНИЕ  В  главе 4 мы уже обсуждали различные режимы хранения данных и различия между ними. Список источников данных, поддерживающих режим Direct­Query, можно найти по адресу https://docs.microsoft.com/en-us/Po­wer-bi/connect-data/Po­wer-bi-data-sources?WT.mc_id=%3FWT.mc_id%3DDP-MVP-5003466.

Механизм управления агрегированием берет на себя заботу о переключениях между исходной и агрегированной таблицами при изменении уровня гранулярности пользователем. В следующих разделах мы подробно поговорим о двух способах реализации агрегированных таб­лиц. Первый способ относится к  созданию таб­лиц агрегатов для источников, не поддерживающих режим хранения DirectQuery, таких как Excel. В  этом случае нам придется создать агрегированную таб­ли­цу и самим позаботиться о механизме переключения между ней и исходной таблицей при изменении пользователем уровня гранулярности анализируемых данных. Второй способ заключается в  использовании инструмента Управление агрегированием при доступе к  источнику, поддерживающему режим DirectQuery.

Реализация агрегирования для источников, не поддерживающих DirectQuery Зачастую в  реальных сценариях нам приходится работать с  источниками данных, не поддерживающими режим DirectQuery. В этом случае мы не смо-

366    Продвинутые техники моделирования данных жем воспользоваться специальным инструментом Управление агрегированием, присутствующим в Po­wer BI Desktop. Но мы можем самостоятельно реализовать процесс агрегирования данных. Для этого необходимо выполнить следующие действия. 1. Агрегировать данные на нужном уровне гранулярности. 2. Создать связи между новой агрегированной таблицей и измерениями на соответствующих уровнях гранулярности. 3. Создать нужные меры (заметьте, что эти меры будут вычисляться на соответствующих уровнях агрегации). 4. Создать другой набор мер для контроля уровня гранулярности, выбранного пользователем. 5. Скрыть агрегированную таб­ли­цу для обеспечения полной ясности картины. В этой главе мы будем работать с файлом Chapter 10, Aggregations on NonDirectQurey Data Sources.pbix, источником данных для которого является файл Excel AdventureWorksDW2017.xlsx.

Реализация агрегации на уровне Date Нам необходимо создать таб­ли­цу агрегатов для исходной таб­ли­цы Internet Sales, в  которой содержится 60 398 строк. Агрегировать данные мы будем только на уровне Date. Назовем новую агрегированную таб­ли­цу Internet Sales Aggregated. ПРИМЕЧАНИЕ  В  главе 5 мы уже обсуждали тему агрегирования, когда говорили о группировке данных. В связи с этим мы не будем подробно останавливаться на том, как провести агрегацию по таб­ли­це Internet Sales.

Суммирование данных в таблице Internet Sales Чтобы агрегировать данные из таб­ли­цы Internet Sales на уровне гранулярности Date, необходимо воспользоваться инструментом группировки (Group by) в  редакторе Po­wer Query. Мы будем агрегировать следующие столбцы с использованием операции суммирования (SUM):   Order Quantity;   Sales;   Tax;   Freight Costs. В качестве группирующих столбцов будут выступать следующие:   OrderDateKey;   DueDateKey;   ShipDateKey. На рис. 10.1 показано диалоговое окно с группировкой данных в редакторе Po­wer Query. Теперь, когда мы выполнили агрегирование данных из таб­ли­цы Internet Sales на уровне Date (с образованием новой таб­ли­цы Internet Sales Aggregated), можно закрыть и применить изменения для загрузки данных в модель.

Использование агрегаций    367

Рис. 10.1    Агрегирование таб­ли­цы Internet Sales в редакторе Po­wer Query

Создание связей На этом этапе мы загрузили необходимые данные в модель. В созданной таб­ ли­це Internet Sales Aggregated оказалось всего 1124 строки, что значительно меньше по сравнению с исходной таблицей Internet Sales. На рис. 10.2 показано содержимое таб­ли­цы Internet Sales Aggregated после загрузки в модель данных.

Рис. 10.2    Таб­ли­ца Internet Sales Aggregated

368    Продвинутые техники моделирования данных Теперь нам необходимо создать связи между новой таблицей и таблицей Date. На рис. 10.3 показаны созданные связи.

Рис. 10.3    Связи между таб­ли­ца­ми Internet Sales Aggregated и Date

Далее создадим меры для расчета продаж.

Создание мер в агрегированной таблице Итак, пришло время снабдить таб­ли­цу Internet Sales Aggregated необходимыми мерами. Для упрощения сценария мы ограничимся созданием одной меры для расчета суммы по полю Sales в таб­ли­це Internet Sales Aggregated. Выражение DAX для этой меры будет следующим: Sales Agg = SUM('Internet Sales Aggregated'[Sales])

В мере Sales Agg происходит вычисление суммы продаж. Помните, что таб­ли­ца Internet Sales Aggregated была образована на основе таб­ли­цы Internet Sales. Следовательно, в мере Sales Agg будет использоваться такой же расчет, как и в мере Internet Sales из таб­ли­цы Internet Sales. Ниже приведено выражение DAX для меры Internet Sales: Internet Sales = SUM('Internet Sales'[SalesAmount])

Основное отличие между мерами Sales Agg и  Internet Sales заключается в следующем:   мера Sales Agg производит вычисление в  небольшой таб­ли­це Internet Sales Aggregated, тогда как мера Internet Sales обсчитывает всю объемную таб­ли­цу Internet Sales. Этим может быть обусловлена разница в скорости вычисления данных мер при одновременной работе с отчетом нескольких пользователей.

Использование агрегаций    369

Пользователи могут фильтровать меру Internet Sales по измерениям Customer, Product и Date, тогда как при вычислении меры Sales Agg им будет доступен только один фильтр по таб­ли­це Date. После написания меры Sales Agg можно приступать к созданию контрольной меры для определения уровня гранулярности, выбранного пользова­ телем.

Создание контрольной меры в исходной таблице Сейчас мы создадим особую меру, которая поможет нам в определении выбранного пользователем уровня гранулярности в отчете. Если пользователь находится на уровне Date, контрольная мера перенаправит вычисление в меру Sales Agg из агрегированной таб­ли­цы. Но если он выберет столбец из таб­ли­цы Product или Customer, вычисление будет производиться посредством меры Internet Sales из исходной таб­ли­цы. Эту контрольную меру мы создадим в нашей исходной таб­ли­це Internet Sales. Причина этого в том, что на следующем шаге мы скроем созданную таб­ли­цу агрегатов. Для определения уровня гранулярности, выбранного пользователем, есть разные способы. Мы можем воспользоваться функциями IF или SWITCH для проверки условия, а также одной или несколькими функциями DAX из приведенного ниже списка:   ISFILTERED;   ISINSCOPE;   HASONEFILTER;   HASONEVALUE. Следующее выражение DAX позволяет определить, был ли пользователем выбран столбец из таб­ли­цы Product или Customer, и перенаправляет вычисление на соответствующую меру: Internet Sales Total = IF( OR(ISFILTERED('Product'); ISFILTERED('Customer')) ; [Internet Sales] ; [Sales Agg] )

Скрытие агрегированной таблицы Последнее, что нужно сделать, – это скрыть таб­ли­цу Internet Sales Aggregated и  меру Internet Sales из таб­ли­цы Internet Sales во избежание путаницы для пользователей. На рис. 10.4 показана модель данных после скрытия таб­ли­цы Internet Sales Aggregated и меры Internet Sales.

370    Продвинутые техники моделирования данных

Скрыта Контрольная мера

Скрыта

Рис. 10.4    Модель данных после скрытия таб­ли­цы Internet Sales Aggregated и меры Internet Sales

Теперь, когда мы вроде все сделали, пришло время протестировать наше решение при помощи визуализации данных. Нам необходимо убедиться, что меры Internet Sales и Internet Sales Total всегда будут показывать одинаковые значения. Кроме того, нам нужно, чтобы при выборе пользователем любых столбцов в таб­ли­цах Product или Customer мера Internet Sales Total использовала для расчета исходную таб­ли­цу (Internet Sales). В нашем примере мы создали страницу отчета, на которую одновременно вывели меры Internet Sales и Internet Sales Total. На рис. 10.5 показан внешний вид отчета.

Использование агрегаций    371

Рис. 10.5    Проверка агрегации данных при помощи визуализации

В верхней части отчета располагается визуальный элемент Карточка (Card), на котором выводится имя используемой в  расчетах таб­ли­цы. Для этого элемента визуализации мы использовали следующее выражение DAX: Test Grain Selection Control = IF( OR(ISFILTERED('Product'); ISFILTERED('Customer')) ; "Internet Sales" ; "Internet Sales Aggregated" )

В этом выражении проверяется, фильтруется ли таб­ли­ца Product или Customer. Если да, то в карточке выводится имя таб­ли­цы Internet Sales, в противном случае – Internet Sales Aggregated. На рис. 10.6 показано, как изменится внешний вид карточки при выборе пользователем одной из категорий товаров в левом срезе. Как видите, агрегация отработала корректно. Мы рассмотрели простейший способ реализации агрегации в  Po­wer BI Desktop. Но можно придумать и более сложные сценарии. Давайте пойдем на шаг дальше и усложним задачу.

372    Продвинутые техники моделирования данных

Рис. 10.6    Карточка после выбора элемента в левом срезе

Реализация агрегации на уровне Year и Month Теперь создадим еще одну агрегированную таб­ли­цу на базе таб­ли­цы Internet Sales – на этот раз на уровнях гранулярности Year и Month на основе единственного столбца OrderDateKey. Также мы включим в качестве агрегированного столбца количество строк в таб­ли­це Internet Sales. Последовательность шагов для реализации этого сценария будет очень похожа на предыдущий пример. Единственное отличие будет наблюдаться на этапе подготовки данных при агрегировании таб­ли­цы Internet Sales и смене гранулярности данных с  Date на Year и  Month. Давайте внимательнее присмотримся к  этапу подготовки данных. Для агрегирования таб­ли­цы Internet Sales на уровнях Year и Month нам необходимо выполнить агрегацию следующих столбцов (с указанием агрегатной функции):   Order Quantity (SUM);   Sales (SUM);   Tax (SUM);   Freight Costs (SUM);   Internet Sales (Count). В качестве группирующего будет выступать один столбец:   OrderDateKey. Здесь очень важно понять, что нам придется модифицировать поле OrderDateKey таким образом, чтобы оно отражало требуемые уровни Year и Month. При этом в поле OrderDateKey хранятся числа, а не даты. Кроме того, нам нужно будет создать связь между таблицей агрегатов и таблицей Date с использованием ключа OrderDateKey из первой таб­ли­цы и DateKey из второй. Таким образом, тип данных столбца OrderDateKey должен оставаться числовым, чтобы соответствовать столбцу DateKey из таб­ли­цы Date. Дабы справиться с этой задачей, используем простую математику:

Использование агрегаций    373 New OrderDateKey = (CONVERT(Integer; ([OrderDateKey]/100)) * 100) + 1

В результате этого приведения значение 20130209 преобразуется в  20130201. Вы можете подумать, что гранулярность столбца New OrderDateKey осталась на уровне дня. Так и  есть. Но при этом мы привели все даты к первому дню месяца, а это значит, что при агрегировании данных по полю New OrderDateKey мы на самом деле получим агрегацию на уровне Year и Month. Так что нам нужно просто заменить значения в столбце OrderDateKey на приведенную выше математику. После удаления всех ненужных столбцов в редакторе Po­wer Query добавим шаг с заменой значений в столбце OrderDateKey со следующей формулой: Table.ReplaceValue(#"Removed Other Columns",each [OrderDateKey], each (Int64. From([OrderDateKey]/100) * 100) + 1,Replacer.ReplaceValue,{"OrderDateKey"})

На рис. 10.7 показаны эти шаги в редакторе Po­wer Query.

Ссылка на таблицу Internet Sales

Рис. 10.7    Замена значений в столбце OrderDateKey

Теперь необходимо агрегировать результаты. Помните, что нам понадобится также агрегация по количеству строк. На рис. 10.8 показано заполненное диалоговое окно с группировкой. Применим изменения в редакторе Po­wer Query, что приведет к созданию новой таб­ли­цы Internet Sales Aggregated Year Month. Далее нужно создать связь между таб­ли­ца­ми Internet Sales Aggregated Year Month и Date. На рис. 10.9 показана созданная связь. ПРИМЕЧАНИЕ  Мы установили кратность связи как «многие к одному», а направление кросс-фильтрации сделали односторонним.

При создании этой связи Po­wer BI автоматически определил ее как «один к одному». В принципе, это верно. Каждая строка в таб­ли­це Internet Sales Aggregated Year Month, представленная началом месяца, соответствует только одной строке в  таб­ли­це Date. Но нам нужно изменить кратность связи на «многие к  одному». Это позволит избежать распространения фильтрации с таб­ли­цы Internet Sales Aggregated Year Month на таб­ли­цу Date.

374    Продвинутые техники моделирования данных

Рис. 10.8    Группировка таб­ли­цы Internet Sales на уровне Year и Month

Рис. 10.9    Создание связи между таб­ли­ца­ми Internet Sales Aggregated Year Month и Date

Далее необходимо создать меру со следующей формулой DAX в таб­ли­це Internet Sales Aggregated Year Month: Sales Year Month = SUM('Internet Sales Aggregated Year Month'[Sales])

Использование агрегаций    375

Пришло время для создания контрольной меры для определения уровня детализации, выбранного пользователем, причем не только по таблицам Product и  Customer, но также по таб­ли­це Date. Следующее выражение DAX прекрасно справится с этим: Internet Sales Agg = IF( ISFILTERED('Product') || ISFILTERED('Customer') || ISFILTERED('Date'[Full Date]) ; [Internet Sales] ; [Sales Year Month] )

Давайте создадим еще одну вспомогательную меру с той же конструкцией IF, что и в предыдущей мере, но возвращающую при выборе товара, клиента или даты строку "Internet Sales", а в противном случае – строку "Internet Sales Aggregated". Это позволит нам лучше понять работу меры Internet Sales Agg: Internet Sales Agg Test = IF( ISFILTERED('Product') || ISFILTERED('Customer') || ISFILTERED('Date'[Full Date]) ; "Internet Sales" ; "Internet Sales Aggregated" )

Осталось проверить все в отчете. На рис. 10.10 показан внешний вид отчета до выбора пользователем элементов в фильтрах.

Уровень года Уровень месяца

Уровень даты

Рис. 10.10    Отчет перед выбором элементов в срезах Product и Customer

Заметьте, что в итоговой строке в колонке с мерой Internet Sales Agg Test отображается текст Internet Sales Aggregated. Также по рис. 10.10 видно, что при отсутствии выбора элементов в срезах Product и Customer для расчета на уровнях Year и Month используется мера Internet Sales Agg. Но на уровне Date мера меняется на Internet Sales. Этот метод можно использовать с целью оптимизации быстродействия отчета в условиях, когда с системой одновременно работают несколько пользователей. Но не стоит забывать и о следующих побочных эффектах такого подхода:

376    Продвинутые техники моделирования данных   агрегированные таб­ли­цы будут занимать определенное место в  па­ мяти;   наличие агрегированных таб­лиц также негативно скажется на времени обновления модели;   время разработки увеличится, поскольку необходимо создать таб­ли­цы агрегатов, связать между собой таб­ли­цы и создать нужные меры. Теперь, когда мы познакомились с техникой агрегирования данных при работе с  источниками, не поддерживающими режим DirectQuery, пришло время узнать, как работает встроенный в Po­wer BI инструмент управления агрегированием.

Использование инструмента управления агрегированием Управление агрегированием (managing aggregations) – это один из наиболее важных инструментов моделирования данных в  составе Po­wer BI Desktop, позволяющий повысить масштабируемость модели за счет возможности работы с большими данными. Как мы уже знаем, Po­wer BI сжимает и кеширует все данные в памяти при использовании режима загрузки Импорт (Import). А что делать, если в нашем источнике данных Azure Synapse хранятся миллиарды строк, а нам необходимо разработать аналитическое решение в Po­ wer BI? Мы прекрасно знаем об ограничениях Po­wer BI в отношении места, отводимого для хранения модели данных, особенно это касается лицензий Free и Pro. Но даже с лицензией Premium мы будем ограничены ресурсами, выделенными под наше решение. Конечно, использование версии Po­wer BI Premium 2-го поколения (Po­wer BI Premium Gen 2) позволит меньше задумываться об этих ограничениях. Но если не подходить к вопросам моделирования данных со всей тщательностью, то очень скоро обработка данных и использование памяти станут главными сдерживающими факторами разрабатываемой модели. И здесь вам придет на помощь механизм управления агрегированием. Как мы уже упоминали, этот механизм применим только к исходным таблицам (base table) из источников данных, поддерживающих режим DirectQuery. ПРИМЕЧАНИЕ  Иногда исходные таб­ли­цы также называют таб­ли­ца­ми детализации. В обоих случаях речь идет о таб­ли­цах, использующихся для создания агрегированных данных.

Поддержка режима DirectQuery – один из краеугольных камней моделирования данных. Как мы уже говорили в главе 4, таб­ли­цу, находящуюся в режиме хранения Импорт, невозможно перевести в  режим DirectQuery или Двойной (Dual). Таким образом, всегда необходимо думать об управлении агрегированием заранее, на этапе проектирования модели данных. В противном случае вам придется все начинать сначала. С учетом всего сказанного можно описать процесс агрегирования данных следующим образом. 1. Подключаемся к источнику данных.

Использование агрегаций    377

2. Загружаем нужные таб­ли­цы в режиме DirectQuery: •• источник данных уже может содержать агрегированную таб­ли­цу; •• если источник не содержит агрегированную таб­ли­цу, можно использовать Po­wer Query или DAX для ее создания. 3. Создаем связи между таб­ли­ца­ми. 4. Устанавливаем для агрегированной таб­ли­цы режим Импорт. Помним при этом, что это действие необратимо. Также переводим все измерения, объединенные с агрегированной таблицей при помощи активной связи, в режим хранения Двойной (Dual). 5. Настраиваем управление агрегированием. 6. Проверяем, чтобы запросы использовали созданную агрегацию. В данном разделе мы будем использовать источник AdventureWorksDW2019 (база данных SQL Server). ПРИМЕЧАНИЕ  Резервную копию базы данных вы можете загрузить с сайта Microsoft по адресу https://docs.microsoft.com/en-us/sql/samples/adventureworks-installcon­f i­g ure?view=sql-server-ver15&tabs=ssms&WT.mc_id=%3FWT.mc_id%3DDPMVP-5003466.

Давайте реализуем агрегации следующих типов применительно к таб­ли­це FactInternetSales:   FactInternetSales (количество строк);   SalesAmount (сумма);   OrderQuantity (сумма);   TaxAmt (сумма);   Freight (сумма);   ProductKey (группировка);   Year (группировка);   Month (группировка). Для создания агрегированной таб­ли­цы воспользуемся следующим скриптом T-SQL: CREATE VIEW vw_Sales_Agg AS SELECT dp.ProductKey , dd.CalendarYear , dd.EnglishMonthName , COUNT(1) Sales_Count , SUM(fis.SalesAmount) AS Sales_Sum , SUM(fis.OrderQuantity) AS OrderQty_Sum , SUM(fis.TaxAmt) AS Tax_Sum , SUM(fis.Freight) AS Freight_Sum FROM FactInternetSales fis LEFT JOIN DimDate dd ON dd.DateKey = fis.OrderDateKey LEFT JOIN DimProduct dp ON fis.ProductKey = dp.ProductKey GROUP BY dp.ProductKey , dd.CalendarYear , dd.EnglishMonthName

Теперь можно использовать созданное представление в Po­wer BI Desktop.

378    Продвинутые техники моделирования данных

Управление агрегированием в Power BI Desktop для источников, поддерживающих DirectQuery, и больших данных Теперь, когда мы создали агрегированную таб­ли­цу, пришло время воспользоваться инструментом управления агрегированием. Для этого выполните следующие действия. 1. С помощью соответствующего коннектора подключитесь к вашей базе данных, как показано на рис. 10.11.

Рис. 10.11    Подключение к базе данных SQL Server в режиме DirectQuery

2. Загрузите следующие таб­ли­цы в режиме DirectQuery: •• DimDate; •• DimCustomer; •• DimProduct; •• FactInternetSales; •• vw_Sales_Agg. ПРИМЕЧАНИЕ  Мы могли создать агрегированную таб­ли­цу и  при помощи Po­wer Query. Но для этого примера мы воспользовались представлением из базы данных.

3. Переименуйте таб­ли­цу vw_Sales_Agg в Sales_Agg, как показано на рис. 10.13. 4. Создайте связи между таб­ли­ца­ми, как показано на рис. 10.14. ПРИМЕЧАНИЕ  Нам нужно создать связи между агрегированной таблицей и всеми нужными измерениями, чтобы запросы могли обращаться к ней. В нашем примере необходимо объединить таб­ли­цы Sales_Agg и DimProduct по полю ProductKey.

Использование агрегаций    379

Рис. 10.13    Переименование таб­ли­цы vw_Sales_Agg в Sales_Agg Рис. 10.12    Таб­ли­цы, загруженные в режиме DirectQuery

Рис. 10.14    Создание связей на вкладке Модель

380    Продвинутые техники моделирования данных 5. Измените режимы хранения для агрегированной таб­ли­цы и всех связанных измерений, следуя приведенным ниже правилам: a) режим хранения для таб­ли­цы Sales_Agg установите в Импорт (Import). При этом вы увидите предупреждение, указывающее на то, что режим хранения связанных с  Sales_Agg таб­л иц должен быть установлен в  Двойной (Dual). В  диалоговом окне, показанном на рис. 10.15, вы можете установить флажок Преобразовать затронутые таб­л и­ц ы в  режим «Двойной» (Set the affected tables to dual). Можно также изменить режим хранения связанных таб­лиц позже; b) измените режим хранения таб­ли­цы DimProduct на Двойной.

Рис. 10.15    Изменение режима хранения агрегированной и связанных таб­лиц

Мы установили для агрегированной таб­ли­цы режим Импорт, поскольку хотим, чтобы запросы могли обращаться к  ней и  выполняться быстрее. Это возможно только в  случае загрузки данных и  предоставления доступа к ним движку xVelocity для внутреннего выполнения запросов. Если вынести в  визуализацию меру из таб­ли­цы FactInternetSales (таб­ли­ца детализации) и поле EnglishProductName из таб­ли­цы DimProduct, таб­ли­ца FactInternetSales будет в режиме Импорт, тогда как DimProduct – в режиме DirectQuery. Движок должен частично выполнять запрос внутренне при задействовании агрегированной таб­ли­цы. Другая часть, представляющая DirectQuery, должна быть транслирована в машинный запрос источника данных. Именно поэтому мы установили для таб­ли­цы DimProduct режим Двойной. Давайте продолжим с настройками агрегирования. 6. Щелкните правой кнопкой мыши по таб­ли­це Sales_Agg и  выберите пункт Управление агрегированием (Manage aggregations), как показано на рис. 10.16.

Использование агрегаций    381

Рис. 10.16    Управление агрегированием в таб­ли­це Sales_Agg

7. В открывшемся диалоговом окне выполните следующие действия: a) убедитесь, что в выпадающем списке Таб­ли­ца агрегатной обработки (Aggregation table) выбрана таб­ли­ца Sales_Agg; b) оставьте в поле Приоритет (Precedence) значение 0; c) заполните столбец Суммирование (Summarization) для полей из таб­ли­цы Sales_Agg. Мы намеренно использовали в названиях полей тип их агрегации, чтобы было удобнее; d) нажмите на кнопку Применить все (Apply all). Эти шаги показаны на рис. 10.17.

Рис. 10.17    Управление агрегированием

382    Продвинутые техники моделирования данных ПРИМЕЧАНИЕ  Нет необходимости выбирать в списке Суммирование (Summarization) для поля ProductKey значение Группировать по (Group by). Между таб­ли­ца­ми DimProduct и Sales_Agg уже существует связь. После применения агрегации таб­ли­ца Sales_Agg будет скрыта.

8. Теперь нужно создать следующую меру в таб­ли­це детализации (FactInternetSales): Total Internet Sales = SUM(FactInternetSales[SalesAmount])

Итак, мы настроили агрегирование в таб­ли­це FactInternetSales. Мы также создали новую меру. Теперь пришло время убедиться, что на уровнях Product, Year или Month запрос будет обращаться к нашей агрегированной таб­ли­це.

Проверка агрегирования На этом этапе нам необходимо протестировать созданную агрегацию на предмет обращения к ней в запросах. Для мониторинга модели можно использовать SQL Server Profiler, подключенный к Po­wer BI Desktop. Инструмент SQL Server Profiler входит в состав SQL Server Management Studio (SSMS). ПРИМЕЧАНИЕ  Подробнее об использовании SQL Server Profiler можно почитать по адресу https://docs.microsoft.com/ru-ru/sql/tools/sql-server-profiler/sql-server-profi­ ler?view=sql-server-ver15.

SQL Server Profiler можно использовать двумя способами:   можно установить его в качестве внешнего инструмента. В этом случае можно будет открывать SQL Server Profiler напрямую из Po­wer BI Desktop на вкладке Внешние инструменты (External Tools). Таким образом, SQL Server Profiler будет автоматически подключаться к нашей модели данных Po­wer BI с  использованием диагностического порта Po­wer BI (Po­wer BI Diagnostic Port); ПРИМЕЧАНИЕ  Подробнее о том, как зарегистрировать инструмент SQL Server Profiler в Po­wer BI, можно почитать по адресу https://www.biinsight.com/quick-tips-registering-sql-server-profiler-as-an-external-tool.

  можно просто открыть SQL Server Profiler и  вручную подключиться к нашей модели данных Po­wer BI с использованием диагностического порта Po­wer BI. Для этого сначала нужно найти номер диагностического порта, после чего подключиться к модели с помощью этого номера. ПРИМЕЧАНИЕ  Почитать подробно о том, как найти номер диагностического порта в Po­wer BI Desktop, можно по адресу https://www.biinsight.com/four-different-waysto-find-your-Po­wer-bi-desktop-local-port-number.

Использование агрегаций    383

Мы воспользуемся первым способом, поскольку он проще. В  SQL Server Profiler мы будем отслеживать следующие события. Если у вас SSMS версии 17.9 или выше, вы должны выбрать приведенные ниже события:   Query Processing\Aggregate Table Rewrite Query;   Query Processing\Direct Query Begin;   Query Processing\Vertipaq SE Query Begin. Для более старых версий SSMS список событий должен быть следующим:   Queries Events\Query Begin;   Query Processing\DirectQuery Begin;   Query Processing\Vertipaq SE Query Begin. Мы рассмотрим первый вариант. Выполните следующие действия. 1. Нажмите на кнопку SQL Server Profiler на вкладке Внешние инструменты (External Tools), как показано на рис. 10.18. Инструмент автоматически выполнит подключение к вашей модели данных с использованием диагностического порта.

Рис. 10.18    Запуск SQL Server Profiler со вкладки Внешние инструменты

2. В открывшемся диалоговом окне Свойства трассировки (Trace Properties) перейдите на вкладку Выбор событий (Events Selection). 3. Отметьте события, которые мы перечислили ранее, в  разделе Query Processing. 4. Нажмите на кнопку Запустить (Run). Эти действия показаны на рис. 10.19. 5. Переключитесь в Po­wer BI Desktop, разместите на странице отчета визуальный элемент Матрица (Matrix) и перенесите меру Total Internet Sales в область Значения (Values), как показано на рис. 10.20. 6. Вернитесь в окно SQL Server Profiler и щелкните на событии Aggregate Table Rewrite Query. 7. Проверьте вывод. Если обращение к  агрегированной таб­ли­це произошло, вы, среди прочего, увидите в  выводе строку "matchingResult": "matchFound", как показано на рис. 10.21. Еще одним признаком того, что в  запросе была задействована таб­ли­ца агрегатов, служит отсутствие события DirectQuery Begin.

384    Продвинутые техники моделирования данных

Рис. 10.19    Выбор событий в SQL Server Profiler

Рис. 10.20    Добавление меры Total Internet Sales в матрицу

8. Снова откройте Po­wer BI Desktop и добавьте поле EnglishProductName из таб­ли­цы DimProduct в область Строки (Rows) матрицы. Перейдите в окно SQL Server Profiler и щелкните по событию Aggregate Table Rewrite Query. Вы увидите, что в этот раз опять была использована агрегированная таб­ли­ца. На рис. 10.22 показаны окна Po­wer BI Desktop и SQL Server Profiler рядом.

Использование агрегаций    385

Рис. 10.21    Использование SQL Server Profiler для проверки применения в запросе таб­ли­цы агрегатов

Рис. 10.22    После добавления поля EnglishProductName из таб­ли­цы DimProduct запрос по-прежнему обращается к таб­ли­це Sales_Agg

9. Теперь добавьте поля CalendarYear и EnglishMonthName из таб­ли­цы DimDate в область Столбцы (Columns) и снова проверьте окно SQL Server Profiler. Заметьте, что для просмотра информации по месяцам нам необходимо раскрывать уровень с годами.

386    Продвинутые техники моделирования данных

Рис. 10.23    Таб­ли­ца Sales_Agg продолжает использоваться при добавлении столбцов CalendarYear и EnglishMonthName

А давайте пойдем на шаг дальше, внесем небольшое изменение в модель данных и посмотрим, что произойдет. 10. Поднимитесь в матрице на уровень CalendarYear. Теперь для столбца EnglishMonthName в таб­ли­це DimDate установите сортировку по полю MonthNumberOfYear. Опуститесь в  матрице на уровень EnglishMonthName. Проверьте SQL Server Profiler на предмет задействования таб­ли­ цы Sales_Agg. Как видно на рис. 10.24, на этот раз вывод будет содержать строку "matchingResult": "attemptFailed", а это означает, что таб­ли­ца Sales_Agg не была использована в запросе.

Рис. 10.24    Таб­ли­ца Sales_Agg перестала использоваться после сортировки столбца EnglishMonthName по полю MonthNumberOfYear

Добавочное обновление    387

Еще одним индикатором того, что таб­ли­ца Sales_Agg не задействуется, служит появление события DirectQuery Begin. Чтобы исправить положение, нужно выполнить следующие действия. 1. Добавьте поле MonthNumberOfYear в  таб­ли­цу Sales_Agg посредством изменения представления SQL. 2. Обновите таб­ли­цу Sales_Agg на вкладке Модель. 3. В окне управления агрегированием настройте операцию Группировать по (Group by) для поля MonthNumberOfYear. Это мы оставляем вам на самостоятельное выполнение. ВАЖНОЕ ЗАМЕЧАНИЕ ОТНОСИТЕЛЬНО АГРЕГИРОВАНИЯ  Таб­ли­ца детализации (исходная таб­ли­ца) должна храниться в режиме DirectQuery. Поле Приоритет (Precedence) в диалоговом окне управления агрегированием позволяет расставить очередность использования таб­лиц при наличии нескольких таб­лиц агрегатов. Чем выше значение в этом поле, тем выше приоритет. К примеру, если бы у  нас была еще одна агрегированная таб­ли­ца, к  которой мы хотели бы обращаться до таб­ли­цы Sales_Agg, мы должны были бы для нее установить более высокий приоритет.  Движок xVelocity при построении запросов будет учитывать значения приоритетов для всех агрегированных таб­лиц. Типы данных агрегируемых столбцов из таб­ли­цы агрегатов должны совпадать с типами соответствующих полей в таб­ли­це детализации. В противном случае агрегирование настроить не получится. Невозможно сцепить вместе агрегации на основе трех и более таб­лиц. Например, у вас не получится создать агрегацию в случае, если таб­ли­ца X является агрегированной таблицей для таб­ли­цы Y, которая, в свою очередь, представляет собой таб­ ли­цу агрегатов для таб­ли­цы Z. В диалоговом окне управления агрегированием необходимо заполнить столбец Суммирование (Summarization) для всех полей. Для извлечения количества строк в  таб­ли­це детализации используйте агрегацию вида Подсчитать строки таб­ли­цы (Count table rows). Не забывайте, что после создания агрегации таб­ли­ца агрегатов по умолчанию будет скрыта. Всегда создавайте меры в  таб­ли­це детализации, а  не в  агрегированной таб­ли­це. Последняя должна быть скрыта от глаз пользователя. Нет необходимости использовать операцию Группировать по (Group By) применительно к агрегированным столбцам из таб­ли­цы при наличии активной связи с агрегированной таблицей. Агрегирование для неактивных связей не поддерживается, даже с использованием функции USERELATIONSHIP() для их активации.

Добавочное обновление Поначалу операция добавочного (или инкрементального) обновления (incremental refresh) была доступна только при наличии лицензии Premium. Однако с февраля 2020 года она появилась среди доступных вариантов и для пользователей с лицензиями Pro. Давайте узнаем, что из себя представляет добавочное обновление (или добавочная загрузка).

388    Продвинутые техники моделирования данных В техническом смысле любая операция переноса данных из места A в мес­ то B может представлять из себя:   удаление и загрузку: в этом случае мы целиком переносим данные из места A в место B. Если в последнем на момент загрузки была какая-то информация, мы ее полностью удаляем и загружаем новые данные;   добавочную загрузку: полностью данные переносятся лишь в первый раз. В  следующие разы производится загрузка только обновившихся данных. В этом подходе мы никогда не удаляем содержимое места назначения. Вместо этого мы переносим только ту информацию, которая присутствует в месте A, но отсутствует в месте B. Если добавочное обновление в Po­wer BI не настроено, применяется первый подход, – с полным удалением и загрузкой данных. Нет необходимости говорить, что приведенные здесь операции обновления актуальны в Po­wer BI только для таб­лиц с режимом хранения Импорт или Двойной. После настройки политики инкрементального обновления в Po­wer BI все данные будут автоматически делиться на исторические (historical) и  добавочные (incremental) диапазоны. Исторические диапазоны включают в себя данные, которые были обработаны в прошлом, а добавочные – текущие данные для обработки. При добавочном обновлении в Po­wer BI поиск изменений выполняется в добавочных диапазонах данных, а не в исторических. Таким образом, изменения в исторических сведениях обрабатываться не будут. ПРИМЕЧАНИЕ  Инкрементальное обновление выполняется путем удаления старых данных и добавления новых.

Настройка добавочного обновления оправдывает себя для объемных таб­ лиц, насчитывающих миллионы строк. Преимущества, которые можно получить за счет использования добавочного обновления:   данные обновляются гораздо быстрее, поскольку фактически переносятся только изменившиеся сведения;   операция обновления данных задействует меньше ресурсов по сравнению с полной перезаписью;   на больших таб­ли­цах процесс обновления становится менее дорогостоящим, и его гораздо легче поддерживать. Добавочное обновление практически неизбежно при работе с  огромными объемами данных, состоящими из миллиардов строк, которые не помещаются в  модель. Не забывайте, что Po­wer BI все обрабатываемые данные хранит в памяти, а ваш компьютер вряд ли справится с загрузкой в память миллиардов строк. Теперь, когда вы узнали, что такое добавочное обновление данных, давайте посмотрим, как оно реализовано в Po­wer BI.

Добавочное обновление    389

Настройка добавочного обновления в Power BI Desktop Мы практически всегда в  своей работе используем операцию добавочного обновления. Первое обновление после публикации модели в  службе Po­wer BI выполняется дольше, поскольку в этот момент все данные из источника переносятся в службу. Зато все последующие обновления будут выполняться гораздо быстрее, так как в переносе будут участвовать только изменившиеся данные. В Po­wer BI Desktop концепция добавочного обновления реализована достаточно просто. Для начала необходимо создать два параметра с типом Дата или Дата и  время в  редакторе Po­wer Query и  назвать их Range­Start и RangeEnd. Эти имена переменных зарезервированы для настройки добавочного обновления данных. ПРИМЕЧАНИЕ  Как вы знаете, Po­wer Query является регистрозависимой платформой, и имена переменных должны быть написаны в точности так: RangeStart и RangeEnd.

Следующим шагом необходимо отфильтровать данные в больших таб­ли­ цах по столбцу с датой (или датой и временем), применяя параметры Range­ Start и RangeEnd для определения вхождения в интервал. ПРИМЕЧАНИЕ  При выполнении фильтрации необходимо, чтобы значение даты включало в себя либо параметр RangeStart, либо RangeEnd, но не оба сразу.

Фильтр по календарной колонке будет использован для разбиения данных на диапазоны. С учетом сказанного выше давайте реализуем добавочное обновление. В этом разделе мы будем использовать файл Chapter 10, Incremental Refresh.pbix, источником для которого является восстановленная резервная копия базы данных SQL Server AdventureWorksDW2019. ПРИМЕЧАНИЕ  Вы можете загрузить резервную копию базы данных по адресу https:// docs.microsoft.com/en-us/sql/samples/adventureworks-install-configure?view=sqlserver-ver15&tabs=ssms&WT.mc_id=%3FWT.mc_id%3DDP-MVP-5003466.

Опишем нашу методику добавочного обновления: мы бы хотели, чтобы у нас хранились данные за десять лет вплоть до текущей даты, а добавочное обновление выполнялось за один месяц. Выполните следующие действия для реализации этого плана. 1. Загрузите в  редактор Po­wer Query данные, находящиеся в  таб­ли­це FactInternetSales, из базы данных AdventureWorksDW2019 в  SQL Server и переименуйте таб­ли­цу в Internet Sales, как показано на рис. 10.25.

390    Продвинутые техники моделирования данных

Рис. 10.25    Получение данных из источника

2. Определите параметры RangeStart и  RangeEnd с  типом данных Дата и  время (Date/Time). Как мы упоминали ранее, эти ключевые имена зарезервированы специально для нужд добавочного обновления. Установите в качестве текущих значений параметров следующие, как показано на рис. 10.26: a) для параметра RangeStart: 1/12/2010 12:00:00 AM; b) для параметра RangeEnd: 31/12/2010 12:00:00 AM.

Рис. 10.26    Определение параметров RangeStart и RangeEnd

Добавочное обновление    391 ПРИМЕЧАНИЕ  Устанавливайте для своих параметров такие текущие значения параметров, которые будут работать для вашего сценария. Помните, что эти значения используются только на этапе разработки – таб­ли­ца Internet Sales после фильтрации будет содержать лишь значения в указанном интервале дат. В нашем примере в качестве текущего значения параметра RangeStart мы выбрали первый день месяца, в котором была совершена первая транзакция. В нашей таб­ли­це Internet Sales самая ранняя дата в столбце OrderDate относится к 29 декабря 2010 года. Таким образом, в  качестве текущего значения параметра RangeStart мы выбрали дату 1/12/2010, а для параметра RangeEnd применили дату 31/12/2010.

3. Отфильтруйте столбец OrderDate так, как показано на рис. 10.27.

Рис. 10.27    Фильтрация столбца OrderDate по значениям параметров RangeStart и RangeEnd

4. Нажмите на кнопку Закрыть и применить (Close & Apply), чтобы загрузить данные в модель, как показано на рис. 10.28.

Рис. 10.28    Применение изменений и загрузка данных в модель

392    Продвинутые техники моделирования данных 5. Щелкните правой кнопкой мыши по таб­ли­це Internet Sales и выберите пункт Добавочное обновление (Incremental refresh), как на рис. 10.29. Эта опция доступна в контекстном меню во всех трех вкладках: Отчет, Данные и Модель.

Рис. 10.29    Выбор добавочного обновления из контекстного меню таб­ли­цы

6. В открывшемся диалоговом окне проделайте следующие действия: a) установите переключатель Добавочное обновление этой таб­ли­ цы (Incremental refresh); b) в полях Начало архивации данных до даты обновления (Store rows where column «OrderDate» is in the last) выберите 10 лет; c) в полях Начало добавочного обновления данных до даты обновления (Refresh rows where column «OrderDate» is in the last) выберите 1 месяц; d) оставьте переключатели Обнаруживать изменения данных (Detect data changes) и Обновлять только завершенный месяц (Only refresh complete month) неустановленными; e) нажмите на кнопку Применить (Apply all). Эти действия показаны на рис. 10.30. ПРИМЕЧАНИЕ  Зачастую в  процессе интеграции и  хранения данных в  таб­ли­цах создаются вспомогательные столбцы с полезными метаданными, такими как дата последнего обновления, пользователь, последним обновлявший данные, активность, флаг обработки и т. д. Если у вас есть колонки с датой и временем, отражающие изменения данных (например, та же дата последнего обновления), вам может оказаться полезной опция Обнаруживать изменения данных (Detect data changes). В нашем источнике данных нет вспомогательных столбцов с метаданными, так что мы не будем устанавливать этот флажок.

Добавочное обновление    393 Опция Обновлять только завершенный месяц (Only refresh complete month) зависит от установок в полях Начало добавочного обновления данных до даты обновления (Refresh rows where column «OrderDate» is in the last), обозначенных на рис. 10.30 буквой C. Она позволяет запускать добавочное обновление только для всего периода в целом. Нам это не нужно, так что мы оставили переключатель неустановленным.

Рис. 10.30    Настройка добавочного обновления

7. Нажмите на кнопку Опубликовать (Publish) для размещения модели данных в службе Po­wer BI. В диалоговом окне необходимо указать нужную рабочую область и нажать на кнопку Выбрать (Select), как показано на рис. 10.31. На данный момент мы настроили добавочное обновление модели данных и  опубликовали ее в  службе Po­wer BI. После этого в  игру должен вступить администратор Po­wer BI – он завершит настройку расписания обновлений, установит локальный шлюз данных (On-premises Data Gateway), введет нужные учетные данные и т. д. Все эти установки выходят за рамки данной книги, так что мы оставляем эту тему вам для самостоятельного изучения. Предположим, администратор сделал все необходимые настройки службы Po­wer BI. Как же нам проверить работоспособность добавочного обновления? Займемся этим в следующем разделе.

394    Продвинутые техники моделирования данных

Рис. 10.31    Публикация отчета в службе Po­wer BI

Проверка добавочного обновления На момент написания книги для подключения к  нужной рабочей области в службе Po­wer BI необходимо использовать лицензию Premium или Embedded. Вам нужно использовать такие приложения, как SQL Server Management Studio (SSMS) или DAX Studio, для просмотра секций, которые мы создали для добавочного обновления данных. ПРИМЕЧАНИЕ  Если у вас нет в наличии лицензий Premium или Embedded, вы можете получить их бесплатно на испытательный период. Подробнее об этом можно узнать по адресу https://www.biinsight.com/what-does-xmla-endpoints-mean-for-Po­ wer-bi-and-how-to-test-it-for-free.

Если же у вас есть лицензия Premium или Embedded, выполните следующие действия для подключения к рабочей области Premium. 1. В службе Po­wer BI перейдите к нужной рабочей области Premium, содержащей набор данных с настроенным добавочным обновлением. 2. Перейдите в раздел настроек. 3. Откройте вкладку Premium. 4. Скопируйте подключение к рабочей области, как показано на рис. 10.32. 5. Откройте SSMS и в диалоговом окне Соединение с сервером (Connect to Server) сделайте следующее: a) в выпадающем списке Тип сервера (Server type) выберите вариант Analysis Services; b) вставьте скопированную ссылку подключения в поле Имя сервера (Server name); c) в выпадающем списке Проверка подлинности (Authentication) выберите вариант Active Directory – универсальная с поддержкой MFA (Azure Active Directory – Universal with MFA), если у  вас уста-

Добавочное обновление    395

новлена многофакторная аутентификация (Multi-Factor Authentication – MFA); d) введите имя пользователя в соответствующее поле; e) нажмите на кнопку Соединить (Connect), как показано на рис. 10.33.

Набор данных с настроенным добавочным обновлением

Рис. 10.32    Извлечение подключения к рабочей области из службы Po­wer BI

Рис. 10.33    Подключение к рабочей области Po­wer BI Premium из SSMS

6. На панели Обозреватель объектов (Object Explorer) в разделе Базы данных (Databases) вы увидите все наборы данных, присутствующие в рабочей области. Раскройте набор данных, а там – пункт Таб­ли­цы (Tables). 7. Щелкните правой кнопкой мыши по таб­ли­це Internet Sales. 8. Выберите пункт с секциями (Partitions). 9. Теперь вы можете видеть все секции, созданные в процессе добавочного обновления, как показано на рис. 10.34.

396    Продвинутые техники моделирования данных

Рис. 10.34    Просмотр созданных секций из SSMS

Как видите, допустимо создавать и  модифицировать секции напрямую из SSMS и  сохранять изменения в  службе Po­wer BI. Такая возможность существует благодаря конечным точкам XMLA (XMLA endpoints), доступным в лицензиях Po­wer BI Premium и Embedded. Подробно о  возможностях подключения к  наборам данных с  помощью конечных точек XMLA можно почитать по адресу https://docs.microsoft.com/ ru-ru/Po­wer-bi/enterprise/service-premium-connect-tools?WT.mc_id=%3FWT.mc_ id%3DDP-MVP-5003466.

Иерархии типа родитель–потомок Концепция иерархий типа родитель–потомок (Parent-Child hierarchy) широко используется в  области реляционного моделирования данных. Такие иерархии возникают, когда значения двух столбцов в таб­ли­це представляют собой иерархические уровни данных. У  родительских элементов есть потомки, у которых также есть наследники, что и ведет к образованию иерархического графа (hierarchical graph). Давайте реализуем пример иерархии родитель–потомок в  реляционной модели данных. После этого перейдем к рассмотрению примера в Po­wer BI. На рис. 10.35 показан типичный граф иерархии типа родитель–потомок. Каждый узел иерархии содержит идентификатор и имя сотрудника.

Иерархии типа родитель–потомок    397

Рис. 10.35    Иерархический граф

Можно представить этот граф в виде таб­ли­цы, как показано на рис. 10.36.

Рис. 10.36    Представление иерархического графа в виде таб­ли­цы

Несложно заметить, что между столбцами ID и  ParentID в  таб­ли­це есть связь типа «один ко многим». В  реляционной модели данных мы обычно создаем связь между такими колонками. В данном случае эта связь будет объединять таб­ли­цу саму с собой, делая ее автореферентной (self-referencing table), что видно по рис. 10.37. Итак, мы знаем, как иерархический граф может Рис. 10.37    Таб­ли­ца, объединенная сама с собой быть представлен в реляционной модели данных. При этом модель данных в Po­wer BI также является реляционной. Но, к сожалению, Po­wer BI не поддерживает образование связей таб­ли­цы самой с  собой во избежание появления неоднозначностей

398    Продвинутые техники моделирования данных в  модели данных. Хорошая новость состоит в том, что в  DAX присутствует целый набор функций для реализации иерархий родитель–потомок в Po­wer BI. Перед тем как перейти к  практике, давайте постараемся лучше понять процесс реализации, выделив следующие стадии:   сначала необходимо определить глубину иерархии (depth of the hierarchy). Иерархия, показанная на рис. 10.38, содержит четыре уровня, так что ее глубина равна четырем. Элементы на четвертом уровне представляют собой конечные узлы, или листья (leaves), иерархии. В нашем случае это сотрудники Уильям (William) и Мелани (Melanie);

Рис. 10.38    Глубина иерархии

  после этого нужно создать вычисляемые столбцы для каждого уровня иерархии;   наконец, мы сможем создать иерархию с использованием вычисленных уровней. Как видите, процесс довольно простой. Давайте реализуем его на практике.

Определение глубины иерархии Для определения глубины иерархии типа родитель–потомок можно использовать функцию PATH(ID, ParentID). Функция PATH() возвращает строку, разделенную символами вертикальной черты (|), начинающуюся с родителя и  оканчивающуюся текущим потомком. Давайте создадим вычисляемый столбец со следующей формулой DAX: Path = PATH('Parent Child'[ID]; 'Parent Child'[ParentID])

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

Иерархии типа родитель–потомок    399

Рис. 10.39    Создание вычисляемого столбца с иерархическим путем ПРИМЕЧАНИЕ ОБ ИСПОЛЬЗОВАНИИ ФУНКЦИИ PATH()  Параметры ID и ParentID должны иметь одинаковый тип данных – либо integer, либо text. Значения из столбца ParentID должны присутствовать в столбце ID. Функция PATH() не сможет найти родителя, если уровень потомка не существует. Если значение ParentID равно null, значит, мы имеем дело с корневым элементом иерархии. Каждому ID (уровень потомка) может соответствовать один и только один ParentID. В  противном случае функция PATH() вернет ошибку. Если ID  – пустое значение (BLANK()), то функция PATH() вернет BLANK().

Теперь, когда мы заполнили столбец Path иерархическими путями, можно быстро определить глубину иерархии при помощи функции PATH­L ENGTH(Path­ Column). Создадим еще один вычисляемый столбец со следующим выражением DAX: Path Length = PATHLENGTH('Parent Child'[Path])

На рис. 10.40 показан вывод этого выражения.

Рис. 10.40    Вычисление длины пути

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

400    Продвинутые техники моделирования данных

Создание уровней иерархии Итак, мы определили уровень нашей иерархии, равный четырем, и теперь нам необходимо создать четыре дополнительных вычисляемых столбца с уровнями иерархии. Для определения этих уровней можно воспользоваться функцией PATHITEM(Path, Path Length, Datatype), возвращающей элемент для указанной длины пути (Path Length) в рамках столбца Path. Иными словами, функция PATHITEM() возвращает конкретные значения каждого уровня иерархии. С  помощью необязательного параметра Datatype можно определить тип данных для вывода: INTEGER или TEXT. Значением параметра Datatype по умолчанию является TEXT. Давайте разберемся, как работает функция PATHITEM(). К примеру, выражение PATHITEM('Parent Child'[Path], 2, INTEGER) можно прочитать так: «Верни целочисленное значение из столбца Path для второго уровня иерархии». На рис. 10.41 показан вывод этого выражения.

Рис. 10.41    Результат выполнения выражения PATHITEM('Parent Child'[Path], 2, INTEGER)

Как видите, функция PATHITEM() возвращает идентификатор элемента заданного уровня. Но нам нужен не идентификатор, а  соответствующее ему имя элемента. Для его извлечения можно воспользоваться функцией LOOKUPVALUE(Returning Column, Lookup Column, Lookup Value). К примеру, следующее выражение вернет значения из столбца Name, соответствующие идентификаторам на втором уровне иерархии: Level 2 Name = LOOKUPVALUE( 'Parent Child'[Name] ; 'Parent Child'[ID] ; PATHITEM('Parent Child'[Path]; 2; INTEGER) )

Вывод этого выражения показан в виде вычисляемого столбца на рис. 10.42.

Иерархии типа родитель–потомок    401

Рис. 10.42    Новый вычисляемый столбец Level 2 Name

Для первого элемента в новом столбце стоит пустое значение. Иерархии, в которых есть пустые значения, называются неоднородными (ragged hierarchy). Неоднородные иерархии могут приводить пользователей в замешательство при выводе в визуализациях по причине появления пустых значений BLANK(). Одним из способов избавиться от неоднородности иерархии является наложение на нее фильтра на пустые значения. Также для этого можно использовать выражения на языке DAX. Нужно только проверять значение в столбце Path Length. Если оно больше или равно указанному уровню иерар­ хии, возвращаем соответствующее значение из столбца Name. В противном случае возвращаем значение столбца Name для предыдущего уровня. Очевидно, что для первого уровня иерархии мы не найдем значений null, поэтому и проверять значение столбца Path Length не обязательно. Итак, создадим четыре вычисляемых столбца с приведенными ниже выражениями для каждого уровня иерархии, начиная с первого: Level 1 Name = LOOKUPVALUE( 'Parent Child'[Name] ; 'Parent Child'[ID] ; PATHITEM('Parent Child'[Path]; 1; INTEGER) ) Level 2 Name = IF( 'Parent Child'[Path Length] >=2 ; LOOKUPVALUE( 'Parent Child'[Name] ; 'Parent Child'[ID] ; PATHITEM('Parent Child'[Path]; 2; INTEGER) ) //End LOOKUPVALUE ; 'Parent Child'[Level 1 Name] ) // End IF Level 3 Name = IF(

402    Продвинутые техники моделирования данных 'Parent Child'[Path Length] >=3 ; LOOKUPVALUE( 'Parent Child'[Name] ; 'Parent Child'[ID] ; PATHITEM('Parent Child'[Path]; 3; INTEGER) ) //End LOOKUPVALUE ; 'Parent Child'[Level 2 Name] ) // End IF Level 4 Name = IF( 'Parent Child'[Path Length] >=4 ; LOOKUPVALUE( 'Parent Child'[Name] ; 'Parent Child'[ID] ; PATHITEM('Parent Child'[Path]; 4; INTEGER) ) //End LOOKUPVALUE ; 'Parent Child'[Level 3 Name] ) // End IF

На рис.  10.43 показан результат выполнения этих выражений. Заметьте, что мы удалили столбцы Level 1 ID и Level 2 ID за ненадобностью.

Рис. 10.43    Четыре новых вычисляемых столбца с уровнями иерархии

Итак, мы заполнили значения по всем четырем уровням иерархии. Теперь можно воссоздать саму иерархию с помощью этих уровней. На рис. 10.44 показана новая иерархия и ее визуальное представление на срезе. В этом разделе мы говорили об иерархиях типа родитель–потомок. В процессе обсуждения мы рассмотрели самый простой пример, но использованные принципы можно применить и  к  гораздо более сложным сценариям с  иерархиями сотрудников, отделов и  штатного расписания. В  следующем разделе мы поговорим о  ролевых измерениях и  способах их реализации в Po­wer BI.

Ролевые измерения    403

Рис. 10.44    Иерархия типа родитель–потомок

Ролевые измерения Ролевые измерения (roleplaying dimension) встречаются в практике моделирования данных достаточно часто. Сам термин был унаследован из области многомерного моделирования в  SQL Server Analysis Services. Прежде чем приступить к созданию ролевых измерений, давайте разберемся, о чем вообще идет речь. Мы используем концепцию ролевых измерений всякий раз, когда создаем несколько связей между таблицей фактов и измерением, каждая из которых выполняет определенную роль. Наиболее часто встречаемые ролевые измерения в моделях данных – это измерения даты и времени. К примеру, в таб­ли­це фактов может быть сразу несколько полей с датами для разных событий (Order Date, Due Date, Ship Date), которые являются основой для связей таб­ли­цы фактов с  календарным измерением. При этом каждая дата характеризуется конкретной ролью в анализе. Иными словами, мы можем посредством связи с таблицей дат проводить различные виды анализа. К примеру, можно посчитать сумму продаж (Sales Amount) по дате заказа (Order Date), и она будет отличаться от суммы продаж по другим полям с датами (Due Date или Ship Date). Но есть небольшая проблема, состоящая в том, что движок xVelocity не поддерживает одновременное присутствие нескольких активных связей между двумя таб­ли­ца­ми. Однако мы можем программно активировать нужную нам связь посредством функции USERELATIONSHIP() в DAX на время выполнения вычисления. Для этого можно использовать ее внутри функции CALCULATE(). Теперь, когда вы знаете, с  какой целью применяются ролевые измерения, давайте реализуем их на примере файла с источником AdventureWorksDW2017.xlsx. Для этого выполните следующие действия.

404    Продвинутые техники моделирования данных 1. Откройте Po­wer BI Desktop, создайте подключение к файлу AdventureWorksDW2017.xlsx и извлеките данные из таб­лиц Reseller_Sales и Dates, как показано на рис. 10.45.

Рис. 10.45    Получение данных из таб­лиц Reseller_Sales и Dates

2. Создайте следующие связи между таб­ли­ца­ми Reseller_Sales и Dates, сделав активной первую из них: •• Reseller_Sales (OrderDateKey) => Dates (DateKey); •• Reseller_Sales (DueDateKey) => Dates (DateKey); •• Reseller_Sales (ShipDateKey) => Dates (DateKey).

Рис. 10.46    Связи между таб­ли­ца­ми Reseller_Sales и Dates

Теперь давайте создадим меры – по одной для каждой конкретной роли и с соответствующими ролям именами.

Ролевые измерения    405 ПРИМЕЧАНИЕ  Помните, что активная связь между таб­ли­ца­ми будет использоваться по умолчанию при всех вычислениях в модели данных. В связи с этим рекомендуется делать активной ту связь, которая лучше остальных подходит для этого с точки зрения бизнес-логики. В нашем случае наибольший смысл имеет оставить активной связь со столбцом Order Date, что мы и сделали.

Итак, создадим меру Reseller Sales by Order Date с использованием следующего выражения DAX: Reseller Sales by Order Date = SUM(Reseller_Sales[SalesAmount])

Формула для меры Reseller Sales by Due Date будет чуть посложнее: Reseller Sales by Due Date = CALCULATE([Reseller Sales by Order Date] ; USERELATIONSHIP(Dates[DateKey]; Reseller_Sales[DueDateKey]) )

И для последней меры Reseller Sales by Ship Date выражение будет почти таким же: Reseller Sales by Ship Date = CALCULATE([Reseller Sales by Order Date] ; USERELATIONSHIP(Dates[DateKey]; Reseller_Sales[ShipDateKey]) )

Как видите, при вычислении меры Reseller Sales by Order Date мы не использовали функцию USERELATIONSHIP(), поскольку активной связью между таб­ли­ца­ми Reseller_Sales и Dates является связь по полю OrderDateKey. Теперь можно использовать рассчитанные меры в  визуализации. На рис.  10.47 показан одновременный вывод в  матрице всех трех созданных мер.

Рис. 10.47    Визуализация ролевых измерений

406    Продвинутые техники моделирования данных Если у вас есть опыт проектирования многомерных моделей данных, вы могли бы задуматься о создании нескольких измерений Date. И хотя такой подход к реализации ролевых измерений тоже существует, мы не рекомендуем идти этим путем. Вот лишь несколько аргументов против создания нескольких таб­лиц с датами для поддержки разных ролей:   наличие нескольких календарей в модели данных (даже двух) может запутать пользователей, строящих отчеты;   этот подход ведет к увеличению размера модели данных и объема расходуемой памяти;   такую реализацию сложно будет поддерживать. Мы встречали сценарии с десятком ролей, и создавать для них десять таб­лиц с календарями было бы просто неразумно.

Использование групп вычислений Создание групп вычислений (calculation group) – это одна из наиболее полезных возможностей для разработчиков Po­wer BI, позволяющая существенно сократить количество мер в  модели данных. С  помощью этой концепции можно легко избавиться от множества мер, которые в  этом случае станут просто избыточными. Создание этих мер может быть очень утомительным и отнимать немало времени. Представьте, что у нас есть базовая мера с именем Sales Amount. Зачастую мы не обходимся одной лишь базовой версией меры, а создаем множество производных от нее мер, использующих логику операций со временем. Обычно они называются Sales Amount YTD, Sales Amount QTD, Sales Amount MTD, Sales Amount LYTD, Sales Amount LQTD, Sales Amount LMTD и  т. д. Мы видели модели данных, в  которых было создано до 20 производных мер на основе базовой. Но страшно не это, а то, что таких базовых мер в модели данных может быть не одна, а множество. И для каждой придется создавать по 20 производных мер. Наверное, не стоит объяснять, сколько времени это может занять. Но с  применением групп вычислений нам достаточно будет один раз создать набор шаблонных ссылочных мер (referencing measure), после чего можно будет использовать его применительно к  любой базовой мере в  модели. Иными словами, наши меры можно будет использовать повторно, что очень удобно. Сначала группы вычислений были доступны только в SQL Server Analysis Services Tabular 2019, Azure Analysis Service и Po­wer BI Premium. Однако сегодня их можно создавать при наличии любой лицензии Po­wer BI, даже бесплатной. Увы, на момент написания книги в  Po­wer BI Desktop не было предусмотрено средства для управления группами вычислений, так что вам придется воспользоваться сторонним инструментом Tabular Editor, созданным Дэниелом Отикиером (Daniel Otykier). Прежде чем начать создавать собственные группы вычислений, давайте ознакомимся с сопутствующими требованиями и терминологией.

Использование групп вычислений    407

Требования Как мы уже упоминали, пока в Po­wer BI Desktop отсутствует возможность создания групп вычислений. В связи с этим вам придется выполнить некоторые действия, чтобы получить доступ к этому функционалу:   загрузите инструмент Tabular Editor по адресу https://tabulareditor.com;   следующее требование применимо к версиям Po­wer BI Desktop до сентября 2020, так что вы можете пропустить этот пункт, если у вас более поздняя версия программы. Вам нужно будет установить переключатель Хранение наборов данных с использованием расширенного формата метаданных (Store datasets using enhanced metadata format) в разделе Предварительные версии возможностей (Preview features) в параметрах Po­wer BI Desktop, как показано на рис. 10.48;

Рис. 10.48    Активация хранения наборов данных в расширенном формате метаданных

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

Терминология Теперь давайте ознакомимся с  терминами, применяемыми при работе с группами вычислений:

408    Продвинутые техники моделирования данных   группа вычислений: по сути, группа вычислений является таблицей, содержащей элементы вычисления: •• очередность (precedence): у каждой группы вычислений существует свойство Precedence, с  помощью которого можно указать очередность вычислений при наличии нескольких групп вычислений. Группы вычислений с  более высокой очередностью будут применяться первыми;   элемент вычисления (calculation item): элементы вычисления создаются внутри группы вычислений при помощи языка DAX. Элементы вычисления напоминают шаблонные меры, которые могут выполняться с любыми явными мерами, присутствующими в модели данных. Каждый элемент вычисления характеризуется двумя полями: текстовым свойством Name и целочисленным Ordinal. В поле Name хранится имя элемента вычисления. Поле Ordinal является скрытым и  отвечает за порядок сортировки поля Name. Иными словами, столбец Ordinal упорядочивает поле Name. Элементов вычисления можно создать столько, сколько необходимо: •• Ordinal: у каждого элемента вычисления есть свойство Ordinal. При помощи него задается порядок, в  котором элементы вычисления будут располагаться при визуализации в отчетах. Если свойство Ordinal не установлено, элементы вычисления будут упорядочены по алфавиту. Свойство Ordinal не оказывает влияния на то, в каком порядке будут применяться элементы вычисления;   косвенная рекурсия (sideways recursion): этот термин относится к ситуа­ ции, в  которой элемент вычисления ссылается на другие элементы вычисления в рамках одной группы вычислений. Возникновение косвенной рекурсии допускается, если при этом не возникает бесконечных циклов (infinite loop), когда элемент вычисления A ссылается на элемент вычисления B и наоборот. Бесконечный цикл также может возникнуть, когда элемент вычисления ссылается на явную меру, которая ссылается на исходный элемент вычисления. Рекомендуется избегать возникновения косвенной рекурсии. Теперь, когда мы познакомились с требованиями и терминологией, связанными с группами вычислений, пришло время попробовать сделать что-то на практике.

Группы вычислений и логика операций со временем Одной из самых распространенных областей применения групп вычислений являются меры для работы с  логикой операций со временем. Начнем без промедлений и создадим группу вычислений с именем Time Intelligence, в  рамках которой впоследствии создадим несколько элементов вычисления для работы со временем. В этом разделе мы будем работать с файлом

Использование групп вычислений    409

Chapter 10, Calculation Groups.pbix, источником данных для которого служит файл Excel AdventureWorksDW2017.xlsx. Мы уже загрузили в модель таб­ли­цы Internet_Sales и Dates и произвели с ними некоторые действия по переименованию столбцов. Мы также избавились от ненужных столбцов, после чего импортировали данные в модель, пометив таб­ли­цу Dates как таб­ли­цу для работы с датами. Попутно мы загрузили и установили в качестве внешнего инструмента Tabular Editor v.2. Теперь пришло время выполнить следующие действия. 1. Нажмите на кнопку Tabular Editor на вкладке Внешние инструменты (External Tools), как показано на рис. 10.49.

Рис. 10.49    Открытие Tabular Editor в качестве внешнего инструмента

2. В открывшемся окне Tabular Editor щелкните правой кнопкой мыши по узлу Tables, наведите на выпадающее меню Create New и выберите пункт Calculation Group, как показано на рис.  10.50. Эту операцию можно выполнить также при помощи сочетания клавиш Alt+7.

Рис. 10.50    Создание новой группы вычислений в Tabular Editor

3. Назовите созданную группу Time Intelligence. 4. Установите свойству группы Calculation Group Precedence значение 10, как на рис. 10.51.

410    Продвинутые техники моделирования данных

Рис. 10.51    Создание группы вычислений

5. Переименуйте столбец Name в Time Calculations. 6. Щелкните правой кнопкой мыши на узле Calculation Items и выберите пункт New Calculation Item. Последние шаги показаны на рис. 10.52.

Щелчок правой кнопкой мыши и выбор New Calculation Item

Переименуем в Time Calculations

Рис. 10.52    Создание элементов вычисления в Tabular Editor

7. Назовите созданный элемент вычисления Current. Он будет показывать текущее значение выбранной меры.

Использование групп вычислений    411

8. Введите в окно Expression Editor выражение SELECTEDMEASURE(). 9. Установите свойству Ordinal значение 0. 10. Нажмите на кнопку с  галочкой (Accept changes), как показано на рис. 10.53.

Рис. 10.53    Добавление выражения DAX для группы вычислений

11. Создайте следующий элемент вычисления, назовите его YTD, задайте выражение TOTALYTD(SELECTEDMEASURE(); 'Dates'[Date]) и  установите свойству Ordinal значение 1, как показано на рис. 10.54.

Рис. 10.54    Создание еще одного элемента вычисления

412    Продвинутые техники моделирования данных 12. Нажмите на кнопку с дискетой (Save), показанную на рис. 10.55, чтобы применить изменения к нашей модели данных в Po­wer BI Desktop.

Рис. 10.55    Сохранение изменений в Tabular Editor и перенос их в Po­wer BI Desktop

13. Вернитесь в  окно Po­wer BI Desktop и  нажмите на кнопку Обновить сейчас (Refresh now) на желтой полоске, как на рис. 10.56.

Рис. 10.56    Обновление группы вычислений после переноса изменений в Po­wer BI Desktop

Похожим образом можно создать столько элементов вычисления, сколько потребуется. В нашем примере мы добавили семь элементов, что видно на рис. 10.57. Давайте внимательно присмотримся к  характеристикам созданных элементов вычисления в табл. 10.1.

Использование групп вычислений    413

Рис. 10.57    Элементы вычисления в примере

Таб­ли­ца 10.1. Все элементы вычисления, их выражения и свойства Ordinal в нашей модели данных Элемент Выражение DAX вычисления SELECTEDMEASURE() Current

0

YTD

1

MTD

LMTD

LYTD

LYTD SwR

LY MTD

TOTALYTD( SELECTEDMEASURE() ; 'Dates'[Date] ) TOTALMTD( SELECTEDMEASURE() ; 'Dates'[Date] ) TOTALMTD( SELECTEDMEASURE() ; DATEADD('Dates'[Date]; -1; MONTH) ) TOTALYTD( SELECTEDMEASURE() ; DATEADD('Dates'[Date]; -1; YEAR) ) CALCULATE( SELECTEDMEASURE() ; DATEADD('Dates'[Date]; -1; YEAR) ; 'Time Intelligence'[Time Calculations] = "YTD" ) TOTALMTD( SELECTEDMEASURE() ;SAMEPERIODLASTYEAR('Dates'[Date]) )

Ordinal

Описание Показывает текущее значение выбранной меры Нарастающий итог с начала года

2

Нарастающий итог с начала месяца

3

Нарастающий итог с начала месяца за предыдущий месяц

4

Нарастающий итог с начала года за предыдущий год

5

Нарастающий итог с начала года за предыдущий год с косвенной рекурсией Нарастающий итог с начала месяца за аналогичный период в прошлом году

6

414    Продвинутые техники моделирования данных Таблица 10.1 (окончание) Элемент Выражение DAX вычисления var _current = SELECTEDMEASURE() YOY% val _ly = CALCULATE( SELECTEDMEASURE() ; DATEADD('Dates'[Date]; -1; YEAR) ) return DIVIDE(_current - _ly; _ly)

Ordinal 7

Описание Годовое изменение в процентах

Обратите внимание на элемент вычисления LYTD SwR. Он представляет собой пример использования косвенной рекурсии. Результаты вычисления элементов LYTD SwR и LYTD будут одинаковые. Мы просто хотели продемонстрировать косвенную рекурсию в действии. Но мы по-прежнему советуем избегать применения этой концепции там, где это возможно, поскольку она может вносить дополнительную сложность в выражения. К тому же эти меры будет сложно использовать тем, кто незнаком с косвенной рекурсией. Теперь, когда мы закончили создание элементов вычисления, давайте опробуем их.

Тестирование групп вычислений Как мы уже упомянули, группы вычислений работают только применительно к явным мерам. Так что нам необходимо создать хотя бы одну меру, чтобы проверить работу групп вычислений. Мы остановили выбор на простом суммировании по полям SalesAmount и OrderQuantity: Total Sales = SUM('Internet Sales'[SalesAmount]) Quantity Ordered = SUM('Internet Sales'[OrderQuantity])

Выполните следующие действия, чтобы проверить работу созданной группы вычислений. 1. Разместите на странице отчета в Po­wer BI Desktop матрицу и перенесите на ее строки поля Year, Month и Date из таб­ли­цы Dates. 2. Перенесите поле Time Calculations из группы вычислений Time Intelligence в область Столбцы (Columns). 3. Перенесите меру Total Sales из таб­ли­цы Internet Sales в область Значения (Values). Как видно по рис.  10.58, существует проблема с  форматированием значений в столбце YoY%. В следующем разделе мы вместе исправим эту проб­ лему.

Использование групп вычислений    415

Рис. 10.58    Визуализация группы вычислений в матрице

Проблема с форматированием строк На рис.  10.58 мы видим, что все элементы вычисления, созданные нами ранее в  рамках группы вычислений Time Intelligence, форматируются как валюта. При этом мы не задавали для них в явном виде строки форматирования. Созданные элементы вычисления наследуют правила форматирования от выбранной меры. И хотя зачастую это бывает удобно, для некоторых вычислений, как в случае с нашим элементом YoY%, нужен альтернативный подход. Нам необходимо настроить вывод этого поля в процентах вне зависимости от того, какие правила форматирования заданы для выбранной меры. Чтобы сделать это, откройте Tabular Editor и для элемента вычисления YoY% задайте строку форматирования (свойство Format String Expression) следующего вида: "0.00%", как показано на рис. 10.59. ПРИМЕЧАНИЕ  Мы уже говорили подробно о правилах форматирования значений в главе 8.

На рис.  10.60 показана итоговая визуализация в  Po­wer BI Desktop после сохранения изменений. Как видно по рис. 10.60, проблема с форматами осталась в прошлом.

416    Продвинутые техники моделирования данных

Рис. 10.59    Решение проблемы с форматированием строк в Tabular Editor

Рис. 10.60    Матрица после решения проблемы с форматированием значений

Заключение    417

Функции DAX для групп вычислений Существует великое множество областей применения групп вычислений в моделях данных Po­wer BI, и вскоре, поработав с ними, вы сами это поймете. Здесь же мы хотим вам коротко рассказать о функциях DAX, предназначенных для работы с группами вычислений. В их число входят следующие функции:   SELECTEDMEASURE(): ссылка на базовую меру, к  которой применяется элемент вычисления. Подробнее об этой функции можно почитать по адресу https://docs.microsoft.com/en-us/dax/selectedmeasure-functiondax?WT.mc_id=%3FWT.mc_id%3DDP-MVP-5003466;   ISSELECTEDMEASURE( [Measure1], [Measure2], ... ): принимает на вход список явных мер, присутствующих в модели данных, и определяет, входит ли в него мера, выделенная в данный момент в визуальных элементах. Эта функция может быть использована для применения условной логики вычислений. О функции ISSELECTEDMEASURE( [Measure1], [Measure2], ... ) можно подробно узнать по адресу https://docs.microsoft.com/ en-us/dax/isselectedmeasure-function-dax?WT.mc_id=%3FWT.mc_id%3DDPMVP-5003466;   SELECTEDMEASURENAME(): возвращает имя выбранной меры. Также может быть применена для реализации условной логики вычислений. Почитать о функции SELECTEDMEASURENAME() можно по адресу https://docs.microsoft.com/en-us/dax/selectedmeasurename-function-dax?WT.mc_id=%3FWT. mc_id%3DDP-MVP-5003466;   SELECTEDMEASUREFORMATSTRING(): возвращает строку форматирования, определенную для выбранной меры. Может быть использована для динамического указания формата вывода на основе выражения. Больше о  функции SELECTEDMEASUREFORMATSTRING() можно узнать по адресу https://docs.microsoft.com/en-us/dax/selectedmeasureformatstring-functiondax?WT.mc_id=%3FWT.mc_id%3DDP-MVP-5003466.

Заключение В этой главе мы узнали о некоторых продвинутых техниках моделирования данных, а также научились агрегировать информацию в Po­wer BI на основе больших данных. Кроме того, мы поговорили о том, как можно настроить добавочное обновление, позволяющее комфортно работать с  объемными источниками данных. Помимо этого, мы рассмотрели концепцию иерархий типа родитель–потомок и научились применять ее в Po­wer BI Desktop. В заключение мы узнали, что из себя представляют ролевые измерения, а также познакомились с очень важным аспектом моделирования данных, представленным группами вычислений. В следующей главе мы затронем тему безопасности данных – первостепенную для организаций, считающих, что только конкретные люди должны иметь доступ к конкретным данным, и точка.

Глава

11 Безопасность на уровне строк

В предыдущей главе мы познакомились с такими продвинутыми техниками моделирования данных, как агрегация, добавочное обновление, иерархии, ролевые измерения и группы вычислений. Здесь же мы поговорим о важнейшей концепции в области безопасности данных, именуемой безопасностью на уровне строк (row-level security – RLS). Основные темы, которые мы затронем в главе:   безопасность на уровне строк при моделировании данных;   терминология безопасности на уровне строк;   реализация безопасности на уровне строк;   распространенные подходы в  организации безопасности на уровне строк. Мы постараемся осветить эти темы на реальных сценариях, но вы должны понимать, что у конкретных проектов в Po­wer BI могут быть свои специфические требования в области безопасности, и все их описать просто невозможно. Когда речь заходит о безопасности в Po­wer BI, многие думают о том, что этими вопросами должны заниматься исключительно администраторы Po­ wer BI. Это правда, но не вся. Концепция безопасности на уровне строк позволяет осуществлять фильтрацию модели данных с целью обеспечения доступа к данным конкретным пользователям, так что здесь речь идет о механизме контроля доступа, применяемого к модели данных. В этом аспекте безопасность на уровне строк имеет непосредственное отношение к разработчику модели данных. В  конечном же счете мы публикуем нашу модель данных в службе Po­wer BI или Po­wer BI Report Server, где другие пользователи, включая участников (contributor) и конечных пользователей, могут видеть и использовать нашу модель данных. С этой точки зрения вопросы безопасности данных ложатся на разные подразделения в  зависимости от организации. В  одних организациях вопросами тонкой настройки безопасности данных на уровне строк в службе Po­wer BI или Po­wer BI Report Server занимаются исключительно администраторы Po­wer BI. В других эти обязанности отдаются на откуп разработчику модели данных – от проектирования и до воплощения и поддержки. Второй случай чаще встречается в небольших компаниях, где

Безопасность на уровне строк при моделировании данных    419

разработчик Po­wer BI сам занимается созданием модели данных, ее развертыванием и  администрированием. Вне зависимости от того, на чьи плечи ложатся обязанности по обеспечению безопасности данных на уровне строк в вашей конкретной организации, мы в этой главе пройдем полный цикл от проектирования до реализации и настройки системы безопасности. Что ж, приступим!

Безопасность на уровне строк при моделировании данных Как мы уже сказали, безопасность на уровне строк (RLS) в Po­wer BI представляет собой механизм контроля доступа к данным. С его помощью можно разрешить доступ к специфическим данным только конкретным пользователям или группам. Этот механизм может быть реализован достаточно просто – путем написания фильтрующих выражений на языке DAX для определенных пользователей или групп, – а может включать и более сложные методы вплоть до внесения изменений в модель данных. В этом случае на первый план выходят связи между таб­ли­ца­ми и  направление кросс-фильтрации в этих связях. На момент написания книги настройка безопасности на уровне строк возможна только в Po­wer BI Desktop.

Чем безопасность на уровне строк не является Как мы уже сказали, безопасность на уровне строк представляет собой не что иное, как фильтрацию данных в модели. В настоящий момент механизм безопасности на уровне объектов (object-level security – OLS) доступен только в публичном предварительном просмотре. Более подробно о нем мы будем говорить в главе 12. ПРИМЕЧАНИЕ  Мы не можем управлять видимостью данных для разработчиков внутри Po­wer BI Desktop при помощи механизма безопасности на уровне строк – это может быть сделано только в источнике данных. Вне зависимости от настроек безопасности на уровне строк разработчик будет иметь полный доступ ко всем данным в источнике, так что это только механизм ограничения доступа к данным, а не настройки разрешений.

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

420    Безопасность на уровне строк

Роли Ролью (role) называется имя, определяющее характеристики правила безопас­ ности на уровне таб­лиц в модели данных. Для ролей всегда желательно выбирать понятные имена, однозначно описывающие соответствующие правила безопасности. Определить роли в  Po­wer BI Desktop можно, выполнив следующие действия. 1. Перейдите на верхнюю вкладку Моделирование (Modeling). 2. Нажмите на кнопку Управление ролями (Manage roles). 3. Нажмите на кнопку Создать (Create) для добавления новой роли. Эти шаги схематически показаны на рис. 11.1.

Рис. 11.1    Управление ролями в Po­wer BI Desktop

Правила Правила безопасности (security rules), или просто правила, описываются при помощи языка DAX и определяют данные, доступные для конкретной роли. Выражения DAX, определяющие правила, возвращают значение true или false. Для добавления нового правила выполните следующие действия. 1. Нажмите на кнопку Управление ролями (Manage roles) на вкладке Моделирование (Modeling). 2. Нажмите на кнопку Создать (Create) и введите выражение DAX, возвращающее true или false. Также вы можете воспользоваться кнопками с тремя точками справа от имен таб­лиц для добавления в выражение названий столбцов.

Безопасность на уровне строк при моделировании данных    421

3. Нажмите на кнопку Проверьте выражение DAX (Verify DAX expression) с галочкой. На рис. 11.2 показан фильтр, ограничивающий данные в таб­ли­це Currency только продажами в валюте AUD. Назвали мы эту роль AUD Sales Only.

Рис. 11.2    Определение правила безопасности на уровне строк

Проверка ролей При создании ролей и правил необходимо как-то проверять их работоспособность. Тестирование ролей также называется проверкой их достоверности (validating roles). Проверять роли можно как в Po­wer BI Desktop, так и в службе Po­wer BI. Для выполнения проверки в  Po­wer BI Desktop нужно выполнить следующие действия. 1. Нажмите на кнопку Просмотреть как (View as) на вкладке Моделирование. 2. Выберите роль для проверки. 3. Нажмите на кнопку OK. Эти шаги показаны на рис. 11.3. На рис.  11.4 видно, что данные на визуализации после этого оказались ограничены только сделками, которые были совершены в  австралийских долларах (AUD). Для прекращения проверки необходимо нажать на кнопку Остановить просмотр (Stop viewing).

422    Безопасность на уровне строк

Рис. 11.3    Проверка ролей

Рис. 11.4    Проверка результатов фильтрации данных

Безопасность на уровне строк при моделировании данных    423

Назначение участникам ролей в службе Power BI После реализации механизма безопасности на уровне строк необходимо приписать роли конкретным участникам или группам. Управление участниками ролей выполняется в службе Po­wer BI или Po­wer BI Report Server. Ниже показана последовательность действий, которые нужно выполнить после публикации отчета в рабочей области для присвоения участникам роли. 1. Нажмите на кнопку RLS. 2. Нажмите на кнопку с тремя точками справа от набора данных. 3. Выберите в контекстном меню пункт Безопасность (Security). 4. Выберите роль и введите имя пользователя или группы. 5. Нажмите на кнопку Добавить (Add). Эти шаги показаны на рис. 11.5.

Рис. 11.5    Назначение участникам ролей в службе Po­wer BI

Назначение участникам ролей в Power BI Report Server Следующие шаги нужно выполнить в Po­wer BI Report Server после публикации отчета на сервере. 1. Откройте браузер и перейдите в Po­wer BI Report Server. 2. Нажмите на кнопку с тремя точками рядом с нужным отчетом. 3. Выберите пункт управления отчетом (Manage). На рис. 11.6 схематически показаны эти действия.

424    Безопасность на уровне строк

Рис. 11.6    Управление отчетом в Po­wer BI Report Server

4. Перейдите в раздел безопасности на уровне строк (Row-level security). 5. Нажмите на кнопку добавления участника (Add Member), как показано на рис. 11.7.

Рис. 11.7    Управление безопасностью на уровне строк в Po­wer BI Report Server

6. Введите имя пользователя или группы. 7. Выберите присваиваемую пользователю роль. 8. Нажмите на кнопку OK. Последние шаги отображены на рис. 11.8.

Реализация безопасности на уровне строк    425

Рис. 11.8    Назначение участникам ролей в Po­wer BI Report Server

После присвоения участникам определенных ролей они смогут видеть только доступные им данные.

Реализация безопасности на уровне строк Реализация безопасности на уровне строк в Po­wer BI выполняется всегда одинаково применительно ко всем подходам и поддерживаемым режимам хранения. Реализовать безопасность на уровне строк можно в модели данных, при этом набор данных может быть импортирован или храниться в режиме DirectQuery или смешанном режиме. Процедура будет всегда одинаковой и состоять из следующих шагов. 1. Создание ролей безопасности. 2. Определение правил внутри ролей. 3. Проверка ролей в Po­wer BI Desktop. 4. Публикация отчета в службе Po­wer BI или Po­wer BI Report Server. 5. Назначение участникам ролей в службе Po­wer BI или Po­wer BI Report Server. 6. Проверка ролей в службе Po­wer BI (в Po­wer BI Report Server проверка ролей невозможна). На рис. 11.9 показана диаграмма, описывающая эти действия.

426    Безопасность на уровне строк

Определение правил в Power BI Desktop Создание ролей в Power BI Desktop

Публикация в службе Power BI

Назначение участникам ролей в службе Power BI Проверка ролей в службе Power BI

Проверка ролей в Power BI Desktop Публикация в Power BI Report Server

Назначение участникам ролей в Report Server

Рис. 11.9    Реализация безопасности на уровне строк

В следующем разделе мы рассмотрим общие подходы к  реализации безопас­ности на уровне строк.

Распространенные подходы в организации безопасности на уровне строк Обычно при реализации безопасности на уровне строк в  Po­wer BI Desktop применяют один из двух подходов: статический или динамический. В следующих разделах мы рассмотрим оба подхода на реальных сценариях.

Статическая безопасность на уровне строк Статическая безопасность на уровне строк (static RLS) используется при определении статических правил фильтрации модели данных. К примеру, на рис. 11.2 была показана ситуация, в которой мы создали постоянный фильтр таб­ли­цы Internet Sales по валюте AUD. Статический подход к  безопасности на уровне строк бывает реализовать достаточно просто, но с  поддержкой могут возникнуть сложности. Впрочем, иногда этого метода вполне достаточно для обеспечения требований бизнес-логики. К примеру, если в модели данных отсутствуют необходимые сведения для реализации динамического подхода к  безопасности на уровне строк, можно остановиться на статическом. В  ка­честве примера можно привести международную организацию с  несколькими группами безопасности в  Azure Active Directory (Azure AD) или Microsoft 365 и разделением пользователей по их географическому положению. В нашем примере с организацией Adventure Works будет две группы безопасности: одна – для Австралии, вторая – для остального мира. Нам требуется реализовать безопасность на уровне строк таким образом, чтобы пользователи из Австралии могли видеть только свои суммы продаж в таб­ ли­це Internet Sales. В то же время остальные пользователи должны видеть все продажи, за исключением австралийских.

Распространенные подходы в организации безопасности на уровне строк    427

В следующих разделах мы реализуем механизм безопасности на уровне строк на основании этих требований.

Создание ролей и определение правил 1. Нажмите на кнопку Управление ролями (Manage roles) на вкладке Моделирование (Modeling). 2. Нажмите на кнопку Создать (Create). 3. В качестве названия роли введите AUD Sales Only. 4. Нажмите на кнопку с тремя точками справа от таб­ли­цы Currency. 5. Наведите мышь на выпадающий пункт меню Добавить фильтр (Add filter). 6. Выберите поле [CurrencyAlternateKey]. Предыдущие шаги показаны на рис. 11.10.

Рис. 11.10    Создание роли AUD Sales Only в Po­wer BI Desktop

7. Это автоматически создаст выражение DAX вида [CurrencyAlternateKey] = "Value". Замените слово Value в формуле на AUD. 8. Нажмите на кнопку Проверьте выражение DAX (Verify DAX expression) с галочкой. Эти шаги отображены на рис. 11.11. 9. Снова нажмите на кнопку Создать (Create). 10. В качестве названия роли введите Non-AUD Sales. 11. Нажмите на кнопку с тремя точками справа от таб­ли­цы Currency. 12. Наведите мышь на выпадающий пункт меню Добавить фильтр (Add filter). 13. Выберите поле [CurrencyAlternateKey]. 14. Измените созданное выражение DAX на следующее: [CurrencyAlternateKey] "AUD".

428    Безопасность на уровне строк

Рис. 11.11    Определение нового правила

15. Нажмите на кнопку Проверьте выражение DAX (Verify DAX expression) с галочкой. 16. Нажмите на кнопку Сохранить (Save). Эти шаги показаны на рис. 11.12.

Рис. 11.12    Создание роли Non-AUD Sales в Po­wer BI Desktop

Итак, мы создали наши роли. Теперь пришло время проверить их.

Проверка ролей Следующие действия позволят проверить работоспособность созданных ролей в Po­wer BI Desktop. 17. Нажмите на кнопку Просмотреть как (View as) на вкладке Моделирование. 18. Выберите роль для проверки.

Распространенные подходы в организации безопасности на уровне строк    429

19. Нажмите на кнопку OK. 20. По окончании проверки нажмите на кнопку Остановить просмотр (Stop viewing). На рис. 11.13 показана процедура проверки роли Non-AUD Sales.

Результат проверки роли Non-AUD Sales

Рис. 11.13    Проверка роли Non-AUD Sales

Теперь, когда мы проверили созданные роли и убедились, что они работают так, как и ожидалось, нужно опубликовать отчет в службе Po­wer BI, чтобы назначить роли пользователям.

Публикация отчета в службе Power BI Выполните приведенные ниже действия, чтобы опубликовать отчет в службе Po­wer BI. 21. Н ажмите на кнопку Опубликовать (Publish) на вкладке Главная (Home). 22. Выберите желаемую рабочую область из списка. 23. Нажмите на кнопку Выбрать (Select). Эти шаги показаны на рис. 11.14.

430    Безопасность на уровне строк

Рис. 11.14    Публикация отчета в службе Po­wer BI

После публикации отчета необходимо открыть службу Po­wer BI для назначения ролей участникам.

Назначение участникам ролей После входа в службу Po­wer BI перейдите к рабочей области, в которой опуб­ ликовали отчет, и  выполните следующие действия, чтобы присвоить роли участникам. 24. Нажмите рядом с набором данных кнопку Дополнительные парамет­ ры (More options) с тремя точками. 25. Выберите в контекстном меню пункт Безопасность (Security). Эти шаги показаны на рис. 11.15. 26. Выберите нужную роль. 27. Введите имя пользователя или группы. В моем окружении задано две группы безопасности (AU Users и Non-AU Users), так что я присвою этим группам соответствующие роли. 28. Нажмите на кнопку Добавить (Add). 29. Нажмите на кнопку Сохранить (Save). На рис. 11.16 показаны эти действия. ПРИМЕЧАНИЕ  Для назначения пользователям ролей необходимо иметь права доступа к рабочей области уровня Администратор (Admin) или Член (Member). В противном случае опции безопасности будут недоступны в меню.

Распространенные подходы в организации безопасности на уровне строк    431

Рис. 11.15    Управление безопасностью на уровне строк для набора данных в службе Po­wer BI

Рис. 11.16    Назначение пользователям ролей

432    Безопасность на уровне строк На данный момент мы успешно настроили безопасность на уровне строк таким образом, чтобы пользователи из Австралии видели продажи только в  австралийских долларах, а  все остальные видели другие продажи, кроме продаж в австралийских долларах. Как уже было сказано, можно выполнить проверку ролей в службе Po­wer BI. Для проверки ролей в службе нет необходимости присваивать их пользователям. Итак, давайте протестируем роли в службе Po­wer BI.

Проверка ролей в службе Power BI Следующие действия позволят вам проверить работоспособность созданных ролей. 30. Нажмите на кнопку с тремя точками справа от роли. 31. Выберите пункт Проверить в качестве роли (Test as role). Заключительные шаги показаны на рис. 11.17.

Рис. 11.17    Проверка ролей в службе Po­wer BI

Это позволит открыть отчет от имени выбранной роли. На рис. 11.18 показано, как будет выглядеть отчет при выборе роли AUD Sales Only. Теперь, когда мы узнали, как реализовывать безопасность на уровне строк в  статике, рассмотрим более сложные сценарии, требующие применения динамического подхода к безопасности.

Динамическая безопасность на уровне строк При реализации безопасности на уровне строк зачастую бывает недостаточно статически присвоить пользователям роли. В этих случаях вы можете воспользоваться динамическим подходом к безопасности (dynamic RLS), который мы подробно рассмотрим в этом разделе.

Распространенные подходы в организации безопасности на уровне строк    433

Рис. 11.18    Проверка отчета от имени роли AUD Sales Only

Каждый пользователь имеет доступ только к своим данным Представьте, что мы имеем дело с  моделью данных с  продажами товаров и нам необходимо реализовать безопасность на уровне строк таким образом, чтобы каждому продавцу были доступны данные только о его собственных продажах. Статический подход при настройке безопасности здесь не подойдет по причине наличия большого количества продавцов. Должны ли мы для каждого продавца создавать отдельную роль в Po­wer BI Desktop и присваивать ему ее в службе Po­wer BI? Очевидно, что нет. Вместо этого мы можем создать общую роль, которая будет работать динамически на основании имени пользователя. Это, кстати, одна из самых распространенных реализаций механизма динамической безопасности на уровне строк. В этом разделе мы будем работать с файлом Chapter 11, Dynamic RLS.pbix. Реализовать описанный сценарий довольно просто. Для этого можно воспользоваться одной из двух приведенных ниже функций DAX для извлечения текущего имени пользователя:

434    Безопасность на уровне строк   USERNAME(): возвращает имя текущего пользователя (login name) в виде DOMAIN_NAME\USER_NAME при использовании в Po­wer BI Desktop. Пример: biinsight\soheil. При публикации отчета в службе Po­wer BI или Po­wer BI Report Server функция USERNAME() возвращает имя субъекта-пользователя (User Principal Name – UPN), например [email protected];   USERPRINCIPALNAME(): возвращает имя субъекта-пользователя при подключении. Это имя представлено в формате электронной почты, например [email protected]. Функция USERPRINCIPALNAME() не принимает параметров. Реализация безопасности на уровне строк в Po­wer BI имеет смысл только при публикации модели данных в службе Po­wer BI или Po­wer BI Report Server, так что использование функции USERPRINCIPALNAME() является предпочтительным. ПРИМЕЧАНИЕ  При встраивании отчетов в наше собственное приложение с использованием имен пользователей необходимо воспользоваться функцией USERNAME().

Пришло время реализовать наш сценарий на практике. Шаги по созданию ролей и  правил, проверке ролей, публикации отчета в  службе и  назначению ролей пользователям здесь будут такие же, как в предыдущем разделе, так что мы не будем повторно их описывать. Для настройки динамического механизма безопасности на уровне строк нам нужно только установить соответствие между именем текущего пользователя и  значением столбца EmailAddress из таб­ли­цы Employee. Выполните приведенные ниже действия. 1. Создайте роль и назовите ее Salespersons Access. 2. Создайте правило для таб­ли­цы Employee по столбцу EmailAddress. 3. Используйте выражение DAX [EmailAddress] = USERPRINCIPALNAME(). 4. Нажмите на кнопку Сохранить (Save). Эти шаги представлены на рис. 11.19.

Рис. 11.19    Реализация динамической безопасности с фильтрацией данных по полю EmailAddress

Распространенные подходы в организации безопасности на уровне строк    435 ПРИМЕЧАНИЕ  Для проверки ролей нет необходимости создавать визуализации. Достаточно переключиться на вкладку Данные.

5. Переключитесь на вкладку Данные. 6. Выберите таб­ли­цу Employee для просмотра ее содержимого. 7. Нажмите на кнопку Просмотреть как (View as) на вкладке Главная (Home). 8. Выберите роль Другой пользователь (Other user). 9. Введите электронный адрес для проверки роли. 10. Проверьте роль Salespersons Access. 11. Нажмите на кнопку OK. Эти шаги показаны на рис. 11.20.

Рис. 11.20    Проверка динамических ролей на вкладке Данные

На рис. 11.21 показан результат проверки роли Salespersons Access.

Рис. 11.21    Проверка роли Salespersons Access

436    Безопасность на уровне строк 12. Если вам интересно, как изменятся данные в отчетах, переключитесь на вкладку Отчет, как показано на рис. 11.22.

Рис. 11.22    Проверка ролей на вкладке Отчет

Теперь, когда мы убедились, что роль работает так, как и ожидалось, можно опубликовать отчет в службе Po­wer BI. Если у нас правильно настроена безопасность на уровне строк, продавцы должны видеть данные только о своих продажах при открытии отчета. На рис. 11.23 показана пара примеров визуализации. Как видно на рис. 11.23, при открытии отчета Алланом (Allan) выводятся только его продажи, а Эми (Amy) видит лишь свои данные.

Менеджер может видеть данные подчиненных Предыдущий сценарий был достаточно простым, несмотря на применение динамического механизма безопасности на уровне строк. А  именно продавцы могли видеть только свои продажи в  модели данных. Теперь давайте усложним сценарий. Представьте, что в  компании ввели новый отчет, которым остались довольны все, кроме менеджеров отделов и генерального директора. Менеджеров совершенно не устраивает, что они могут видеть только свои данные, но не данные своих подчиненных. А генеральный директор в таких условиях не будет видеть вообще никаких данных, поскольку сам он не осуществляет продажи. В результате ставится задача реализовать механизм динамической безопасности на уровне строк таким образом, чтобы менеджеры могли видеть продажи своих подчиненных, а генеральный директор имел доступ ко всем данным о продажах в компании. Для создания такого механизма нам понадобится построить иерархию подчиненности на основании схемы организационной структуры. В нашей таб­ли­це Employee есть для этого все необходимые данные: поля EmployeeKey и Parent­EmployeeKey помогут нам построить иерархию типа родитель–потомок, а поле EmailAddress послужит в качестве идентификатора имени субъекта-пользователя.

Распространенные подходы в организации безопасности на уровне строк    437

Сначала на основании полей EmployeeKey и  ParentEmployeeKey создадим вычисляемый столбец, в котором будут храниться иерархические пути элементов. Для этого воспользуемся следующим выражением DAX: EmployeePath = PATH(Employee[EmployeeKey]; Employee[ParentEmployeeKey])

Рис. 11.23    Механизм динамической безопасности автоматически включается при открытии отчета пользователем

Результат создания этого столбца можно видеть на рис. 11.24. Следующим шагом нам нужно идентифицировать значение EmployeeKey на основании имени пользователя. В этом нам поможет приведенное ниже выражение DAX: CALCULATETABLE( VALUES(Employee[EmployeeKey]) ; FILTER(Employee; Employee[EmailAddress] = USERPRINCIPALNAME()) ; FILTER(Employee; Employee[Status] = "Current") )

438    Безопасность на уровне строк ПРИМЕЧАНИЕ  В таб­ли­це Employee хранится вся историческая информация о  сотрудниках, а нам нужны лишь актуальные данные, в связи с чем мы наложили дополнительный фильтр на столбец Status, выбрав только текущие сведения.

Рис. 11.24    Вычисляемый столбец EmployeePath в таб­ли­це Employee

Для проверки этого выражения можно создать на его основе меру и проверить ее так же, как мы проверяли другие роли. На рис. 11.25 показан результат использования меры с этим выражением в карточке.

Рис. 11.25    Проверка выражения DAX в мере

Распространенные подходы в организации безопасности на уровне строк    439 ПРИМЕЧАНИЕ  Не забудьте удалить меру EmployeeKey. Мы создали ее только с целью проверки правильности применения механизма.

Теперь, когда мы извлекли нужное значение из столбца EmployeeKey, можно использовать его для поиска всех строк, в которых оно встречается в вычисляемом столбце EmployeePath. Для лучшего понимания идеи давайте внимательно посмотрим на наши данные. На рис.  11.26 показаны данные о продажах, включая ключ, имя и электронный адрес продавца, а также созданный столбец EmployeePath.

Рис. 11.26    Данные о продажах

На рис. 11.26 подсвечены менеджеры по продажам по имени Аллан (Allan), Эми (Amy) и Саид (Syed). Менеджеры по совместительству также являются и продавцами, так что у них есть и собственные продажи. Исходя из значений в столбце EmployeePath понятно, что менеджеры располагаются на третьем уровне подчинения, поскольку их ключ стоит третьим в иерархическом пути. Таким образом, нам бы хотелось, чтобы они видели продажи всех подчиненных продавцов, т.е. тех, у которых в иерархическом пути присутствует ключ данного менеджера. Нет необходимости говорить, что пользователь с ключом 277, находящийся на один уровень ниже генерального директора (ключ 112), должен иметь доступ ко всем продажам. Для реализации поставленной задачи нам придется анализировать все ключи, входящие в иерархические пути сотрудников. К счастью, в DAX есть специальная функция для поиска значений в  иерархических путях: PATHCONTAINS(, ). Функция PATHCONTAINS() возвращает True в  случае нахождения запрашиваемого значения в пути. Сами иерархические пути у нас хранятся в столбце EmployeePath. Сначала мы извлечем ключ текущего пользователя, после чего осуществим его поиск в иерархическом пути. Итоговое выражение DAX будет таким: VAR _key = CALCULATETABLE ( VALUES ( Employee[EmployeeKey] );

440    Безопасность на уровне строк FILTER ( Employee; Employee[EmailAddress] = USERPRINCIPALNAME()); FILTER ( Employee; Employee[Status] = "Current" ) ) RETURN PATHCONTAINS ( Employee[EmployeePath]; _key )

Осталось создать роль и использовать это выражение в качестве правила. На рис. 11.27 показана роль Sales Team с указанным правилом.

Рис. 11.27    Создание роли Sales Team с применением динамической безопасности на уровне строк

Проверим созданную роль для кого-нибудь из менеджеров. На рис. 11.28 показан результат проверки для менеджера по имени Аллан.

Рис. 11.28    Продажи менеджера и всех его подчиненных продавцов

Распространенные подходы в организации безопасности на уровне строк    441

Теперь можно публиковать этот отчет в службе. ПОМНИТЕ  Если вы являетесь администратором Po­wer BI, вам нужно назначить пользователям новую роль Sales Team. В противном случае попросите администратора сделать это.

Теперь при использовании отчета менеджеры должны видеть как свои продажи, так и  продажи своих подчиненных продавцов. На рис.  11.29 показано, что увидит Эми, когда откроет отчет.

Рис. 11.29    При открытии отчета в службе Po­wer BI в действие вступает роль Sales Team

Теперь посмотрим, в  каком виде отчет предстанет перед генеральным директором компании. Как мы помним, он должен видеть информацию обо всех продажах, что и подтверждается при взгляде на рис. 11.30.

Рис. 11.30    Генеральный директор видит все данные

442    Безопасность на уровне строк Хотя этот сценарий оказался немного сложнее предыдущего, нет предела совершенству. Вы, наверное, заметили, что в описанном случае все учетные данные пользователей, такие как EmailAddress, находились в таб­ли­це Employee. В  следующем разделе мы рассмотрим сценарий, в  котором информация об электронном адресе пользователей отсутствует в  нашей модели данных.

Получение учетных данных пользователей из стороннего источника Предположим, наши требования к  безопасности остались такими же, как в предыдущем примере, за исключением того, что в источнике данных информация об электронных адресах пользователей больше не хранится в таб­ ли­це Employee. В этом случае сценарий немного изменится, поскольку нам придется извлекать учетные данные пользователей из другого источника. Проблема же в том, что в этом источнике не обязательно будет присутствовать столбец EmployeeKey для соотнесения с учетными данными пользователя. В зависимости от поставщика данные могут очень сильно отличаться по содержанию. В нашем сценарии мы попросили системного администратора предоставить нам выгрузку с  информацией о  пользователях из Azure Active Directory. В результате мы получили файл в формате JSON, содержащий список имен субъектов-пользователей. Файл Chapter 11, Adventure Works, AAD UPNs.json прилагается к сопроводительным материалам книги. ПРИМЕЧАНИЕ  В  реальных проектах необходимо было бы позаботиться об автоматическом обновлении данных в файле JSON, чтобы они сохраняли свою актуальность. Сформированный файл JSON содержит конфиденциальные сведения, в связи с чем должен располагаться в  защищенном хранилище с  доступом для ограниченного списка сотрудников.

Для простоты мы будем использовать тот же файл Po­wer BI, что и в предыдущем сценарии. Просто будем игнорировать наличие в таб­ли­це Employee поля EmailAddress. Выполните следующие действия, чтобы решить поставленную задачу. 1. В Po­wer BI Desktop подключитесь к  файлу JSON, как показано на рис. 11.31. 2. Po­wer BI автоматически определит содержимое файла и развернет его в виде, показанном на рис. 11.32. 3. Переименуйте запрос в Users. 4. Удалите столбец @odata.context. 5. Переименуйте столбец value.givenName в  First Name, value.surname  – в Last Name, а value.userPrincipalName – в Email Address, как показано на рис. 11.33. Как видите, у нас нет поля EmployeeKey в таб­ли­це Users. Но мы можем получить это значение из таб­ли­цы Employee путем поиска на основе полей First Name и Last Name. Далее мы покажем, как это можно сделать.

Распространенные подходы в организации безопасности на уровне строк    443

6. Выполните объединение (Merge) таб­лиц Users и Employee по полям First Name и Last Name из таб­ли­цы Users и FirstName и LastName из таб­ли­цы Employee. Установите Тип соединения (Join Kind) в положение Левое внешнее (Left Outer), чтобы соединились все строки из первой таб­ли­ цы и совпадающие – из второй, как показано на рис. 11.34.

Рис. 11.31    Извлечение данных из файла JSON

Рис. 11.32    Открытие файла JSON в Po­wer BI

444    Безопасность на уровне строк

Рис. 11.33    Подготовка таб­ли­цы Users

Рис. 11.34    Объединение таб­лиц Users и Employee

7. Разверните структурированный столбец Employee, чтобы получить столбцы EmployeeKey и Status, как на рис. 11.35. ПРИМЕЧАНИЕ  Помните, что в таб­ли­це Employee хранится вся история по сотрудникам, так что потенциально у нас могут появляться дублирующиеся значения. В связи с этим мы сохранили столбец Status, что поможет нам отобрать только текущие (Current) значения.

Распространенные подходы в организации безопасности на уровне строк    445

Рис. 11.35    Разворачивание столбца Employee

8. Отфильтруйте столбец Status по значению Current, как показано на рис. 11.36.

Рис. 11.36    Фильтрация таб­ли­цы Employee для показа только текущих значений

9. Нажмите на кнопку Закрыть и применить (Close & Apply) для загрузки таб­ли­цы Users в модель данных, как на рис. 11.37.

Рис. 11.37    Применение изменений и загрузка таб­ли­цы Users в модель данных

10. Переключитесь на вкладку Модель.

446    Безопасность на уровне строк 11. Создайте новую связь между таб­ли­ца­ми Users и Employee, если Po­wer BI Desktop не сделал это автоматически, как показано на рис. 11.38.

Рис. 11.38    Создание связи между таб­ли­ца­ми Users и Employee

Как видите, между таб­ли­ца­ми Users и  Employee установилась связь типа «один к одному», что нам и нужно. Теперь можно создать новую роль по таб­ ли­це Employee, что мы и сделаем. 12. Создайте новую роль с именем Sales Team2, после чего создайте новое правило по таб­ли­це Employee с использованием следующего выражения DAX: VAR _key = CALCULATETABLE ( VALUES ( Users[EmployeeKey] ); FILTER ( Users; Users[Email Address] = USERPRINCIPALNAME()) ) RETURN PATHCONTAINS ( Employee[EmployeePath]; _key)

Результат показан на рис. 11.39. ПРИМЕЧАНИЕ  Поскольку мы уже отфильтровали таб­ли­цу Users, чтобы в ней отобра­ жались только текущие пользователи, нам нет необходимости добавлять функцию FILTER() в CALCULATETABLE().

Распространенные подходы в организации безопасности на уровне строк    447

Рис. 11.39    Создание роли и правила по таб­ли­це Employee

13. Осталось проверить работоспособность созданной роли с  помощью кнопки Просмотреть как (View as) на вкладке Моделирование, как показано на рис. 11.40.

Рис. 11.40    Проверка новой роли

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

448    Безопасность на уровне строк мы рассмотрели основные сценарии реализации механизма безопасности на уровне строк, все возможные случаи мы осветить просто не могли, так что оставляем их вам для самостоятельного изучения.

Заключение В этой главе мы научились реализовывать механизм безопасности на уровне строк в  Po­wer BI Desktop, а также управлять созданными ролями в  службе Po­wer BI и  Po­wer BI Report Server. Мы узнали, чем отличается статическая безопасность на уровне строк от динамической и как их реализовывать на практике для ограничения доступа пользователей к  данным. В  заключительной главе книги мы поговорим о  медленно меняющихся измерениях, безопас­ности на уровне объектов, потоках данных и составных моделях.

Глава

12

Дополнительные опции и возможности моделирования данных В предыдущей главе мы изучили много важных аспектов моделирования данных, применимых в разных сценариях. Сейчас же мы познакомимся с дополнительными возможностями, предоставляемыми платформой Po­wer BI, которые вы с успехом сможете использовать в реальных проектах. Это достаточно сложные темы, для того чтобы в одной главе охватить их целиком, так что мы сделаем лишь первые шаги, а остаток пути вы, при наличии желания, пройдете сами. Основные темы, которые мы затронем в главе:   медленно меняющиеся измерения;   безопасность на уровне объектов;   введение в потоки данных;   составные модели.

Медленно меняющиеся измерения Термин медленно меняющиеся измерения (slowly changing dimension – SCD) восходит к концепции хранения данных, предложенной потрясающим Ральфом Кимболом (Ralph Kimball), о котором подробнее можно узнать по адресу https://www.kimballgroup.com/about-kimball-group. Эта концепция связана с  переходом специфического набора данных из одного состояния в другое. Представьте, что у нас есть система управления персоналом, в  которой прописано, что Стивен Цзян (Stephen Jiang) является менеджером по продажам (sales manager), в  подчинении которого находится десяток торговых представителей (sales representative), как видно на рис. 12.1. Сегодня Стивен получил продвижение по службе и  был назначен замес­ тителем президента по продажам (Vice President of Sales), в результате чего количество подчиненных у него возросло с 10 до 17. Эти изменения отображены на рис. 12.2.

450    Дополнительные опции и возможности моделирования данных

Рис. 12.1    Менеджер по продажам и десять его торговых представителей

Рис. 12.2    Команда Стивена после повышения в должности

Еще одним примером может быть изменение адреса покупателя в системе учета продаж. Здесь ситуация такая же: сам покупатель остался прежним, изменился лишь его адрес. В зависимости от бизнес-требований мы можем поразному обрабатывать подобные ситуации с точки зрения хранения данных, что обусловливает наличие нескольких типов медленно меняющихся измерений. Тут необходимо понимать, что изменения происходят в источниках данных (в  нашем случае в  системе управления персоналом или в  системе учета продаж), являющихся транзакционными. Мы преобразуем и загружаем данные посредством инструментов ETL в хранилище данных, где и вступает в действие механизм отслеживания медленно меняющихся измерений. Этот механизм связан с тем, как изменения в источнике влияют на данные в хранилище. При этом речь идет об изменениях в источнике, которые происходят

Медленно меняющиеся измерения    451

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

Медленно меняющиеся измерения типа 0 (SCD 0) При реализации этого типа медленно меняющегося измерения мы игнорируем все произошедшие в нем изменения. Таким образом, при изменении адреса покупателя в  источнике данных (в  нашем случае в  системе управления персоналом) мы никак не меняем измерение в  хранилище. Иными словами, мы просто игнорируем все изменения в  источнике данных. Этот тип медленно меняющегося измерения также называется фиксированным (fixed dimension).

Медленно меняющиеся измерения типа 1 (SCD 1) В случае реализации медленно меняющихся измерений первого типа мы просто перезаписываем новые данные поверх старых. Примером может быть ситуация, когда нам не нужна информация о предыдущем адресе покупателя, а достаточно лишь актуальных данных.

Медленно меняющиеся измерения типа 2 (SCD 2) Этот тип медленно меняющихся измерений подразумевает наличие истории изменения данных в хранилище и применяется тогда, когда, например, нам необходимо располагать информацией о предыдущих адресах покупателей. Для реализации этого сценария мы при каждом изменении данных в транз­ акционном источнике вставляем строку с данными в хранилище. В результате мы получаем частично дублирующиеся данные в таб­ли­це хранилища, что не позволяет использовать в ней поле CustomerKey в качестве первичного ключа. В связи с этим нам необходимо добавить в таб­ли­цу новые столбцы:   столбец, гарантирующий уникальность данных в  измерении Customers. Это может быть обычный индекс с порядковыми номерами строк в обновленной таб­ли­це. Такой столбец называется суррогатным ключом (surrogate key). И хотя он помогает обеспечить уникальность строк в измерении, нам по-прежнему нужно поддерживать первичный ключ в источнике. При этом на стороне хранилища данных он в этом случае будет именоваться бизнес-ключом (business key), или альтернативным ключом (alternate key);   столбцы Start Date и End Date для представления диапазонов актуальности данных;   столбец, отображающий статус каждой строки данных. Второй тип медленно меняющихся измерений является наиболее распространенным.

452    Дополнительные опции и возможности моделирования данных Давайте вернемся к  нашему сценарию, в  котором Стивен Цзян получил повышение по службе и  стал заместителем президента по продажам. На рис. 12.3 показано содержимое соответствующей таб­ли­цы до этой счастливой для Стивена новости.

Рис. 12.3    Данные о сотрудниках до повышения Стивена

Здесь столбец EmployeeKey представляет собой суррогатный ключ измерения, а  столбец EmployeeBusinessKey  – бизнес-ключ (первичный ключ в таб­ли­це-источнике). В столбце Start Date указана дата, когда Стивен занял должность менеджера по продажам в  североамериканском регионе (North American Sales Manager), в  поле End Date – пустое значение (null), а  в  поле Status  – значение Current. Теперь посмотрим, как изменится содержимое таб­ли­цы в хранилище после повышения Стивена. Обновленная информация представлена на рис. 12.4.

Рис. 12.4    Данные о сотрудниках после повышения Стивена

Как видите, Стивен занял новую должность 13 октября 2021 года (13/10/2012), а днем ранее (12/10/2012) завершил пребывание на посту менеджера по продажам. Давайте посмотрим, как реализуется второй тип медленно меняющихся измерений посредством моделирования данных в Po­wer BI. Первый вопрос, который нужно задать, должен быть таким: можно ли реализовать второй тип медленно меняющегося измерения непосредственно в Po­wer BI Desktop, без хранилища данных? Для ответа на этот вопрос необходимо вспомнить о том, что при построении модели данных в Po­wer BI мы создаем семантический слой. Семантический слой по определению является представлением данных в  источнике (обычно в  виде хранилища данных), оптимизированным для целей аналитики и  построения отчетов. Семантический слой не может заменить хранилище данных и  не является его версией. Допустим, нам необходимо хранить историю изменения данных. В  этом случае нам либо понадобится хранилище данных, либо придется изыскивать способ поддержания исторических данных на стороне транзакционной базы данных по примеру темпоральных механизмов (temporal mechanism). Темпо-

Медленно меняющиеся измерения    453

ральный механизм – это средство, предлагаемое СУБД, включая SQL Server, позволяющее извлекать исторические сведения о  содержимом таб­лиц на любой момент в противовес хранению только актуальных данных. Подробно о темпоральных таб­ли­цах (temporal table) в SQL Server можно почитать по адресу https://docs.microsoft.com/ru-ru/sql/relational-databases/tables/temporaltables?view=sql-server-ver15. После загрузки данных в модель Po­wer BI Desktop в нашем распоряжении будут все текущие и исторические данные в таб­ли­цах измерений. Это нужно учитывать и очень аккуратно обращаться с такими данными. Например, на рис. 12.5 представлены данные о продажах по сотрудникам.

Рис. 12.5    Данные о продажах по сотрудникам без учета специфики медленно меняющихся измерений

На первый взгляд все нормально. На самом же деле это может быть так, а может быть и не так. Все зависит от того, что необходимо видеть в отчете. При создании этой таб­ли­цы мы не учитывали специфику медленно меняющихся измерений, в результате чего в нее попала информация о продажах нашего Стивена (EmployeeKey 272). Но соответствует ли это нашим требованиям? Хотим ли мы видеть все продажи сотрудников вне зависимости от статуса? Для лучшего понимания давайте добавим в предыдущую таб­ли­цу столбец Status. На рис. 12.6 показано, что получится. А что, если мы хотим видеть продажи по сотрудникам только на момент, когда у  них был статус Current? В  этом случае необходимо учитывать фактор медленно меняющегося измерения и фильтровать данные по Стивену. В  зависимости от требований мы можем либо фильтровать статус прямо в элементе визуализации, либо внести изменения в меру, добавив учет значений в столбцах Start Date, End Date и Status для фильтрации результатов. На рис. 12.7 показан простой вариант с отсеиванием результатов при помощи фильтра на уровне визуализации.

454    Дополнительные опции и возможности моделирования данных

Рис. 12.6    Данные о продажах и статусах по сотрудникам без учета специфики медленно меняющихся измерений

Рис. 12.7    Данные о продажах по сотрудникам с учетом специфики медленно меняющихся измерений

Безопасность на уровне объектов    455

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

Безопасность на уровне объектов В главе 11 мы говорили о том, как можно ограничить доступ пользователям к  данным при помощи механизма безопасности на уровне строк. В  этом разделе мы поговорим о безопасности на уровне объектов (object-level security – OLS) в Po­wer BI. Эта технология позволяет управлять доступом к объектам модели данных на основе ролей. Например, вы можете скрыть для конкретного пользователя целую таб­ли­цу или определенные столбцы. Таким образом, если пользователь применяет в работе инструмент Анализ в Excel (Analyse in Excel) для подключения к  наборам данных, он сможет видеть только те таб­ли­цы и столбцы, к которым у него есть доступ. ПРИМЕЧАНИЕ  Как уже было упомянуто, на момент написания книги механизм безопас­ности на уровне объектов находится на стадии публичного предварительного просмотра, но все может быстро измениться. Пока мы не можем пользоваться этим механизмом в Po­wer BI Desktop. Вместо этого мы должны воспользоваться инструментом Tabular Editor. Кроме того, при помощи механизмов безопасности RLS и  OLS нельзя управлять видимостью объектов для разработчика Po­wer BI Desktop. Это можно сделать только на стороне источника данных. Вне зависимости от использования любого из этих механизмов разработчик будет иметь полный доступ ко всем данным, предоставляемым источником. Важно понимать, что механизмы RLS и OLS предназначены не для настройки разрешений пользователям, а позволяют лишь ограничивать доступ к строкам в первом случае и к объектам – во втором.

Реализация безопасности на уровне объектов Давайте посмотрим, как механизм безопасности на уровне объектов работает на практике. Предположим, вам необходимо скрыть следующие объекты модели данных от указанных групп пользователей:   таб­ли­цу Internet Sales – от группы безопасности Internet Sales Denied;   столбец OrderQuantity в таб­ли­це Internet Sales – от группы OrderQty Denied. В описанном сценарии нам понадобятся две группы безопасности. Предположим, что они у вас уже созданы. Приведенные ниже шаги помогут реализовать безопасность на уровне объектов. 1. Откройте нужный отчет в Po­wer BI и нажмите на кнопку Управление ролями (Manage roles).

456    Дополнительные опции и возможности моделирования данных 2. Нажмите на кнопку Создать (Create) для добавления новой роли. 3. Введите в качестве имени новой роли Internet Sales Denied. 4. Снова нажмите на кнопку Создать (Create) и введите имя роли OrderQty Denied. 5. Нажмите на кнопку Сохранить (Save). Эти шаги показаны на рис. 12.8.

Рис. 12.8    Создание новых ролей безопасности

Теперь необходимо открыть Tabular Editor и продолжить работу там. 6. В Po­wer BI Desktop перейдите на вкладку Внешние инструменты (External Tools). 7. Если вы установили последнюю версию Tabular Editor, соответствующая иконка будет отображаться на вкладке. Нажмите на нее, как показано на рис. 12.9.

Рис. 12.9    Открытие Tabular Editor в качестве внешнего инструмента

Безопасность на уровне объектов    457 ПРИМЕЧАНИЕ  Убедитесь, что у вас установлена последняя версия Tabular Editor.

8. В открывшемся окне Tabular Editor раскройте папку Tables. 9. Выделите таб­ли­цу Internet Sales. 10. Раскройте пункт Object Level Security на панели Properties. 11. В выпадающем меню справа от роли Internet Sales Denied выберите None. Эти шаги отображены на рис. 12.10.

Рис. 12.10    Настройка безопасности на уровне объектов для таб­лиц в Tabular Editor

Итак, мы настроили безопасность для таб­ли­цы Internet Sales, так что никто из группы Internet Sales Denied не сможет ее видеть, словно ее не существует вовсе. Далее необходимо выполнить вторую часть задания в Tabular Editor. 12. Раскройте таб­ли­цу Internet Sales. 13. Щелкните по полю OrderQuantity. 14. Раскройте пункт Object Level Security на панели Properties. 15. В выпадающем меню справа от роли OrderQty Denied выберите None. 16. Нажмите на кнопку Save, чтобы сохранить изменения в модели. Эти действия показаны на рис. 12.11. Итак, мы настроили безопасность так, как требовалось. Теперь нужно все проверить.

458    Дополнительные опции и возможности моделирования данных

Рис. 12.11    Настройка безопасности на уровне объектов для столбца

Проверка ролей Процесс проверки ролей при настройке безопасности на уровне объектов не отличается от настройки безопасности на уровне строк. Выполните следующие шаги. 1. Нажмите на кнопку Просмотреть как (View as) на вкладке Моделирование. 2. Выберите роль Internet Sales Denied для проверки. 3. Нажмите на кнопку OK. Эти шаги показаны на рис. 12.12.

Рис. 12.12    Проверка роли Internet Sales Denied

Безопасность на уровне объектов    459

Результат проверки показан на рис. 12.13. Заметьте, что таб­ли­ца Internet Sales исчезла с панели Поля (Fields), как и все связанные с ней визуальные элементы.

Таблица Internet Sales исчезла

Рис. 12.13    Просмотр отчета в роли Internet Sales Denied

Роль OrderQty Denied можно проверить точно так же. На рис. 12.14 показан результат этой проверки.

Рис. 12.14    Проверка роли OrderQty Denied

460    Дополнительные опции и возможности моделирования данных Как видите, в этом случае перестали работать только визуальные элементы, связанные с полем OrderQuantity из таб­ли­цы Internet Sales. Что еще произошло:   поле OrderQuantity исчезло из таб­ли­цы Internet Sales;   мера Order Qty, связанная с полем OrderQuantity, также пропала.

Назначение участникам ролей в службе Power BI После реализации механизма безопасности на уровне объектов необходимо опубликовать отчет в службе Po­wer BI, после чего назначить пользователям или группам соответствующие им роли. Следующие действия позволят вам назначить пользователю роль в  службе Po­wer BI после публикации отчета в рабочей области. 1. Нажмите на кнопку с тремя точками справа от набора данных. 2. Выберите в контекстном меню пункт Безопасность (Security). 3. Выберите роль. 4. Введите имя пользователя или группы (в нашем случае группы). 5. Нажмите на кнопку Добавить (Add). Эти шаги показаны на рис. 12.15.

Рис. 12.15    Назначение участникам ролей в службе Po­wer BI

Проделайте те же действия для назначения группе безопасности OrderQty Denied роли OrderQty Denied. В  следующем разделе посмотрим, как можно проверить роли в службе, чтобы убедиться, что все работает нормально. 1. Нажмите на кнопку с тремя точками справа от набора данных. 2. Выберите в контекстном меню пункт Безопасность (Security). 3. Нажмите на кнопку с тремя точками справа от роли, которую хотите проверить.

Безопасность на уровне объектов    461

4. Выберите пункт Проверить в качестве роли (Test as role). Эти шаги показаны на рис. 12.16.

Рис. 12.16    Проверка ролей в службе Po­wer BI

На рис. 12.17 показан результат проверки.

Рис. 12.17    Проверка роли в службе Po­wer BI

В этом разделе мы познакомились с механизмом безопасности на уровне объектов в Po­wer BI. Далее познакомимся с потоками данных и их применением.

462    Дополнительные опции и возможности моделирования данных

Введение в потоки данных В ноябре 2018 года компания Microsoft анонсировала публичный предпросмотр потоков данных (dataflows), а через пять месяцев после этого – в апреле 2019-го – инструмент стал доступен широким массам. И если поначалу доступ к этой технологии был только у владельцев лицензии Premium, то сейчас ей можно воспользоваться в любом продукте семейства Po­wer Platform, а также она представлена в Po­wer BI для лицензии Pro. После этого краткого экскурса в историю давайте узнаем, что из себя представляют потоки данных. Если говорить коротко, потоки данных являются облачной версией Po­wer Query, также известной как Po­wer Query Online. С помощью потоков данных у вас появляется возможность воспользоваться всей мощью Po­wer Query при подготовке данных внутри службы Po­wer BI. ПРИМЕЧАНИЕ  Потоки данных не привязаны напрямую к Po­wer BI. Другие инструменты и службы также имеют доступ к данным, хранящимся в потоках.

Подготовленные данные хранятся в виде файлов и папок, получивших название Общая модель данных (Common Data Model – CDM), в хранилище Azure Data Lake Storage второго поколения (ADLS Gen 2), и  управляются службой Po­wer BI. Если организация уже располагает таким хранилищем, мы можем предоставлять доступ к  подготовленным данным различным инструментам и службам. Более того, с помощью потоков данных можно организовать доступ к  данным и  для пользователей в  компании. Потоки данных представляют собой самостоятельный инструмент ETL в рамках платформы Po­ wer BI, делающий процесс подготовки данных менее зависимым от отделов информационных технологий. С  помощью потоков данных пользователи могут получать информацию в  виде, готовом к  обработке. Это позволяет сократить расходы на разработку и повысить возможности для повторного использования данных. Основное отличие между подготовкой данных в Po­wer Query из Po­wer BI Desktop и применением потоков данных состоит в том, что при использовании Po­wer BI Desktop результаты преобразований будут доступны только в модели данных. В то же время после публикации модели в службе Po­wer BI сущности будут доступны в опубликованном наборе данных. Кто-то может подумать, что мы по-прежнему можем получить доступ к таблицам в наборе данных из других наборов при использовании составной модели. Это возможно, но не совсем правильно будет создавать составную модель только ради получения подготовленных данных. О составных моделях мы подробно поговорим далее в этой главе.

Сценарии для использования потоков данных Описание потоков данных как самостоятельного, централизованного, облачного ETL-инструмента подготовки данных звучит очень вдохновляюще – настолько, что хочется забросить подальше Po­wer Query в Po­wer BI Desktop

Введение в потоки данных    463

и перевести все процессы подготовки информации на потоки данных. Это не лучшая идея. Ниже мы перечислим сценарии, в которых может быть уместно использовать потоки данных:   в вашей организации нет своего хранилища данных. Все отчеты Po­wer BI извлекают данные напрямую из источника, что негативно сказывается на производительности. Таким образом, необходимо создать хранилище. В данном случае можно прибегнуть к обычной архитектуре хранилища с разделением на стадии подготовки и преобразования данных, а также построением схемы «звезда»;   вы хотите делиться процедурой преобразования данных в рамках организации. В результате другие наборы данных и отчеты в Po­wer BI (и в Po­wer Platform в целом) смогут повторно использовать подготовленные данные;   в организации есть хранилище ADLS Gen 2, и вам нужно подключить другие службы Azure к подготовленным данным;   вам требуется создать единый источник достоверных данных (single source of truth  – SSOT) для бизнес-аналитиков. Для этого вы можете создать поток данных, к которому будут подключаться аналитики, вместо того чтобы тянуть данные из транзакционных систем или разрозненных файлов;   вам нужно выполнить процесс подготовки данных из объемного источника, и  у  вас есть в  наличии лицензия Po­wer BI Premium. В  этом случае использование потоков данных позволит повысить гибкость процедуры и ее эффективность;   вы хотите использовать подготовленные данные совместно в разных продуктах семейства Po­wer Platform. При создании потока данных вы можете обеспечить доступ к нему из различных инструментов Po­wer Platform, включая Po­wer Apps, Po­wer Automate, Po­wer Virtual Agent и Dynamics 365;   вам нужен самостоятельный инструмент подготовки данных, не сильно завязанный на работу отдела ИТ. По сути, для создания потока данных ничего, кроме Po­wer Query, знать и не нужно.

Терминология потоков данных Как мы уже упоминали, технология потоков данных также называется Po­ wer Query Online. Отсюда и общность в терминологии. Ниже мы приведем некоторые термины, применимые в потоках данных, которые также могут присутствовать и в Po­wer Query:   поля (fields): в потоках данных означают то же, что и в Po­wer Query;   сущности (entity): сущности состоят из набора полей или столбцов, как и в Po­wer Query. Иногда сущности называют таб­ли­ца­ми. В то же время между сущностями в потоках данных и запросами в Po­wer Query есть разница. В Po­wer Query, открытом из Po­wer BI Desktop, все сущности называются запросами, тогда как в  потоках данных есть несколько следующих типов сущностей:

464    Дополнительные опции и возможности моделирования данных •• стандартная сущность (normal entity): аналогична запросу в Po­wer Query из Po­wer BI Desktop. Для стандартной сущности используется такая иконка: ; •• связанная сущность (linked entity): образуется путем создания ссылки на имеющуюся сущность, определенную в  другом потоке данных. При создании связанной сущности данные не будут загружаться в новый поток данных; вместо этого в новом потоке будет присутствовать только ссылка на источник. По этой причине такие сущности всегда доступны только для чтения. В результате вы не сможете добавлять никаких новых шагов по преобразованию данных. Связанная сущность помечается иконкой ; •• вычисляемая сущность (computed entity): вычисляемые сущности образуются путем создания ссылки на другие сущности при помощи новых шагов преобразования данных. В этом случае данные обрабатываются в потоке-источнике. После этого данные трансформируются в  новой сущности. Преобразованные данные затем сохраняются в новом потоке. Для вычисляемых сущностей используется следующая иконка: . ПРИМЕЧАНИЕ  Создание связанных и  вычисляемых сущностей в  данный момент доступно только при наличии лицензии Po­wer BI Premium, тогда как сущности-источники могут располагаться в обычной рабочей области с лицензией Po­wer BI Pro. Рабочая область, содержащая связанные сущности, должна быть модернизированной (не классической рабочей областью, связанной с группами Office 365). Допустимо ссылаться на сущности из нескольких потоков данных, располагающихся в рабочих областях нового типа.

Создание потока данных Для создания потока данных необходимо подключиться к  службе Po­wer BI в браузере и выполнить следующие шаги. 1. Выберите нужную вам рабочую область. 2. Нажмите на кнопку Создать (New). 3. Выберите пункт Поток данных (Dataflow), как показано на рис. 12.18. На этом этапе в  зависимости от типа рабочей области у  вас может быть следующий выбор:   вариант A: в классической рабочей области вы увидите выбор, показанный на рис. 12.19.   вариант B: в классической рабочей области с наличием лицензии Premium вы увидите выбор, показанный на рис. 12.20.   вариант C: в новой рабочей области у вас будет выбор, отображенный на рис. 12.21.

Введение в потоки данных    465

Рис. 12.18    Создание потока данных в службе Po­wer BI

Рис. 12.19    Создание потока данных в классической рабочей области

466    Дополнительные опции и возможности моделирования данных

Рис. 12.20    Создание потока данных в классической рабочей области с лицензией Premium

Рис. 12.21    Создание потока данных в новой рабочей области

Введение в потоки данных    467

Как видно на рисунках выше, полный набор альтернатив будет предложен вам только при работе в новой рабочей области. При этом если у вас нет в наличии лицензии Premium, вы сможете создавать связанные сущности, но не сможете их обновлять. В следующих разделах мы посмотрим, как можно создавать стандартные и связанные сущности, а также импортировать модель. Мы опустим пункт Прикрепление папки Common Data Model (Attach a Common Data Model folder), поскольку на момент написания книги эта опция не была реализована в полном объеме.

Создание сущностей Итак, мы выбрали нужную рабочую область и приступили к созданию сущностей в потоке данных. Выполните следующие действия. 1. Чтобы создать сущность, в предложенном перечне остановите выбор на пункте Определение новых таб­лиц (Define new entities), как показано на рис. 12.22.

Рис. 12.22    Определение новых сущностей в потоке данных

2. Выберите нужный коннектор из списка, показанного на рис. 12.23.

468    Дополнительные опции и возможности моделирования данных

Рис. 12.23    Выбор коннектора

3. Заполните поля в области Параметры подключения (Connection settings). 4. Нажмите на кнопку Далее (Next), как показано на рис. 12.24.

Рис. 12.24    Заполнение полей подключения

5. Отметьте нужные сущности в  окне Выбрать данные (Choose data). Вы можете увидеть другое окно в зависимости от выбора коннектора на предыдущем шаге. Мы использовали коннектор OData для доступа к данным Northwind, которые уже применяли ранее.

Введение в потоки данных    469

6. Нажмите на кнопку Преобразование данных (Transform data), как показано на рис. 12.25.

Рис. 12.25    Выбор данных при создании потока

Откроется окно Po­wer Query Online с  редактированием запросов, сильно напоминающее редактор Po­wer Query в  Po­wer BI Desktop. Здесь важно обратить внимание на раздел Предупреждения (Warnings). Как видно на рис. 12.26, при возникновении проблем с загрузкой данных из определенных столбцов в этом разделе будут появляться важные сообщения. При нажатии на них вы увидите более подробную информацию, что показано на рис. 12.26. Как видите, мы можем щелкнуть по сообщению, чтобы предпринять какие-то действия при необходимости. После создания всех нужных шагов преобразования данных можно сохранить поток данных, нажав на кнопку Сохранить и закрыть (Save & close). Осталось дать потоку данных имя и  сохранить его, как показано на рис. 12.27.

470    Дополнительные опции и возможности моделирования данных

Щелкните по предупреждению

Щелкните здесь, чтобы открыть предупреждения

Рис. 12.26    Предупреждение после получения данных из источника

Рис. 12.27    Сохранение потока данных

В отличие от редактора Po­wer Query в  Po­wer BI Desktop, загружающего данные после нажатия на кнопку применения изменений, поток не будет автоматически загружать данные из источника. Вместо этого вам будет показано сообщение о необходимости обновить данные или задать расписание обновлений, как на рис. 12.28.

Введение в потоки данных    471

Рис. 12.28    Опции обновления данных после создания потока

Можно актуализировать данные в таб­ли­цах, нажав на кнопку Обновить (Refresh now) или установив расписание обновлений.

Создание связанных сущностей из других потоков данных Можно создать связанные сущности из других потоков данных с созданием потока, а  можно добавить их к  существующему потоку. Выполните следующие действия, чтобы добавить связанные сущности с  созданием нового потока. 1. После открытия нужной рабочей области и нажатия на кнопку создания потока данных выберите пункт Добавить связанные таб­ли­цы (Add linked entities), как показано на рис. 12.29. 2. Заполните учетные данные подключения. ПРИМЕЧАНИЕ  Если вы загружаете данные из локального источника, вам необходимо установить локальный шлюз данных (On-premises Data Gateway). Эта тема выходит за рамки книги, но я советую вам ознакомиться со следующей документацией: • документация от Microsoft: https://docs.microsoft.com/ru-ru/Po­wer-bi/connect-data/service-gateway-onprem?WT.mc_id=5003466; • информация на сайте biinsight.com: http://www.biinsight.com/definitive-guide-toimplement-on-premises-data-gateway-enterprise-mode-in-organisations.

472    Дополнительные опции и возможности моделирования данных

Рис. 12.29    Добавление сущностей с созданием нового потока

3. Нажмите на кнопку Далее (Next). Эти шаги показаны на рис. 12.30.

Рис. 12.30    Настройки подключения для создания связанных сущностей

4. В открывшемся окне Выбрать данные (Choose data) раскройте пункт с рабочей областью.

Введение в потоки данных    473

5. Раскройте нужный поток данных. 6. Выберите таб­ли­цы. 7. Нажмите на кнопку Преобразование данных (Transform data), как показано на рис. 12.31.

Рис. 12.31    Выбор таб­лиц из другого потока данных для образования связки

8. Нажмите на кнопку Сохранить и закрыть (Save & close), как показано на рис. 12.32.

Рис. 12.32    Сохранение изменений для выбранных сущностей

474    Дополнительные опции и возможности моделирования данных 9. Введите имя для нового потока данных и нажмите на кнопку Сохранить (Save), как на рис. 12.33.

Рис. 12.33    Сохранение связанных сущностей в виде нового потока данных

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

Создание вычисляемых сущностей В этом разделе мы создадим вычисляемые сущности. Зачастую вычисляемые сущности создаются в  существующем потоке данных путем ссылки на другие сущности. Следующие действия помогут вам в создании вычисляемых сущностей после перехода к  нужной рабочей области и  открытия потока данных. 1. Нажмите на кнопку Изменить таб­ли­цы (Edit entities), как показано на рис. 12.34.

Рис. 12.34    Редактирование сущностей в потоке данных

Введение в потоки данных    475

2. Щелкните правой кнопкой мыши по сущности на панели Запросы (Queries). 3. Выберите пункт Ссылка (Reference), как показано на рис. 12.35.

Рис. 12.35    Создание вычисляемой сущности

В результате будет создана вычисляемая сущность, как видно на рис. 12.36.

Рис. 12.36    Вычисляемая сущность

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

Импорт и экспорт потоков данных Потоки данных можно импортировать и экспортировать. В этом разделе мы научимся экспортировать поток данных, а затем импортировать экспортированный ранее поток.

Экспорт потоков данных Откройте нужную рабочую область и выполните следующие действия. 1. Нажмите на кнопку с тремя точками справа от потока данных. 2. В открывшемся меню выберите пункт Экспорт JSON (Export.json). 3. По готовности файла будет показано сообщение. 4. В зависимости от вашего браузера файл JSON будет так или иначе загружен на ваш компьютер. Эти шаги показаны на рис. 12.37.

Рис. 12.37    Экспорт определений потока данных в файл JSON

Импорт потоков данных Импортировать потоки данных проще простого. Выполните описанные ниже действия после открытия нужной рабочей области. 1. Нажмите на кнопку Создать (New). 2. Выберите пункт Поток данных (Dataflow), как показано на рис. 12.38.

Введение в потоки данных    477

Рис. 12.38    Создание нового потока данных

3. Нажмите на кнопку Импортировать модель (Import model). 4. Выберите загруженный ранее файл JSON. 5. Нажмите на кнопку Открыть (Open), как показано на рис. 12.39.

Рис. 12.39    Импорт потока данных

478    Дополнительные опции и возможности моделирования данных Вернувшись на страницу рабочей области, вы увидите импортированный поток данных. Заметим, что на данный момент вы импортировали лишь определение потока данных. Чтобы загрузить сами данные, необходимо выполнить обновление.

Составные модели В главе 4 мы обсуждали различные режимы хранения наборов данных. Давайте быстро вспомним, какие режимы существуют:   Импорт: данные физически загружаются в  модель Po­wer BI и  кешируются в памяти. При использовании этого режима все таб­ли­цы также используют режим хранения Импорт;   DirectQuery: в  этом случае модель данных создается в  Po­wer BI, но данные в памяти НЕ кешируются. При использовании этого режима все таб­ли­цы будут применять режим хранения DirectQuery;   Подключение в реальном времени (Connect Live): особая разновидность режима DirectQuery с  подключением к  семантической модели, а не к реляционной базе данных (хранилищу данных). В этом режиме модель данных хранится отдельно, и вы не можете вносить в нее изменения. Вместо этого вы просто извлекаете готовые данные из модели;   Составной (Composite  – Mixed): при таком режиме хранения часть данных из набора кешируется в памяти, а другая остается в источнике. Режимы хранения для таб­лиц в  наборе могут быть как Импорт, так и DirectQuery или Двойной. О последнем режиме хранения мы и  поговорим в  этом разделе. Раньше составные модели (composite model) поддерживали только реляционные базы данных в  режиме DirectQuery. Это означало, что SQL Server Analysis Services (SSAS), табличные модели SSAS, Azure Analysis Services (AAS) и наборы данных Po­wer BI были автоматически исключены из списка источников. В декабре 2020 года Microsoft выпустила очередную версию Po­wer BI Desktop, в которой представила новое поколение составных моделей. В этом поколении, помимо традиционной поддержки режима DirectQuery при подключении к реляционным базам данных вроде SQL Server, появилась поддержка режима DirectQuery при подключении к экземплярам AAS и наборам данных Po­wer BI. ПРИМЕЧАНИЕ  На момент написания книги поддержка локальных экземпляров таб­личных моделей SSAS реализована не была.

Это обновление существенно повлияло на способ взаимодействия с данными, особенно в плане аналитики. С помощью составных моделей вы можете подключаться к отдельным семантическим слоям из одной модели данных. Также допустимо импортировать данные из других источников, таких как SQL Server или Excel, и создавать самостоятельные семантические слои уровня предприятия в Po­wer BI.

Составные модели    479

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

Построение цепочек Построение цепочек (chaining)  – это один из терминов, получивший распространение с появлением новой версии составных моделей. Когда отчет или набор данных Po­wer BI основывается на другой семантической модели, хранящейся в AAS или наборах данных Po­wer BI, мы говорим об образовании цепочки (chain). Иными словами, речь идет о зависимостях между семантическими слоями, используемыми в составных моделях. Таким образом, при создании набора данных поверх других наборов данных (или моделей AAS) он становится зависимым от других наборов.

Длина цепочки Под длиной цепочки (chain’s length) подразумевается количество семантических слоев, от которых зависит текущий набор данных. Давайте закрепим полученные знания на практике. Предположим, у вас есть семантическая модель, хранящаяся в наборе данных AAS, которая по-прежнему находится в разработке. У разработчиков AAS полно работы и ворох задач, которые необходимо реализовать. В то же время руководству срочно требуется отчет, в  котором необходимо разбить цены (Unit Price) в таб­ли­це Internet Sales на группы следующим образом:   Low: когда цена ниже $100;   Medium: когда цена находится в диапазоне от $101 до $1000;   High: цена лежит между $1001 и $3000;   Very high: цена превышает $3001. Давайте взглянем на этот сценарий внимательнее. Во-первых, у нас есть семантическая модель в AAS, но разработчики слишком заняты рутинными задачами, чтобы оперативно реагировать на наши запросы. У нас могут хоть каждый день возникать все новые требования к отчетам, но разработчики не могут все бросить и начать удовлетворять наши просьбы. Однако, будучи специалистом в области Po­wer BI, вы можете и сами справиться со своими насущными проблемами. Далее мы покажем, как решить поставленную задачу в Po­wer BI Desktop. 1. При подключении к AAS из Po­wer BI Desktop установите переключатель в положение Подключение в реальном времени (Connect Live), как показано на рис. 12.40. 2. Переключитесь на вкладку Модель, чтобы увидеть модель данных AAS, как на рис. 12.41.

480    Дополнительные опции и возможности моделирования данных

Рис. 12.40    Подключение к AAS

Рис. 12.41    Текущая модель данных AAS

3. Нажмите на кнопку Преобразование данных (Transform data) на вкладке Главная (Home), как показано на рис. 12.42. В результате режим подключения Connect Live изменится на DirectQuery.

Составные модели    481

Рис. 12.42    Изменение режима подключения с Connect Live на DirectQuery

4. Нажмите на кнопку добавления локальной модели, как на рис. 12.43.

Рис. 12.43    Подтверждение добавления локальной модели

5. После этого откроется пустое окно редактора Po­wer Query. Закройте его, как показано на рис. 12.44.

Рис. 12.44    Закрытие пустого окна редактора Po­wer Query

6. Снова перейдите на вкладку Модель, чтобы увидеть изменения (цвет таб­лиц поменялся с черного на синий, и иконка для таб­лиц также изменилась). Эти изменения можно видеть на рис. 12.45. 7. Переключитесь на вкладку Отчет. 8. Щелкните правой кнопкой мыши по таб­ли­це Internet Sales и выберите пункт Создать столбец (New column), как показано на рис. 12.46.

482    Дополнительные опции и возможности моделирования данных

Рис. 12.45    Вид модели данных после изменения режима подключения на DirectQuery

Рис. 12.46    Создание столбца в режиме подключения DirectQuery в модели AAS

9. Используйте следующее выражение DAX для создания настраиваемого столбца:

Составные модели    483 Unit Price Range Band = SWITCH( TRUE() ; 'Internet Sales'[Unit Price] = 101; 'Internet Sales'[Unit Price] = 1001; 'Internet Sales'[Unit Price]