Сегодня BI-аналитика немыслима без ETL. Просто физических джоинов уже не хватает — чаще нужны логические модели данных. Они позволяют создавать сложные структуры без необходимости вручную писать запросы. Tableau, как self-service инструмент, дал такую возможность, представив в 2020-м релейшены (relationships), которые сделали модели данных более гибкими и производительными. А совсем недавно появились мультифакторные релейшены (multi-fact relationships), о которых и поговорим.
Мультифакторные релейшены позволяют работать с несколькими фактовыми таблицами из разных систем, даже если это таблицы с разной гранулярностью.
Именно с такой задачей мы недавно столкнулись при анализе ассортимента торговой сети.
Посмотрим на структуру данных:
Продажи находятся в таблице Orders.
Остатки — в таблице Inventory.
Категории и описания товаров — в таблице Products.
Названия торговых точек — в таблице Stores.
Бизнес-задача: выявить неликвидные товары в разных категориях.
Для этого нужно было узнать, какие товары не продаются на протяжении определенного периода и при этом хранятся в значительных количествах на складах .
Склад здесь — это конкретная торговая точка. В отчете надо было представить продажи и остатки товаров в разрезе категорий. Важно включить сравнение показателей с предыдущим периодом, чтобы отследить динамику. Также на дашборде должен быть фильтр по названию торговой точки для более точного анализа.
На первый взгляд, задача простая. Однако чтобы получить точные результаты и высокую производительность нужно тщательно проработать и правильно настроить модель данных в Tableau. Посмотрите, как мы решали эту задачу раньше, и как можем решить ее сейчас.
Разработчики обычно используют 3 основных подхода:
Работа с релейшенами на логическом уровне.
Сочетание джойнов на физическом уровне с релейшенами на логическом уровне.
Внесение доработок на уровне базы данных.
Логические и физические уровни модели данных в Tableau. База
Модель данных Tableau может быть построена на двух различных уровнях: логическом и физическом. Разница между ними в том, как связаны таблицы.
При объединении физических таблиц формируется один SQL-запрос и возвращается одна итоговая результирующая таблица. При этом в Tableau нам не нужно писать сам запрос, только «перетащить» таблицу в модель данных.
Логические таблицы соединяются при помощи релейшенов. Релейшены функционируют как джойны, но генерируют SQL-запросы динамически для каждой визуализации и задействуют только ту часть модели, которая содержит необходимые данные. Это дает большую гибкость по сравнению с соединениями на физическом уровне. Кроме того, анализируя поля на визуализации, Tableau сам выбирает, какой тип джойна использовать.
1. Работа с релейшенами на логическом уровне
Самый простой вариант — создание модели типа «звезда» при помощи релейшенов. Присоединим к фактовой таблице Orders фактовую таблицу Inventory и справочник Products.
Сначала посмотрим на исходные данные.
Теперь посмотрим, как при такой связи Tableau выводит данные, и подходит ли это для нашей бизнес-задачи.
Поскольку товар №7 не продавался, строки с ним нет в таблице заказов. Довольно типичная ситуация — не по всем товарам из ассортимента должны быть продажи. Т.е. таблицу Заказов нельзя использовать как основную в модели, ведь она не отражает весь перечень продуктов. И если связи в модели будут проходить через нее, Tableau просто не увидит данные по отсутствующему товару в связанной таблице (Inventory) и не выведет их.
Все товары есть в таблице Inventory. Но ее мы тоже не можем использовать как главную, потому что тогда в слепой зоне у нас окажется, например, товар №6. По нему были продажи, но его нет в наличии. Соответственно, сделав главной таблицей Inventory, аналогично получим некорректный результат.
Если бы у нас была только одна справочная таблица, решение проблемы лежало бы на поверхности — сделать главной таблицей справочник Products.
Поскольку таблица Products самая наполненная, при выводе названий товаров из нее корректно подтянутся меры из обеих фактовых таблиц.
Но как быть, если у нас несколько справочных таблиц, которые относятся как к таблице Orders, так и к таблице Inventory?
2. Сочетание джойнов на физическом уровне с релейшенами на логическом уровне
В качестве решения можно объединить некоторые таблицы на физическом уровне, например, Orders и Inventory, а затем связать их с Products и Stores.
Однако создание прямой взаимосвязи между таблицами данных о продажах и остатках может привести к ряду потенциальных проблем, поскольку таблицы содержат разные уровни детализации.
Потенциальная проблема 1: замножение данных
Таблица Orders содержит данные на уровне транзакции (максимальная детализация — Order_ID). Остатки же агрегированы за день для каждого продукта и магазина (Product_ID, Store_ID, Date). Прямое их сопоставление, например, с помощью Product_ID, Store_ID и даты, может привести к замножению данных, когда для каждого заказа дублируется количество товаров на остатке.
Потенциальная проблема 2: конфликт фильтров
Фильтрация на дашборде влияет на обе таблицы одновременно. Однако фильтры, применяемые к одной таблице, могут не иметь смысла для другой (например, фильтрация по Order_date или Order_ID неприменима к остаткам).
Потенциальная проблема 3: потеря производительности
Если в модели таблицы, содержащие миллионы строк, связаны напрямую, это может существенно повлиять на скорость отработки дашборда. Такая модель требует бОльших ресурсов и значительно снижает скорость обработки запросов, особенно без индексации или предварительной агрегации данных на стороне базы данных. Как результат — низкопроизводительные дашборды и недовольство пользователей.
В качестве альтернативы мы могли бы объединить справочники Products и Stores, чтобы создать единую таблицу измерений, а затем связать ее с фактовыми таблицами Orders и Inventory.
Для того чтобы исключить потерю данных, нужно выполнить full outer join по связке калькулируемых полей 1=1, то есть фактически cross join.
Вполне рабочий вариант, если у вас два небольших справочника. Но что если справочников несколько и в каждом содержит тысячи строк? Очень вероятно, что возникнут проблемы с производительностью.
3 Внесение доработок на уровне базы данных
Этот подход обеспечивает более высокую производительность благодаря агрегации данных и материализации вычислений. Однако он ограничивает self-service и возвращает нас в предыдущее поколение BI, когда аналитики сначала создают на стороне СУБД представление и только потом приступают к собственно аналитике.
Подводя итог, что можно сказать о каждом варианте:
1. При использовании релейшенов возможна потеря данных.
2. В случае сочетания джойнов и релейшенов появляются потенциальные проблемы: замножение данных, конфликт фильтров и потеря в производительности.
3. Внесение доработок на уровне БД отдаляет нас от self-service.
Новое решение: мультифакторные релейшены
Еще недавно мы не могли создать в Tableau модель данных с несколькими фактовыми таблицами. Версия Tableau 24.2 представила более эффективное решение для таких случаев — multi-fact relationships.
Они дают возможность подключать несколько фактовых (базовых) таблиц к общей модели данных через релейшены. Это позволяет обрабатывать данные с разной гранулярностью и объединять несколько базовых таблиц с несколькими справочниками.
Раньше модель можно было строить только от одной базовой таблицы, и если какие-то таблицы были с ней соединены, они уже не могли участвовать в других соединениях.
На примере у нас две базовые таблицы, Orders и Inventory, которые находятся слева в модели данных. К ним релейшены присоединяются справочные таблицы Products и Stores. Эти таблицы являются пересекающимися, поскольку содержат общие поля для обеих базовых таблиц.
При помощи мультифакторных релейшенов мы наконец получаем желаемый результат:
Еще одна отличная новость: не все базовые таблицы должны быть связаны со всеми таблицами измерений. Можно добавить справочник покупателей Customers, который будет связан только с таблицей Orders. Кроме того, пересекающиеся таблицы могут быть связаны с последующими таблицами. Например, к таблице Customers можно добавить связь с таблицей Regions.
Сравнение производительности
Посмотрим на производительность двух решений.
Первая модель данных использует сочетание джойнов на физическом уровне с релейшенами на логическом уровне (подробно рассмотрели выше), а вторая модель — мультифакторные релейшены.
Сравнивать производительность будем на примере следующей визуализации: данные о продажах и остатках за выбранный день в сравнении с предыдущим днем (таблицы Sales и Inventory, соответственно), разбитые по категориям товаров из (таблица Products), а также отфильтрованные по названию торговой точки (таблица Stores).
С каким объемом данных работаем? Таблицы Sales и Inventory содержат порядка 30 тыс. строк каждая, таблица Products содержит 1 850 строк, а таблица Stores всего 10 строк.
Чтобы проанализировать, как различается обработка этих моделей данных со стороны Tableau, используем Performance Recording.
Загрузка визуализации, построенной на модели, использующей сочетание джойнов и релейшенов, заняла у Tableau 0.35 секунды.
Загрузка визуализации, использующей мультифакторную модель заняла у Tableau в два раза меньше времени — 0.18 секунды.
Через Executing Query видим, как Tableau генерирует запросы к источнику данных. И видим, что негативно влияет на производительность дашборда.
Запрос, сгенерированной на модели джойнов и релейшенов:
И запрос, сгенерированный на мультифакторной модели:
Второй запрос заметно меньше первого, но давайте рассмотрим узкие места первого запроса более детально.
В первом запросе данные из таблицы Inventory запрашиваются и обрабатываются дважды: один раз для вычисления метрик и еще раз для объединения с дополнительными таблицами. Во втором запросе агрегация и объединение выполняются в рамках одного подзапроса, что упрощает обработку данных.
Первый запросе содержит избыточный cross join, создающий декартово произведение таблиц Products и Stores. Каждая строка из таблицы Products соединяется с каждой строкой из таблицы Stores (1 850*10=18 500 строк). Во втором запросе cross join отсутствует, что делает его более эффективным.
Заметим, что первый запрос был сформирован для вывода всего двух метрик на визуализации: остатков за текущий и за предыдущий период. Параллельно был сформирован аналогичный запрос для отображения продаж. Поскольку количество таких запросов пропорционально числу визуализаций на дашборде, использующих поля из справочных таблиц, это может еще больше замедлить дашборд. В каждом запросе Tableau будет обрабатывать бОльший объем данных, чем если бы обращался к каждой из справочных таблиц по отдельности.
Использование мультифакторной модели позволило ускорить дашборд в 2 раза!
Мультифакторные релейшены в Tableau 24.2 стали настоящим прорывом для работы с моделями данных, содержащими несколько фактовых таблиц.
Ранее разработчики сталкивались с ограничениями: потерей данных, замножением информации или снижением производительности. С мультифакторными релейшенами в Tableau 24.2 стало возможно:
подключать несколько фактовых таблиц к общим справочникам;
корректно обрабатывать данные из фактовых таблиц с разной детализацией;
значительно ускорять обработку запросов и визуализацию.
Сравнение производительности показало, что новая модель позволяет вдвое сократить время загрузки дашбордов и оптимизировать запросы к данным. Теперь аналитики могут создавать гибкие, сложные и производительные модели, не теряя преимущества self-service BI.
Подробнее про то, как работает мультифакторная модель, ее плюсах и минусах, смотрите наше техревью.
Комментарии (5)
Ivan22
20.12.2024 15:49и все-таки для взрослого решения, переиспользуемого в разных отделах нашего огромного энтерпрайза, необходимо минимизоровать все расчеты и джоины на уровне репортинга и делать все расчеты в витрине в DWH
shadowjack
Так релейшены (relations), или релейшоншипы (relationships)? Вы уж определитесь. Между тем, у обоих слов есть вполне устоявшийся в русскоязычной технической литературе перевод:
radachynskaja Автор
Здравствуйте! Имеются в виду relationships, просто среди разработчиков их для упрощения зовут релейшенами.
shadowjack
А давайте вы будете для написания технических публикаций использовать правильную терминологию?
А что и как там вы и ваши малограмотные коллеги зовут для упрощения -- это неважно.
mentin
Да, с терминологией плохо. Вот мне никак не понять почему мультифакторные релейшены но фактовые таблицы. Хотя вроде про одни и те же факты (спасибо хотя бы за английские названия, без них было бы вообще непонятно). Откуда взялись факторы? Хотя бы в пределах одной статьи можно бы быть последовательным, если фактовые таблицы, то мультифактные релейшены.
Хотя я бы предпочел, скажем, таблицы фактов и связи с множественными фактами.