Привет, Хабр! Меня зовут Сергей Тимакин, сейчас учусь на первом курсе онлайн-магистратуры «Специалист по работе с данными и ИИ» НИЯУ МИФИ в партнёрстве с Яндекс Практикумом и параллельно работаю в Озоне аналитиком данных. В этой статье я расскажу, как я столкнулся с трудностями в понимании слоёв и моделей данных — и как разобраться в этой теме.

Зачем вам читать эту статью

В материалах на Хабре и в других блогах я заметил, что описания слоёв и моделей данных очень разнятся. Складывается впечатление, что модели данных и слои не зависят друг от друга, хотя это не так. На конкретном слое обычно может располагаться одна конкретная модель (или несколько однотипных), которая подходит для этого слоя больше всего.

Ещё я недавно познакомился с новомодным термином «medallion» — это архитектурный подход по организации слоёв данных. По сути он практически ничем не отличается от классической трёхуровневой архитектуры (raw слой, core слой, data marts слой), но относится именно к гибридному решению построению Data Lakehouse (хранилище и озеро данных). Читая про medallion, я только запутался: зачем придумывать новый термин, когда уже давно есть трёхуровневая архитектура. Подозреваю, что medallion — это ребрендинг старых идей, как говорится, «Всё новое — хорошо забытое старое».

Если вам тоже интересно разобраться, готовьтесь — вас ждет лонгрид :)

Почему я уделяю такое внимание слоям данных

Даже без существования какого-либо хранилища или другого большого источника данных так или иначе специалист (менеджер, аналитик и т. д.) работает как минимум с 2-3 слоями: 

  1. Сырые данные (в Excel или CSV).

  2. Преобразованные данные (в сводной таблице, с добавленными признаками и т. д.).

  3. Опционально можно выделить третий слой — итоговую сводную таблицу для руководства или коллег.

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

Основные термины в статье:

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

Модель данных — представление структуры данных, связей между таблицами (или витринами) и ограничений целостности. Она определяет, как данные организованы в хранилище.

Какие бывают слои данных и какие операции с ними проводят

Как вы уже поняли из термина в начале статьи, слои данных — это многоуровневая архитектура хранения. Чем выше уровень, тем более качественные данные на нём будут. В классическом подходе выделяют три слоя:

  1. Raw (от англ. raw — сырой, необработанный). Иногда — stage, хотя он может быть дополнительным слоем и не быть raw, но в этом контексте это не важно. На нём хранятся так называемые «сырые данные», которые в целом могут быть либо вообще не обработанными либо обработаны с очень минимальными изменениями. 

  2. Core (от англ. core — ядро, суть). На нём хранятся обработанные данные, которые были подвержены очистке, агрегации, приведению типов или другим манипуляциям. Ещё при работе с этим слоем обычно задумываются о способе организации данных и построению так называемой модели данных (об этом будет ниже в статье).

  3. Data Marts (от англ. Data Mart — витрины данных). Тут лежат данные, готовые к конечному потреблению бизнес-пользователями. Они очищены, агрегированы и отвечают на конкретный бизнес-запрос.

Если приводить аналогию с Excel-файлом, то Raw слой — это выгруженный файл из системы, core слой преобразованный файл с дополнительными необходимыми вам столбцами, а слой Data Marts — это конечная сводная таблица с понятными выводами, которые можно показывать руководству. 

При этом необязательно хранить данные в одном месте, источнике или инструменте хранения — например, Excel-файле, PostgreSQL, Vertica. Raw слой (при должной организации) может лежать в CSV-файле, S3 или любом другом источнике хранения. Core слой (детальный) может уже лежать на самой Vertica или Postgres, а Data Marts слой может быть уже в Clickhouse или же на самой Vertica также как и практически в другом любом источнике, даже в Power BI можно его реализовать. 

Конечно, слишком экзотические варианты реализации слоёв в разных инструментах не нужно брать за основу, т.к. обычно такие решения — костыли и принимаются не от хорошей жизни. Строить Data Marts слой в семантической модели Power BI можно, но по моему мнению, это не лучшая практика. 

В классическом построении слои Raw, Core и Data Marts лежат в одной базе данных (PostgreSQL, MySQL и т.д.), но часто такое хранение обходиться слишком дорого и слои разносят по другим системам, например: Raw слой на hdfs, Core слой — в Vertica, а Data Marts — в Clickhouse. Такой подход называют смешанным, объединяющим dwh и data lake. 

Можно ли такой подход назвать data lakehouse или это modern data warehouse? Точного ответа у меня нет: в разных источниках я видел разные определения, но вы можете поделиться своим мнением в комментариях к статье. 

Такое же количество и назначение слоёв есть в новом подходе medallion, только они иначе называются: 

  • raw — bronze слой.

  • core слой – silver слoй.

  • data marts слой – gold слой.

