Перейти к основному содержимому

Создание семантических моделей

Как создать семантическую модель

Семантическая модель в семантическом слое эквивалентна модели логического слоя (то, что исторически называлось просто "моделью" в dbt). Так же, как конфигурации для моделей определяются в ключе YAML models:, конфигурации для семантических моделей находятся под semantic models:. Ключевое отличие заключается в том, что в то время как логическая модель состоит из конфигурации и SQL или Python кода, семантическая модель определяется исключительно через YAML. Вместо кодирования конкретного набора данных, семантическая модель описывает отношения и выражения, которые позволяют вашим конечным пользователям выбирать и уточнять свои собственные наборы данных динамично и надежно.

  • ⚙️ Семантические модели состоят из трех компонентов:
    • 🫂 сущности: они описывают отношения между различными семантическими моделями (подумайте об идентификаторах)
    • 🔪 измерения: это столбцы, по которым вы хотите разбивать, группировать и фильтровать (подумайте о временных метках, категориях, булевых значениях).
    • 📏 меры: это количественные значения, которые вы хотите агрегировать
  • 🪣 Мы определяем столбцы как сущность, измерение или меру. Столбцы обычно попадают в одну из этих 3 категорий, или, если это сложное выражение агрегации, они могут составлять метрику.

Определение заказов

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

  • 📗 Мы определяем ее как YAML-словарь в списке semantic_models.
  • 📑 Она будет иметь имя, список сущностей, список измерений и список мер.
  • ⏬ Мы рекомендуем определять их в этом порядке последовательно как лучшую практику стиля.
models/marts/orders.yml
semantic_models:
- name: orders
entities: ... # мы определим их позже
dimensions: ... # мы определим их позже
measures: ... # мы определим их позже
  • Далее мы укажем на соответствующую логическую модель, предоставив ref в свойстве model:, и description для документации.
models/marts/orders.yml
semantic_models:
- name: orders
description: |
Модель, содержащая данные о заказах. Зерно таблицы — идентификатор заказа.
model: ref('stg_orders')
entities: ...
dimensions: ...
measures: ...

Установление наших сущностей

  • 🫂 Сущности — это объекты и концепции в наших данных, которые имеют измерения и меры. Вы можете думать о них как о существительных нашего проекта, основах наших запросов, по которым мы можем захотеть агрегировать, или просто как о ключах соединения.
  • 🔀 Сущности помогают MetricFlow понять, как различные семантические модели связаны друг с другом.
  • ⛓️ В отличие от многих других семантических слоев, в MetricFlow нам не нужно явно описывать соединения, вместо этого отношения описываются неявно через сущности.
  • 1️⃣ Каждая семантическая модель должна иметь одну основную сущность, определенную для себя, и любое количество внешних сущностей для других семантических моделей, к которым она может присоединяться.
  • 🫂 Сущности требуют имени и типа

Сущности в действии

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

