Что такое Activity Schema?

Activity Schema — это стандарт моделирования данных, разработанный для современных хранилищ данных. Идея принадлежит Ахмеду Эльсамадиси и заключается она в том, чтобы сделать моделирование и анализ данных значительно проще, быстрее и надежнее, чем существующие методологии (например, чем схема «звезда»).

Он противопоставляется сложным уровням зависимостей, соединениям по внешнему ключу и чрезвычайно сложным SQL-запросам в схемах «звезда» или «снежинка».

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

Основая идея

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

Бизнес-концепции представлены как сущности, выполняющие действия («клиент совершил перевод денежных средств», «клиент пополнил депозит» и т.д.), а не как факты или сущности (переводы, депозиты). Сущности являются «действующим лицом» в данных и каждое действие (событие) в Activity Schema выполняется определенной сущностью с уникальным идентификатором.

События (действия) — это конкретные действия, которые совершает сущность. Например, если объект является клиентом, действие может быть «открытие нового депозита» или «снятие начисленных процентов с депозита». Каждая строка в таблице, смоделированной Activity Schema, представляет собой отдельный экземпляр действия, выполняемого определенной сущностью.

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

С каждым событием  связаны метаданные, помимо клиента, события и временной метки. Например, событие «Пополнение депозита» будет хранить сумму, на которую был пополнен депозит. Таблицы activity stream имеют конечное число столбцов метаданных, которые могут быть связаны с каждым событием.

Все запросы выполняются в одной таблице activity stream, чтобы собрать таблицы для анализа, бизнес-аналитики и отчетов. Вместо традиционных объединений по внешнему ключу запросы объединяют действия, используя отношения во времени (например, количество клиентов, которые после закрытия депозита открыли новый, и среднее количество дней между двумя этими событиями).

Структура

Основное преимущество Activity Schema заключается в том, что все данные представлены в согласованном формате. Это означает, что для него требуются таблицы с определенными именами, типами и количеством столбцов.

Таблицы

В Activity Schema есть два типа таблиц:

  1. поток активности (Activity Stream)

  2. таблица сущностей (Entity)

В таблице activity stream хранятся все действия, их временные метки, идентификатор объекта и некоторые метаданные.

Таблица activity stream является основной и единственной необходимой таблицей в Activity Schema . Она содержит большую часть смоделированных данных в хранилище.

Column

Description

Type

activity_id

Уникальный идентификатор записи активности

string

ts

Отметка времени в формате UTC, когда произошло действие

timestamp

customer

Глобальный уникальный идентификатор клиента

string

activity

Название действия (например, «выполненный заказ»)

string

anonymous_customer_id

Уникальный идентификатор анонимного клиента (например, 'segment_abfb8a')

string

feature_1

Характеристика действия 1

string

feature_2

Характеристика действия 2

string

feature_3

Характеристика действия 3

string

revenue_impact

Доход или затраты, связанные с деятельностью

float

link

URL-адрес, связанный с действием

string

activity_occurrence

Сколько раз это действие произошло для этого клиента. Используется для оптимизации запросов.

integer

activity_repeated_at

Отметка времени следующего экземпляра этого действия для этого клиента. Используется для оптимизации запросов.

timestamp

_activity_source

Сценарий преобразования, который создал это действие

string

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

Таблица activity stream предназначена для быстрых запросов к общим хранилищам данных, таким как Redshift, BigQuery и Snowflake. Почти все современные хранилища данных ориентированы на столбцы — таблицы с меньшим количеством столбцов и большим количеством строк работают быстрее. Кроме того, таблицу activity stream обычно нужно соединять только с самой собой при запросе, что еще больше повышает производительность по сравнению с другими подходами к моделированию.

При этом важно выбрать правильную сортировку/распределение/раздел/кластер/индекс (в зависимости от технологии хранилища), чтобы обеспечить высокую производительность.

Дополнительные столбцы

Activity Schema содержит два специальных столбца, которые упрощают запросы и повышают их производительность.

Столбец activity_occurrence — количество совершенных объектом аналогичных действий на момент времени ts. activity_repeated_at — это дата и время, когда аналогичное действие совершалось в последний раз. Оба должны быть NULL, если аналогичное действие еще не произошло.

И activity_occurrence, и activity_repeated_at вычисляются из самоой таблицы activity stream, поэтому их заполнение зависит от реализации Activity Schema. Они полагаются на предыдущие экземпляры данного действия, поэтому должны вычисляться после записи действия.

Столбец _activity_source помогает реализовать таблицу activity stream — это метаданные о том, как создается сама таблица activity stream, и они не используются в запросах. Он записывает идентификатор в сценарий преобразования, который создал это событие и используется реализациями Activity Schema для поддержки инкрементальных обновлений таблицы activity stream (идентифицировать все строки с событиями, созданные данным преобразованием, найти максимальную отметку времени и вставить новые строки с более новой отметкой времени).

