В сводных таблицах есть два типа данных: измерения (dimensions) и показатели (или меры, measures). Измерения представлены в формате системы координат. Когда я слышу слово «измерения», я представляю себе три оси координат, выходящие из одной точки перпендикулярно по отношению друг другу как нас учили на уроках геометрии. Измерений (осей) может быть гораздо больше трех. Их можно будет использовать в виде столбцов, строк или фильтров сводной таблицы, но их нельзя помещать в ячейки. Примеры измерений:
Дата и время.
Тип клиента.
Статус клиента.
Показатели это уже статистики, которые будут рассчитываться в сводной таблице, когда вы будете «вращать» или менять измерения. Они, как правило, агрегатные: суммы, средние, количество уникальных значений (distinct count), количество непустых значений (count). Примеры показателей для нашей задачи:
Сумма заказов.
Средний чек заказа.
Количество заказов (уникальность здесь обеспечена тем, что одна строка это заказ, дублей заказов нет).
Количество уникальных клиентов (нужно считать число уникальных ID, так как один клиент может сделать несколько заказов, и его посчитают несколько раз).
ID заказов и ID клиентов могут быть как измерениями тогда вы сможете считать статистику по конкретным заказам или клиентам, так и показателями тогда можно просто посчитать количество заказов или клиентов. Это целиком зависит от вашей задачи, оба способа работают.
Аналитик определяет для каждого столбца, являются ли данные в нем измерениями или показателями, а также какие статистики по показателям ему нужны. Подготовительные работы закончены, теперь время сформулировать гипотезы и для каждой из них определить один или несколько срезов, которые подтвердят гипотезу или опровергнут. Понятие среза происходит из многомерной природы сводных таблиц. Представьте себе трехмерный предмет, имеющий следующие измерения: длину, ширину и высоту. Пусть это будет кусок сливочного масла. Вы берете нож, разрезаете его и получаете срез, причем плоскость среза перпендикулярна оси, которую вы фиксируете. То же самое вы проделываете, когда работаете со сводной таблицей делаете срез многомерных данных. Осей может быть много, это число равно числу измерений вот откуда берется многомерность. Место на оси (измерение), перпендикулярно которой режете, попадет в фильтр отчета как значение. Вы фиксируете его. Измерения, которые будут лежать в плоскости среза, будут столбцами и строками нашей таблицы. Если фильтр отчета не используется, то все данные будут спроецированы на наш срез при помощи операции агрегации, которая для каждого показателя выбирается индивидуально (суммы, средние, количество).
Аналитик формулирует две гипотезы относительно падения продаж:
Изменение поведения вызвано одним из типов клиента. Для этой гипотезы одно из измерений тип клиента.
Изменение поведения вызвано одной из групп лояльности. Для этой гипотезы одно из измерений статус лояльности клиента.
Так как у нас произошли изменения во времени, то нам понадобится еще одно измерение время. Итак, гипотеза и нужный срез данных сформулированы, а дальше дело техники: мышью перетащить нужные измерения, например, дату в столбцы, тип клиента в строки. Заполнить таблицу нужными показателями и проверить, подтверждается ли проверяемая гипотеза цифрами или нет. Правильность гипотезы желательно проверить подходящим статистическим критерием для гипотез, что в реальности делается довольно редко.
Гипотезы можно формулировать и проверять последовательно, а когда наработается опыт, то они будут формулироваться на уровне подсознания. Аналитик будет играть ими, чтобы найти самую вероятную причину проблемы или успеха: делать первый срез, а потом добавлять измерения, пересекая их со старыми, и изменять показатели.
Если бы не было электронных таблиц и средств визуального анализа на сводных таблицах, то скорость подобного типа анализа была бы в десятки раз ниже. Аналитику пришлось бы программировать каждый срез, например, через оператор GROUP BY в SQL или pivot в питоновской библиотеке pandas. Со сводными таблицами аналитик работает со скоростью своей мысли.
OLAP-кубы
Сводные таблицы бывают не только в электронных таблицах. Большие объемы данных туда не поместить они будут очень медленно работать, если вообще туда поместятся. А мы ведь хотим, чтобы все работало со скоростью мысли, не правда ли? Для этого производители софта идут на всякие ухищрения, например, размещают данные в колоночной базе данных прямо на компьютере пользователя (о преимуществах колоночных баз данных уже написано в главе про хранилища). Второй способ делать все вычисления на серверах, а пользователю предоставить туда доступ через интерфейс (толстый или тонкий клиент). Именно так были придуманы кубы OLAP (On-Line Analytical Processing интерактивный анализ данных).
История их появления очень интересна как минимум тем, что к этому приложил руку наш бывший соотечественник Михаил (Моша) Пасуманский. Михаил переехал в Израиль из Санкт-Петербурга в 1990 году. Там он написал аналитическое приложение «Панорама». В 1995 году они выпустили первую версию. В 1996 году компанию купила Microsoft, которой нужно было подобное решение для новой версии SQL Server. После интеграции системы в софт Microsoft появился язык программирования для работы с OLAP-кубами, который называется MDX (Multidimensional Expressions), чьим автором является Михаил Пасуманский. Этот язык является стандартом для работы с OLAP-кубами, и его поддерживают очень многие вендоры. Сервис OLAP-кубов теперь называется Analysis Services.
Мы уже рассмотрели, как работают сводные таблицы. Теперь посмотрим, как проблема производительности решается в OLAP-кубах, которые эти сводные таблицы умеют очень быстро рассчитывать. Я много работал с технологиями Microsoft по OLAP-кубам, поэтому буду опираться на свой опыт. Центральным звеном любого OLAP-куба является таблица фактов, которую мы рассмотрели на примерах построения сводных таблиц чуть ранее. Однако есть небольшое, но важное отличие: таблица фактов, как правило, не соединяется со справочниками, она загружается в кубы отдельно от них.
Для этого в хранилище данные готовятся по схеме «звезда» (рис. 7.4): таблица фактов соединяется по полям, содержащим ID (ключи), со справочниками, как показано на рисунке. Существует правило все измерения лучше держать в отдельных справочниках. Это сделано для того, чтобы можно было их обновлять независимо от таблицы фактов. После подготовки нужных данных в программе-дизайнере нужно отметить, какие таблицы являются таблицами измерений, а какие таблицами фактов. Там же в настройках указывается, какие показатели необходимо рассчитать. Первичная обработка куба заключается в чтении всех данных из хранилища и помещении их в специальные структуры, которые очень быстро работают с расчетом сводных таблиц. Сначала читаются и обрабатываются все измерения, и только после этого таблица фактов. Но самое интересное происходит потом, когда нужно добавить в куб новые данные.
Рис. 7.4. Соединение таблиц по схеме «звезда»
Но что делать, если появились новые данные? Нужно обновить данные в нашей «звезде» хранилище и обновить куб на их основе. Обновление данных для уже обработанного рабочего куба заключается в полном прочтении всех измерений (справочников): если появляются новые элементы или они переименовываются все обновится. Поэтому справочники измерений для OLAP-кубов нужно сохранять и обновлять в первозданном виде данные оттуда удалять нельзя. Обновление таблицы фактов интереснее можно выбрать полное обновление и пересчет куба, а можно стереть старые данные из таблицы фактов и залить туда новые, которых нет в кубе, и только после этого обновить куб. Схема с инкрементальным обновлением выгоднее с точки зрения времени обработки куба. В Ozon.ru полный процессинг куба мог занимать у меня четыре дня, а инкрементальное обновление всего двадцать минут.
Существует несколько популярных вариантов хранения и обработки данных в OLAP-кубах:
MOLAP та схема хранения, которую я описал выше. Данные хранятся в специальных структурах, которые очень быстро вычисляют сводные таблицы.
ROLAP данные никуда не помещаются, они находятся в хранилище. OLAP-куб транслирует запросы из сводных таблиц в запросы к хранилищу и отдает результат.
HOLAP данные частично находятся в MOLAP-, частично в ROLAP-схемах. Например, это может быть полезно для уменьшения времени отставания куба от реального времени. Куб обновляется раз в день по схеме MOLAP, а новые данные, которых там пока нет, существуют в схеме ROLAP.
Я всегда предпочитал пользоваться MOLAP-схемой, как наиболее быстрой. Хотя в связи с развитием быстрых колоночных баз данных ROLAP могут оказаться проще. Ведь ROLAP-схема не требует тщательного дизайна куба, как MOLAP, что сильно упрощает техническую поддержку OLAP-куба.
Самый идеальный клиент для OLAP-кубов это электронные таблицы Microsoft Excel, где работа с кубами от Microsoft реализована очень удобно. Любые тонкие клиенты не обеспечивают того удобства и гибкости, которые предлагает Excel: возможность использования MDX, гибких формул, построения отчетов из отчетов. К сожалению, эта функциональность поддерживается только в операционной системе Windows. Версия Excel для OS X (Apple) не поддерживает ее. Вы даже не представляете себе, сколько руководителей и специалистов шлют проклятья разработчикам MS за это. Ведь им приходится держать отдельные ноутбуки с Windows или удаленные машины в облаке только для того, чтобы работать с кубами Microsoft. Я считаю, что это самая большая ошибка Microsoft в нашей области.