По функционалу и существу это те же самые слои, описанные выше. Я думаю, что термин medallion относится к построению data lakehouse, в то время как классические три слоя (raw, core, data marts) относятся к построению dwh. 

Возможно, введение нового термина оправдано и позволяет быстро ориентироваться в контексте, но лично я, читая документацию по medallion (она, кстати есть на официальном сайте Microsoft) ещё больше запутался и задался вопросом, а в чём разница между классическими тремя слоями и архитектурой medallion?  Пока мне не удалось ответить на этот вопрос и подозреваю, что большой разницы нет. 

В небольших компаниях, которые собирают не очень много данных, может быть только два слоя (например raw и core), где core слой может одновременно быть и Data Marts слоем. Это может быть из-за экономии ресурсов или из-за того, что нет необходимости выделять отдельно слой Data Marts из-за небольшого количества данных и преобразований. 

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

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

Если разобраться со слоями данных и их назначением, будет легче понять модели данных и то, на каких слоях какие модели могут располагаться. Данные нужно моделировать, чтобы они не превратились в хаос, а бизнес мог принимать решения быстро и без ошибок. Без моделирования данные — это просто огромное количество файлов, таблиц и полей, в которых сложно разобраться. 

Я расскажу про основные модели данных, которые часто используются в компаниях и хорошо подходят к слоёной архитектуре. Этот список не исчерпывающий, есть настолько экзотические модели данных, что их достаточно сложно понять (по крайней мере мне).

Представим, что у нас есть две исходные таблицы из какого-либо источника: orders и clients. Они нам приходят в таком виде, другой формат мы получить не можем. Эти таблицы помещаются у нас на Raw слой.

На примере исходных таблиц orders и clients разберу каждую модель данных и покажу, как она будет выглядеть и на каком слое она может находиться. Я не хочу начинать с классической снежинки или звезды, так как в современном мире они обычно моделируются уже на третьем слое Data Marts (Gold по medallion). Я хочу вам показать последовательное моделирование от Raw слоя до Data Marts слоя. Поэтому начнём с моделей Data Vault 2.0 и Anchor, которые обычно строятся на втором, Core (Silver по medallion) слое. На Raw слое обычно нет моделей или копируется модель из исходного источника. В нашем случае на Raw (Bronze по medallion) слое лежат две, пока несвязанные, таблицы — orders и clients.

В действительности на слоях может лежать какая угодно модель данных. Бывают хранилища данных, которые состоят полностью из несвязанных между собой таблиц и источников. Необязательно, чтобы звезда или снежинка строились на Data Marts слое или Anchor model на core (silver) слое. Но если выстраивать рекомендуемые модели ниже на определённых слоях, это может облегчить вам жизнь по анализу и обработке данных. 

Ещё эти модели можно использовать не только в реляционных базах данных — хотя, если честно, на практике я ещё не встречал реализацию anchor модели в других средах. Ниже я использовал аннотацию похожую на проектирование реляционных баз, но пусть она вас не смущает. 

Все преобразования при построении дальнейших моделей основываются на наших двух таблицах orders и clients. Также могут добавляться только различные технические поля или урезаться часть столбцов для читаемой схемы. При этом не стоит забывать, когда мы перейдем на моделирование Data Marts слоя, он будет собираться из модели на основе Core слоя. Обычно не рекомендуется перепрыгивать при построении моделей и таблиц через слои, хотя это и не запрещается.

Моделирование на слое Core

Основные принципы при создании модели на Core слое: 

Отсутствие прямого копирования исходной структуры

  • Core слой — модель, спроектированная под задачи, а не под источник. 

  • Переименование полей в единый стандарт (snake_case / camelCase). 

  • Приведение типов (datetime вместо string).

Историчность

  • На Core слое нельзя потерять историю изменений.

  • Если в источнике изменился адрес клиента, в Core слое появляется новая запись, а старая помечается как закрытая. Примеры дополнительных полей для историчности: valid_from, valid_to (или is_current), load_datetime.

Интеграция разных источников

  • Core слой обязан связать данные из разных систем. Пример: orders из CRM, shipments из WMS, payments из ERP.

  • В Core слое появляется единое представление заказа (в нашем случае) — даже если в источниках нет внешних ключей, их восстанавливают через маппинг/справочники.

Отказоустойчивость и идемпотентность

  • Загрузка в Core слой должна безопасно повторяться.

  • Повторная подача тех же данных не создаёт дубли.

  • Каждая запись может содержать source_system, чтобы можно было откатить данные одной системы.

Отсутствие агрегатов и денормализации под отчёт

  • На Core слое нельзя строить: сумму по клиенту, количество заказов в месяце, отчётную выгрузку с расчётами. Всё это должно быть на Data Marts (Gold) слое.

  • Core слой — только детализация. Даже если запрос становится сложным (много JOIN).

Один слой Core — много витрин на слое Data Marts

  • Core слой проектируется как стабильное основание для любых будущих витрин.

  • Нельзя подстраивать Core под один конкретный отчёт.

  • Нельзя удалять колонку, потому что «пока не нужна».