Таблица сущностей

Таблица сущностей хранит неограниченное количество столбцов метаданных. Концептуально таблица содержит столбец первичного ключа для идентификации уникального клиента и неограниченное количество необязательных столбцов, содержащих метаданные. Это похоже на таблицы измерений в схеме «звезда». При запросе эту таблицу можно соединить с таблицей activity stream, когда это необходимо, с использованием идентификатора объекта.

Столбец первичного ключа — единственный обязательный столбец.

В заключение

В заключение хотелось бы отметить несколько преимуществ и недостатков Activity Schema.

К преимуществам можно отнести:

  • меньше моделей — одна (и только одна) бизнес-концепция для каждого вида деятельности означает меньше моделей для управления, понимания и поддержки

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

  • легко вносить изменения в исходные данные — нужно только обновить одно действие

  • простое происхождение данных — единый слой данных значительно упрощает отслеживание происхождения данных и отладку

  • более быстрые обновления — моделирование временных рядов означает добавочные обновления (а не полные перестроения) по умолчанию

  • нет словарей — значительно упрощает документирование Activity Schema

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

  • настоящие нерегламентированные запросы — поскольку все действия связаны во времени, замена одного действия на другое не требует структурных изменений в запросах

  • высокая производительность — запросы выполняются значительно быстрее к таблице activity stream, которая имеет меньше столбцов, требует меньше объединений и может быть легко секционирована/индексирована по времени

Если говорить о недостатках, то можно отметить следущее:

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

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

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

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

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

Комментарии (8)


  1. baldr
    14.11.2022 16:41
    +5

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

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

    То есть, храним цвет собачки клиента в одной таблице вместе с его номером банковского счета? Никаких индексов, constraints.. И джойним десяток раз таблицу саму с собой? И планировщик не сходит с ума? Да что за волшебный движок у вас там внутри что все работает даже еще быстрее?

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


  1. SLASH_CyberPunk
    14.11.2022 16:48
    +1

    Концептуально подход имеет место быть, но имхо, в своей голове я развил это немного до другого уровня (граф как бизнес-процесс с классическими подходами на множествах). Но вся проблема в том, что тут описанный подход, что мной придуманный - это проблема технического характера. Надо понимать, что у нас помесь OLTP с OLAP (ныне модный HTAP) и что для масштабирования, для транзакций, для блокировок и для аналитики, подход в одну таблицу априори не подойдет...


  1. Ivan22
    14.11.2022 17:17
    +1

    "Bi-щик изобретает EAV" - смотреть без регистрации и СМС.

    p.s. Это порно очень жесткое - поэтому строго 18+


  1. OkunevPY
    14.11.2022 21:28
    +1

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

    Не очень понятно как и что индексировать в метаданных. Хорошо если там действительно храниться один аттрибут сумма и он не требует поиска и индексации, а если это не так?

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


  1. Ninil
    15.11.2022 01:03
    +4

    Представил вопрос от бизнеса в банке, адаптированный под эту модель и захотелось уволиться: посчитай количество клиентов, которые открыли продукт Х в рамках маркетинговой компании Y в месяце Z на сумму не менее А и у которых среднемесячный оборот по кредитной карте за последние В месяцев не менее С.

    А по делу. Эта модель не для DWH. Одна из задач хранилища — ОБЛЕГЧАТЬ и УПРОЩАТЬ аналитические запросы к данным. Вы же предлагает модель, скорее оптимизированную под транзакционные бизнес-системы. Не говоря уже о том, что непонятно как поддерживать в такой модели историчность сущностей, консистентность данных, контролировать их качество и т.п.

    Чтобы просто абы как хранить данные, чтобы потом абы как писать к ним запросы — есть 100500 способов, плохих и не очень. Хранить все разнородные сущности в одной таблице, а все разнородные транзакции — в другой? Такой подход давно известен под названием «любое DWH на трёх таблицах»))) на практике, естественно, никем не используется )

    ПыСы полагаю, автор очень мало работал с настоящими DWH


  1. MentalBlood
    15.11.2022 11:01

    Можно ли обойтись одной таблицей вместо хранилища данных?

    А можно не надо


  1. Ivan22
    15.11.2022 11:35
    +2

    и вообще, как-то сложно выглядит. Таблицы, поля... взять все и сложить в один файл! Обзовем по модному - даталейк и всё из него будем считать.


  1. Shadilan
    16.11.2022 08:58
    +2

    О в Oracle EBS так было, даже пожестче все храним в одной таблице рядом храним описание типов сущностей на этой таблице (что означает feature1-feature3) только там пошли дальше универсальная таблица была из 100 полей, но полей не хватало поэтому была ещё рядом таблица экстеншен где не поместившиеся, не такие важные метаданные. Пока запросы формируются самим ЕBS все относительно не плохо, но как только сам пытаешься разобрать что где лежит, начинается ад