models/staging/stg_orders.sql
renamed as (

select

---------- ids
id as order_id,
store_id as location_id,
customer as customer_id,

---------- properties
(order_total / 100.0) as order_total,
(tax_paid / 100.0) as tax_paid,

---------- timestamps
ordered_at

from source
  • 👉 Мы добавляем их с name, type и необязательным expr (выражение). Выражение может быть любым допустимым SQL-выражением на вашей платформе.
  • 📛 Если вы не добавите выражение, MetricFlow предположит, что имя равно имени столбца в подлежащей логической модели.
  • 👍 Наша лучшая практика — по возможности предоставлять name, который является единственным числом предмета или зерна таблицы, и использовать expr для указания точного имени столбца (с _id и т.д.). Это позволит нам писать более читаемые метрики поверх этих семантических моделей. Например, мы будем использовать location вместо location_id.
models/marts/orders.yml
semantic_models:
- name: orders
...
entities:
# мы используем столбец для имени здесь, потому что order является зарезервированным словом в SQL
- name: order_id
type: primary
- name: location
type: foreign
expr: location_id
- name: customer
type: foreign
expr: customer_id

dimensions:
...
measures:
...

Определение наших измерений

  • 🧮 Измерения — это столбцы, которые мы хотим фильтровать и группировать, прилагательные нашего проекта. Они бывают трех типов:
    • категориальные
    • временные
    • медленно изменяющиеся измерения — они описаны в документации и немного сложнее. Чтобы сосредоточиться на построении ваших ментальных моделей основ MetricFlow, мы не будем использовать SCD в этом руководстве.
  • ➕ Мы не ограничены существующими столбцами, мы можем использовать свойство expr для добавления простых вычислений в наши измерения.
  • 📛 Категориальные измерения самые простые, они просто требуют name и type (тип — категориальный). Если свойство name совпадает с именем столбца измерения, это все, вы закончили. Если вы хотите или вам нужно использовать name, отличный от имени столбца, или сделать некоторое фильтрование или вычисление, вы можете предоставить необязательное свойство expr для оценки измерения.

Измерения в действии

  • 👀 Давайте снова посмотрим на нашу модель подготовки и посмотрим, какие поля у нас доступны.
models/staging/stg_orders.sql
select

---------- ids -> entities
id as order_id,
store_id as location_id,
customer as customer_id,

---------- numerics -> measures
(order_total / 100.0) as order_total,
(tax_paid / 100.0) as tax_paid,

---------- timestamps -> dimensions
ordered_at

from source
  • ⏰ На данный момент единственное измерение, которое нужно добавить, это временное измерение: ordered_at.
  • 🕰️ По крайней мере одно основное временное измерение требуется для любых семантических моделей, которые имеют меры.
  • 1️⃣ Мы обозначаем это с помощью свойства is_primary, или если предоставлено только одно временное измерение, оно является основным по умолчанию. Ниже у нас есть только ordered_at как временная метка, поэтому нам не нужно указывать ничего, кроме минимальной гранулярности, к которой мы группируем (в данном случае, день). Под этим мы подразумеваем, что мы не будем рассматривать заказы с более мелкой гранулярностью, чем день.
models/marts/orders.yml
dimensions:
- name: ordered_at
expr: date_trunc('day', ordered_at)
type: time
type_params:
time_granularity: day
подсказка

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

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

  • 🔢 Мы также можем создать измерение из числового столбца, который обычно был бы мерой.
  • 🪣 Используя expr, мы можем создавать группы значений, которые мы маркируем для нашего измерения. Мы добавим одну из них для маркировки 'больших заказов' как любых заказов с общей суммой более $50.
models/marts/orders.yml
dimensions:
- name: ordered_at
expr: date_trunc('day', ordered_at)
type: time
type_params:
time_granularity: day
- name: is_large_order
type: categorical
expr: case when order_total > 50 then true else false end

Создание наших мер

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

Меры в действии

  • 👀 Давайте посмотрим на нашу модель подготовки в последний раз и посмотрим, какие поля мы хотим измерить.
models/staging/stg_orders.sql
select

---------- ids -> entities
id as order_id,
store_id as location_id,
customer as customer_id,

---------- numerics -> measures
(order_total / 100.0) as order_total,
(tax_paid / 100.0) as tax_paid,

---------- timestamps -> dimensions
ordered_at

from source
  • ➕ Здесь order_total и tax paid — это столбцы, которые мы хотим использовать как меры.
  • 📝 Мы можем описать их с помощью кода ниже, указав имя, описание, агрегацию и выражение.
  • 👍 Как и прежде, MetricFlow по умолчанию будет считать, что имя равно имени столбца, если выражение не указано.
  • 🧮 Множество различных агрегаций доступно для нас. Здесь мы просто хотим суммы.
models/marts/orders.yml
measures:
- name: order_total
description: Общая сумма для каждого заказа, включая налоги.
agg: sum
- name: tax_paid
description: Общая сумма налога, уплаченного за каждый заказ.
agg: sum
  • 🆕 Мы также можем создавать новые меры, используя выражения, например, добавляя количество отдельных заказов, как показано ниже.
models/marts/orders.yml
- name: order_count
description: Количество отдельных заказов.
expr: 1
agg: sum

Проверка нашей работы

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

 Подход с совместным расположением
 Подход с параллельной поддиректорией

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

  1. Расположение файла

    • Подход с совместным расположением: models/marts/orders.yml
    • Подход с параллельной поддиректорией: models/semantic_models/sem_orders.yml
  2. Именование файла

    • Подход с совместным расположением: Использует то же имя, что и соответствующий mart (orders.yml)
    • Подход с параллельной поддиректорией: Добавляет префикс sem_ к файлу (sem_orders.yml)

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

Следующие шаги

Давайте рассмотрим основы семантических моделей:

  • 🧱 Состоят из сущностей, измерений и мер.
  • 🫂 Описывают семантику и отношения объектов в хранилище.
  • 1️⃣ Соответствуют одной логической модели в вашем проекте dbt.

Далее, давайте используем нашу новую семантическую модель для создания метрики!

0