Гибкость к изменениям источников

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

Список можно продолжить. Для моделирования данных на Core слое с учётом вышеописанных принципов отлично подходят Data Vault 2.0 или Anchor Model (есть ещё и 3 нормальная форма, но в статье я решил её не описывать). 

Data Vault 2.0

Это модель данных, предназначенная для историчного, отказоустойчивого и масштабируемого хранения данных в Core слое хранилища. Основные сущности Data Vault: 

  • Хабы (Hubs) — бизнес-сущности

  • Линки (Links) — Связи

  • Сателлиты (Satellites) — Атрибуты и описание бизнес-сущностей

  • Хаб — это одна бизнес-сущность. На картинке выше вы можете увидеть два хаба т.е. две бизнес-сущности: hub_clients и hub_orders в них содержаться id заказов и id клиентов, а также остальные технические поля: record_source – источник загрузки, из какой системы загружены эти данные, load_date – время загрузки, order_hk искусственно созданный хеш ключ (нужен для построения модели).

  • Линк — это связка между двумя бизнес-сущностями, в нашем случае между клиентами и заказами.

  • Сателлиты — это атрибуты заказа или клиентов. Например: возраст клиента, пол, номер телефона. Они выделяются в несколько разных отдельных таблиц по бизнес-логике. E-Mail и телефон можно выделить в один сателлит, а пол и возраст в другой (можно разделять также по частоте заполнения и т. д.). Если вдруг в источнике появится новый атрибут, можно создать для него новый сателлит.

Anchor Model

Это якорная модель, реляционная, «ещё более гранулярная версия Data Vault». Основные сущности Anchor Model:

  • Anchor — бизнес-сущность (клиент, заказ)

  • Knot — общие справочники 

  • Attribute — атрибуты бизнес-сущностей 

  • Tie — связи

Якорная модель — это максимальная нормализация (6-я нормальная форма). В отличие от Data Vault, каждый атрибут (почта, телефон, имя, пол) бизнес-сущности содержится в отдельной таблице. Я не стал в схеме рисовать все атрибуты, только несколько. В настоящих боевых системах это потрясающее зрелище, якорная модель может спокойно дробиться на десятки, а то и сотни тысяч таблиц. Не знаю, как у вас, но у меня это вызывает восторг!

Моделирование на слое Data Marts

Data Marts слой — это прежде всего витрины данных, которые строятся поверх Core слоя (Silver по medallion) и предназначены для бизнес-пользователей, отчётов, дашбордов и BI-инструментов. На уровне Data Marts находятся денормализованные, агрегированные, оптимизированные под чтение данные, отвечающие на конкретный бизнес-вопрос. Сейчас мы в том числе проходим модели данных на Data Marts слое в магистратуре и разбираем, как звёзды и снежинки оптимизируют BI-запросы

Основные принципы при моделировании Data Marts слоя:

  1. Предварительные агрегаты и вычисляемые поля.

  2. Оптимизация под конкретные BI-запросы.

  3. Витрины могут быть виртуальными (Views) или физическими (Tables).

  4. Одна витрина — обычно один бизнес-процесс, но может быть и несколько.

  5. Только актуальное состояние (обычно SCD Type 1 или Type 2 точечно).

Классические модели на слое Data marts — звезда и снежинка, ещё встречается и модель OBT (one big table).

  • Звезда— модель данных, которая состоит из двух типов таблиц: одной таблицы фактов (fact table) — центр «звезды» —и нескольких таблиц измерений (dimension table) – лучи так называемой звезды.

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

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

  • One Big Table (OBT) — денормализованный подход к структурированию данных, при котором вся информация из различных источников (факты и измерения) объединяется в одну огромную плоскую таблицу.

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

Моделирование на слое Data Marts обычно сводиться к денормализации и агрегированию информации, в отличие от моделирования на core слое, т. к. необходимо, чтобы данные были оптимизированы под чтение. Core слой — источник для построения витрин на слое Data Marts и в случае необходимости витрины на Data Marts слое можно пересобрать на конкретный момент времени (состояние данных, которое, например, было актуально 5 дней назад).

Подведём итоги

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

Если смотреть на архитектуру хранилища последовательно, то Raw слой отвечает за сохранение исходных данных, Core слой — за их очистку, нормализацию и интеграцию, а Data Marts слой — за подготовку витрин под конкретные бизнес-задачи. Medallion-подход описывает ту же логику, но другими терминами: bronze, silver и gold.

На Core слое лучше всего работают нормализированные модели, такие как Data Vault и Anchor Model, потому что они хорошо подходят для исторического и гибкого хранения данных. На Data Marts слое, наоборот, наиболее уместны более простые и прикладные модели — звезда, снежинка и OBT, так как здесь важны скорость чтения, понятность и удобство для аналитики