Перевод 2 главы «Моделирование данных для аналитики (dbt)»

Table of Contents

Глава 2 «Моделирование данных для аналитики (dbt)»

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

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

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

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

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

В этой книге мы выделяем SQL и dbt как две основные технологии для поддержания эффективного проекта по аналитической инженерии, что также применимо к проектированию и реализации эффективной модели данных. Причина этого в том, что SQL предоставляет пользователям возможность определять таблицы, манипулировать данными и извлекать информацию благодаря своим мощным возможностям запросов. Его непревзойдённая гибкость и универсальность делают его отличным инструментом для построения и поддержки моделей данных, позволяя пользователям формулировать сложные взаимосвязи и с лёгкостью получать доступ к конкретным подмножествам данных.

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

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

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

Краткое введение в моделирование данных

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

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

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

Помимо этих ключевых практик, стоит отметить, что эксперты в данной области, такие как Лоуренс Корр в своей популярной книге Agile Data Warehouse Design (DecisionOne Press), рекомендуют использовать дополнительные техники, такие как визуализация на доске и обсуждение, на начальном этапе проектирования моделей данных. Эти стратегии могут привнести тонкость в процесс, позволяя более глубоко изучить требования бизнеса и гарантировать, что итоговые модели данных будут безупречно соответствовать целям и особенностям бизнеса.

После завершения этапа понимания мы переходим к трём базовым этапам моделирования базы данных:

  • Концептуальная фаза
  • Логическая фаза
  • Физическая фаза

Эти этапы представляют собой путь к созданию надёжной и хорошо организованной структуры базы данных.

Концептуальная фаза моделирования

Концептуальная фаза моделирования базы данных требует выполнения нескольких важных шагов.

Во-первых, необходимо определить цель и задачи базы данных, а также уточнить конкретные проблемы или требования, которые она должна решать.

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

Затем проводится анализ и определение сущностей, что включает в себя идентификацию ключевых объектов или концепций, которые будут представлены в базе данных, и определение их атрибутов и отношений.

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

Эти проекты базы данных часто создаются с помощью диаграмм, текстовых описаний или других методов, которые фиксируют и эффективно передают дизайн и концепцию базы данных. Одним из самых распространённых инструментов для визуального представления концепций базы данных является диаграмма сущность-связь (ERD). Визуальные модели, созданные с использованием ERD, служат диаграммным представлением, которое эффективно описывает сущности для моделирования, их взаимосвязи и кардинальность этих взаимосвязей. Используя модель ERD, мы можем визуально описать структуру базы данных, включая сущности как основные компоненты, связи или ассоциации между сущностями, а также количество или степень этих взаимосвязей.

Давайте сделаем очень простой концептуальный дизайн базы данных. Представьте, что O’Reilly хочет отслеживать книги и авторов, которые были ранее опубликованы, а также даты выхода новых книг, которые ещё не изданы. Мы проводим серию интервью с менеджерами издательства и начинаем понимать, какие именно данные необходимо хранить в базе данных. Основная цель — определить задействованные сущности, их связи и атрибуты каждой сущности. Имейте в виду, что это упражнение является иллюстративным и намеренно упрощено.

Мы выделяем три разные сущности в этой подсистеме управления книгами:

Книга (Book)

Эта сущность представляет книгу, опубликованную O’Reilly. Атрибуты могут включать:

  • book_id
  • title
  • publication_date
  • ISBN
  • price
  • конкретную категорию.

Собеседники отметили, что в этой модели каждая книга может относиться только к одной категории.

Автор (Author)

Эта сущность представляет автора, который написал книги для O’Reilly.

Атрибуты могут включать:

  • author_id
  • author_name
  • email
  • bio.

Категория (Category)

Эта сущность представляет категорию книги и может содержать такие атрибуты, как:

  • category_id (уникальный идентификатор)
  • category_name.

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

Например:

  • В отношении «один-к-одному» (one-to-one) можно рассматривать связь между сущностями «Книга» и «Автор», где каждая книга связана только с одним автором, и наоборот.
  • В отношении «один-ко-многим» (one-to-many) можно рассматривать связь между сущностью «Категория» и «Книга», где каждая книга может относиться только к одной категории, но каждая категория может содержать несколько книг.
  • В отношении «многие-к-одному» (many-to-one) можно рассматривать связь между сущностью «Издатель» и «Книга», где один издатель издаёт множество книг.
  • В отношении «многие-ко-многим» (many-to-many) можно рассматривать связь между сущностью «Книга» и «Читатель», где множество читателей могут владеть множеством книг.

Продолжая наше упражнение, мы также определили две чёткие связи.

Связь «Книга-Категория»

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

Связь «Книга-Автор»

Устанавливает связь между книгами и авторами. Одна книга может иметь нескольких авторов, а один автор может писать несколько книг. Эта связь представлена как отношение «многие-ко-многим». Именно в рамках этой связи происходит публикация конкретной книги.

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

Теперь, когда у нас есть представление о сущностях, атрибутах и связях, у нас есть всё необходимое для проектирования базы данных с использованием диаграммы «сущность-связь» (ERD). Таким образом, мы можем визуально представить сущности, связи и их кардинальность, как показано на Рисунке 2-1.

Рисунок 2-1. Пример ERD для базы данных книг

Как мы можем наблюдать, сущности представлены в виде белых прямоугольных блоков и обозначают реальные объекты или концепции, такие как «Книга» или «Автор».

Связи представлены в виде ромбов и показывают, как сущности связаны друг с другом.

Атрибуты представлены в виде затенённых блоков и описывают свойства или характеристики сущности. Примером могут быть «Имя» или «Дата публикации». Кроме того, атрибуты можно классифицировать как ключевые атрибуты (подчёркнутые затенённые блоки), которые уникально идентифицируют сущность, или как неключевые атрибуты (неподчёркнутые затенённые блоки), которые предоставляют дополнительную информацию о сущности. Существуют и другие типы атрибутов при проектировании таких диаграмм, но мы ограничимся основами.

Другие компоненты в ERD включают кардинальность и ограничения участия. Кардинальность определяет количество экземпляров в связи, обычно обозначается символами, такими как 1, M или N, чтобы указать, является ли связь «один-к-одному» или «один-ко-многим». (N указывает на неопределённое количество связей.)

Логическая фаза моделирования

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

Эта фаза может быть разделена на два шага.

Сначала реструктуризация схемы «сущность-связь» фокусируется на оптимизации схемы на основе определённых критериев. Этот шаг не привязан к какой-либо конкретной логической модели.

На втором этапе оптимизированная ERD переводится в конкретную логическую модель.

Предположим, мы решили сопоставить ERD с реляционной моделью базы данных (что будет нашим случаем), в отличие от документационной или графовой базы данных. В этом случае каждая сущность из концептуального упражнения ERD представлена в виде таблицы. Атрибуты каждой сущности становятся столбцами соответствующей таблицы. Ограничение первичного ключа указывается для столбцов, являющихся первичными ключами каждой таблицы. Кроме того, связи «многие-ко-многим» представлены отдельными промежуточными таблицами, которые содержат внешние ключи, ссылающиеся на соответствующие сущности.

Переводя концептуальное упражнение ERD в логическую схему с использованием реляционной модели, мы создаём структурированное представление сущностей, их атрибутов и их связей. Эта логическая схема может стать основой для реализации базы данных в конкретной системе управления базами данных (DBMS), оставаясь независимой от какой-либо конкретной системы.

Чтобы выполнить этот перевод эффективно, применяются все шаги нормализации, но мы хотим поделиться эффективным алгоритмом:

  1. Сущность E преобразуется в таблицу T.
  2. Имя E становится именем T.
  3. Первичный ключ E становится первичным ключом T.
  4. Простые атрибуты E становятся простыми атрибутами T.

Что касается связей, можно выделить несколько шагов:

Связи N:1

В таблице T1 определяется внешний ключ, который ссылается на первичный ключ таблицы T2. Это устанавливает связь между двумя таблицами, указывая на отношение N:1. Атрибуты (Attrs), связанные с этой связью, отображаются и включаются в таблицу T1.

Связи N:N

Создаётся специальная таблица перекрёстных ссылок для представления связи REL. Первичный ключ REL определяется как комбинация первичных ключей обеих таблиц T1 и T2, которые выступают в роли внешних ключей в таблице перекрёстных ссылок. Атрибуты (Attrs), связанные с этой связью, отображаются и включаются в таблицу перекрёстных ссылок.

Теперь давайте применим эти правила к нашему предыдущему концептуальному модели; см. Рисунок 2-2.

Рисунок 2-2. Пример логической ERD для базы данных книг

В нашем примере мы имеем несколько сущностей, которые, как предполагает наш алгоритм, напрямую сопоставляются с таблицами. Это относится к «Авторам», «Книгам» и «Категории».
Мы определили отношение 1:N между «Книгами» и «Категорией», где одна книга принадлежит одной категории, но одна категория может содержать несколько книг. Для отображения этого отношения мы создаём внешний ключ в таблице «Книги», чтобы он ссылался на соответствующую категорию.

У нас также есть отношение N:N. В этом случае мы должны создать новую таблицу (таблицу перекрёстных ссылок), которая хранит это отношение. В нашем случае мы создаём таблицу «Publishes» (Публикации), для которой первичный ключ становится составным, объединяющим связанные сущности (ID книги и ID автора). Одновременно атрибуты связи становятся атрибутами этой таблицы перекрёстных ссылок.

Физическая фаза моделирования

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

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

В нашем случае мы продолжаем с предыдущей логической модели и предполагаем, что будем работать с MySQL. Пример 2-1 демонстрирует физическую модель базы данных для книг.

Пример 2-1. База данных для книг в физической модели

В Примере 2-1 мы создали четыре таблицы:

  1. category (категории),
  2. books (книги),
  3. authors (авторы) и
  4. publishes (публикации).

Аспект физического дизайна уточняет структуру таблиц, типы данных и ограничения, чтобы соответствовать системе базы данных MySQL.

Например, в таблице category мы можем указать тип данных для столбца category_id как INT, что обеспечивает его пригодность для хранения целочисленных значений. Этот столбец также определяется как первичный ключ, так как он идентифицирует уникальные записи в таблице. Аналогично, столбец category_name может быть определён как VARCHAR(255) для размещения строк с переменной длиной, представляющих названия категорий.

В таблице books можно назначить соответствующие типы данных и длины для таких столбцов, как book_id (INT), ISBN (VARCHAR(13)), title (VARCHAR(50)) и summary (VARCHAR(255)). Кроме того, столбец category_id может быть настроен как внешний ключ, ссылающийся на столбец category_id в таблице category. Обратите внимание, что каждый ISBN-код состоит из строк длиной 13 символов, поэтому для хранения большего количества символов нет необходимости.

Аналогично, в таблице authors можно определить типы данных для столбцов author_id (INT), author_name (VARCHAR(255)) и date_birth (DATETIME), все они соответствуют ожидаемым типам значений.

В таблице publishes мы отмечаем, что установили ограничения внешнего ключа для создания связей между столбцом book_id в таблице books и столбцом author_id в таблице authors. При этом внешний ключ состоит из первичных ключей двух таблиц, которые он связывает.

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

Процесс нормализации данных

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

Пример 2-2. Таблица books для нормализации

Первым шагом нормализации, известным как первая нормальная форма (1NF), является устранение повторяющихся групп путём разбиения данных на более мелкие атомарные единицы. Мы создаём таблицу authors, включающую идентификатор автора и его имя. Таблица books теперь ссылается на идентификатор автора вместо того, чтобы многократно хранить полное имя, как показано в Примере 2-3.

Пример 2-3. Таблица books в 1NF

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

Чтобы соответствовать 2NF, мы разделяем таблицу books на три таблицы:

  • books, содержащую идентификатор книги и название.
  • authors, содержащую идентификатор автора и его имя.
  • bookDetails, хранящую идентификатор книги, год публикации и жанр.

Это гарантирует, что каждый столбец зависит исключительно от первичного ключа, как показано в Примере 2-4.

Пример 2-4. Таблица books во 2NF

Третья нормальная форма (3NF) сосредотачивается на устранении транзитивных зависимостей. Мы осознаём, что жанр можно вывести из идентификатора книги через таблицу bookDetails. Чтобы решить эту проблему, мы создаём новую таблицу genres с идентификатором жанра и его названием. Таблица bookDetails теперь ссылается на идентификатор жанра вместо того, чтобы напрямую хранить название жанра (Пример 2-5).

Пример 2-5. Таблица books в 3NF

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

Важно отметить, что при необходимости можно применять дополнительные шаги нормализации, такие как четвёртая нормальная форма (4NF) и пятая нормальная форма (5NF), чтобы устранить сложные зависимости данных и обеспечить ещё более высокий уровень целостности данных.

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

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

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

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

Однако парадигма несколько отличается, когда речь идёт о проекте или системе аналитики. Часто пользователи хотят иметь возможность получать необходимые данные без необходимости выполнения множества соединений, что является естественным следствием процесса нормализации. В то время как система OLTP оптимизирована для операций записи, чтобы избежать увеличения задержки в таких живых системах, как веб-приложения, пользователи аналитических систем хотят оптимизации операций чтения, чтобы как можно быстрее получать аналитические данные.

В отличие от нормализованных транзакционных баз данных, которые хранят живые данные, аналитические базы данных, как ожидается, содержат как данные в реальном времени, так и не в реальном времени, а также выступают в качестве исторического архива для прошлых данных. Часто аналитическая база данных ожидает интеграции данных из нескольких OLTP-систем для предоставления объединённого представления бизнес-процессов.

Эти различия действительно критически важны для понимания, так как они лежат в основе различных требований к организации, хранению и использованию данных. Однако важно уточнить, что то, что мы только что изучили, относится главным образом к области нормализации для оптимизации производительности и соблюдения лучших практик в проектировании баз данных OLTP. Хотя эта основа ценна, она представляет собой лишь одну грань более широкой области аналитической инженерии.

Чтобы предоставить более чёткий план, давайте определим, что наше путешествие начинается с изучения базового типа моделирования данных, который составляет основу систем OLTP. После этого мы перейдём к обсуждению подходов к моделированию данных, оптимизированных для среды OLAP. Разграничивая эти аспекты, мы стремимся обеспечить всестороннее понимание обеих сторон моделирования данных, что подготовит нас к более глубокому изучению методов аналитической инженерии и их применения в последующих разделах.

Моделирование данных в разрезе измерений (Dimensional Data Modeling)

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

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

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

Для понимания моделирования данных в разрезе измерений стоит отдать должное двум личностям, считающимся отцами хранилищ данных и этого подхода: Биллу Инмону и Ральфу Кимболлу. Они признаны пионерами в области корпоративного сбора информации, управления и аналитики для поддержки принятия решений.

Инмон против Кимболла: подходы к хранилищам данных

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

Инмон предлагает создание централизованного хранилища данных, охватывающего всё предприятие, с целью создания комплексной BI-системы.

В то время как Кимболл предлагает создание множества небольших витрин данных (data marts), ориентированных на конкретные отделы, что позволяет проводить анализ и составлять отчёты на уровне департаментов.

Их противоположные точки зрения приводят к различным техникам проектирования и стратегиям внедрения хранилищ данных.

Помимо различных подходов, Инмон и Кимболл предлагают отличающиеся методы структурирования данных в контексте хранилищ данных. Инмон выступает за использование реляционной модели (ERD), в частности, третьей нормальной формы (3NF), для корпоративного хранилища данных. В то время как подход Кимболла использует многомерную модель в измерительном хранилище данных с применением звёздных и снежиноковых схем.

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

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

Звёздная схема, снежинка и Data Vault

В следующих разделах мы углубимся в три техники моделирования: звёздную схему, снежинку и новую модель Data Vault. Data Vault, представленная Дэном Линстедтом в 2000 году, набирает популярность в последние годы. Эта модель следует более нормализованной структуре, которая не полностью совпадает с подходом Инмона, но является похожей.

Моделирование с использованием звёздной схемы

Звёздная схема является широко используемым подходом к моделированию в реляционных хранилищах данных, особенно для аналитики и составления отчётов. Этот подход включает классификацию таблиц как таблиц измерений (dimension tables) или таблиц фактов (fact tables) для эффективной организации и представления бизнес-единиц и связанных наблюдений или событий.

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

Таблицы фактов, напротив, хранят наблюдения или события, происходящие в бизнесе. Это могут быть заказы на продажу, уровни запасов, валютные курсы, температуры и другие измеряемые данные. Таблица фактов содержит ключевые столбцы измерений, которые ссылаются на таблицы измерений, а также числовые столбцы измерений. Ключевые столбцы измерений определяют размерность таблицы фактов и указывают, какие измерения включены в анализ. Например, таблица фактов, которая хранит данные о целях продаж, может содержать ключевые столбцы измерений для Date и ProductKey, что означает, что анализ включает измерения, связанные с временем и продуктами.

Гранулярность таблицы фактов определяется значениями в её ключевых столбцах измерений. Если, например, столбец Date в таблице фактов для целей продаж содержит значения, представляющие первый день каждого месяца, то гранулярность таблицы находится на уровне Месяц/Продукт. Это означает, что таблица фактов фиксирует данные о целях продаж на ежемесячном уровне, специфичном для каждого продукта.

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

Возвращаясь к нашей таблице книг, мы следуем шагам моделирования для разработки простой модели звёздной схемы. Первый шаг — это идентификация таблиц измерений. Для начала вспомним нашу базовую таблицу в Примере 2-6.

Пример 2-6. Базовая таблица для звёздной схемы

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

Пример 2-7. Таблицы измерений для звёздной схемы

Когда речь идёт о наименовании таблиц измерений, рекомендуется использовать описательные и интуитивно понятные названия, которые отражают представляемые сущности. Например, если у нас есть таблица измерений, представляющая книги, её можно назвать dimBook или просто books. Аналогично, для таблиц измерений, представляющих авторов, жанры или другие сущности, можно использовать такие названия, как dimAuthor или dimGenre.

Для таблиц фактов рекомендуется использовать названия, указывающие на измерения или события, которые фиксируются. Например, если у нас есть таблица фактов, записывающая данные о продажах книг, её можно назвать factBookSales или salesFact. Эти названия показывают, что таблица содержит данные, связанные с продажами книг.

Мы можем создать таблицу фактов под названием factBookPublish, как показано в Примере 2-8, для фиксации данных о публикации.

Пример 2-8. Таблица фактов для звёздной схемы

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

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

Рисунок 2-3. Модель звёздной схемы

Использование этой модели

Теперь мы можем легко анализировать публикации книг, применяя фильтры, такие как жанр, автор или год публикации. Например, можно быстро получить общее количество публикаций для определённого жанра. Соединяя таблицы измерений с таблицей фактов, как показано в Примере 2-9, мы можем без труда получать информацию о взаимосвязях между книгами, авторами, жанрами и продажами.

Пример 2-9. Извлечение данных из звёздной схемы

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

Этот подход важен, поскольку учитывает возможность отсутствия соответствующих записей в каждой таблице измерений для каждой записи таблицы фактов. Используя LEFT JOIN, вы сохраняете все данные из таблицы фактов, одновременно дополняя их соответствующими атрибутами из таблицы измерений. Это позволяет выполнять анализ и агрегации на основе различных измерений и исследовать данные с разных точек зрения. Однако необходимо учитывать отсутствие соответствий, для чего часто используется оператор COALESCE, позволяющий установить значение по умолчанию, например, -1 или Not available.

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

Преимущества звёздной схемы

В целом, простота и денормализованная структура звёздной схемы делают её удобной для выполнения агрегаций и обобщений. С её помощью можно создавать различные отчёты, такие как анализ трендов продаж за период, самые популярные жанры или доходы по авторам. Также звёздная схема поддерживает операции детализации (drill-down) и свёртки (roll-up), что позволяет переходить к более детализированной информации или, наоборот, к более обобщённым данным для комплексного анализа.

Эта техника моделирования также отлично интегрируется с инструментами визуализации данных и платформами BI. Подключив модель к инструментам, таким как Tableau, Power BI или Looker, можно создавать наглядные дашборды и интерактивные отчёты. Такие ресурсы позволяют заинтересованным сторонам быстро извлекать инсайты и принимать решения на основе данных.

Уточнение модели

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

Моделирование с использованием снежинки

В схеме «Снежинка» (Snowflake Data Model) — модель данных более нормализована по сравнению со звёздной схемой. Она включает дополнительные уровни нормализации, разделяя таблицы измерений на несколько связанных таблиц. Это обеспечивает лучшую целостность данных и уменьшает избыточность.

Например, рассмотрим схему Снежинка для базы данных электронной коммерции. У нас есть таблица измерений customers, которая содержит информацию о клиентах, такую как идентификатор, имя и адрес. В схеме Снежинка эту таблицу можно разделить на несколько связанных таблиц.

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

Для извлечения данных из схемы Snowflake обычно требуется выполнить несколько соединений между связанными таблицами. Например, если нужно запросить имя клиента и адрес, необходимо объединить таблицы customers и addresses по идентификатору. Хотя Snowflake схема обеспечивает лучшую целостность данных, она также требует более сложных запросов из-за дополнительных связей.

Сравнение Star и Snowflake схем

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

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

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

Пример 2-10. Измерение местоположения в звёздной схеме

А в snowflake схеме иерархия местоположений будет разделена на несколько таблиц (Пример 2-11).

Пример 2-11. Измерение местоположения в схеме Снежинка

В примере схемы Снежинка

Измерение местоположения разделено на четыре таблицы:

  • dimLocation,
  • dimCity,
  • dimState и
  • dimCountry.

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

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

На Рисунке 2-4 показана эта схема.

Моделирование с использованием Data Vault

Data Vault 2.0 — это подход к моделированию, который не относится к измерительному моделированию, но заслуживает упоминания. Его методология сочетает элементы трёхзвенной нормальной формы (3NF) и dimensional modeling для создания логической корпоративной базы данных (EDW). Data Vault разработан для работы с различными типами данных, включая структурированные, полуструктурированные и неструктурированные, предоставляя гибкие и масштабируемые шаблоны.

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

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

Модель Data Vault состоит из трёх основных компонентов:

  • хабы (hubs),
  • связи (links) и
  • спутники (satellites).

Хабы (Hubs)

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

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

Связи (Links)

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

Спутники (Satellites)

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

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

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

Пример моделирования таблицы книг

Рассмотрим таблицу books и следуем трём этапам моделирования, чтобы разработать простую модель Data Vault.

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

В данном случае у нас есть только одна бизнес-сущность, поэтому связи использоваться не будут. Пример 2-12 демонстрирует моделирование таблицы книг с использованием Data Vault 2.0.

Пример 2-12. Моделирование таблицы книг с использованием Data Vault 2.0

В моделировании Data Vault мы начинаем с идентификации бизнес-ключей, которые являются уникальными идентификаторами для каждой сущности. В данном случае первичный ключ таблицы books, book_id, служит бизнес-ключом.

Теперь мы можем приступить к моделированию и созданию нашей первой таблицы: таблицы хаба, которая хранит уникальные бизнес-ключи и соответствующие им хэш-ключи для обеспечения стабильности. Пример 2-13 показывает создание таблицы хаба.

Пример 2-13. Создание хаба

В таблице хаба мы храним уникальный идентификатор для каждой книги в виде первичного ключа (bookKey) и хэш-ключа (bookHashKey) для обеспечения стабильности. Колонка Title содержит описательную информацию о книге.

Далее создаётся спутниковая таблица, представленная в Примере 2-14, которая фиксирует дополнительные детали о книгах и сохраняет историю изменений.

Пример 2-14. Создание спутника

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

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

Моделирование данных в монолитной архитектуре

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

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

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

  • отсутствие контроля версий для скриптов;
  • сложность управления зависимостями между представлениями (views);
  • практика создания новых представлений или таблиц от исходных данных до финальных отчетов, что затрудняет повторное использование;
  • несоответственное применение принципа идемпотентности для крупных таблиц, что иногда приводило к избыточности данных;
  • сложные и трудоёмкие процессы обратной загрузки (backfills).

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

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

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

Сложности монолитных моделей

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

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

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

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

Преимущества модульного подхода

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

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

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

Эта структура устраняет риск непреднамеренных изменений, влияющих на всю систему, и делает процесс внесения изменений и обновлений безопаснее. Тема модульности с использованием dbt будет более подробно рассмотрена в следующих подразделах, а в Главе 4 будет дано её детальное исследование.

Построение модульных моделей данных

Приведённый выше пример подчёркивает, насколько важны dbt и модульный подход к моделированию данных для улучшения процесса разработки. Однако почему это до сих пор не стало повсеместной практикой среди инженеров и учёных данных?

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

Преимущества модульного подхода

Улучшение управляемости

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

Поддержка командной работы

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

Повышение качества кода

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

Повторное использование кода

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

Организация и читаемость

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

Результат: надёжность и масштабируемость

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

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

Модульность в моделировании данных

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

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

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

В итоге основные принципы модульного моделирования данных можно сформулировать следующим образом:

Декомпозиция

Разделение модели данных на меньшие, более управляемые компоненты.

Абстракция

Сокрытие деталей реализации модели данных за интерфейсами.

Повторное использование

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

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

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

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

Возможные недостатки модульности

Несмотря на очевидные преимущества, модульность может иметь свои риски и недостатки:

  • Оптимизация интегрированных систем: Интегрированные системы часто можно оптимизировать лучше, чем модульные, благодаря минимизации перемещения данных, снижению использования памяти и возможностям оптимизатора базы данных улучшать SQL на уровне базы данных. Например, создание таблиц из представлений может приводить к неоптимальным моделям.
  • Увеличение количества объектов: Модульность создаёт больше файлов, что означает больше объектов для управления, сопровождения и, возможно, вывода из эксплуатации. Без зрелой стратегии управления данными это может привести к хаосу, связанному с множеством модульных, но неуправляемых таблиц, которые становится сложно поддерживать при возникновении проблем.

Реализация модульных моделей данных с помощью dbt

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

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

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

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

Как показано на Рисунке 2-5, использование базовых моделей данных в различных сценариях, вместо того чтобы каждый раз начинать с нуля, упрощает визуализацию DAG (ориентированного ациклического графа) при моделировании данных. Модульная многоуровневая структура делает понятной логику построения уровней моделей данных и их зависимости.

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

Рисунок 2-5. Модульность в dbt

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

Эти принципы можно применять к различным моделям в dbt, включая модели подготовки (staging models), промежуточные модели (intermediate models) и модели для визуализации данных (mart models), чтобы улучшить модульность и поддерживать хорошо структурированный DAG.

Начнём путь к использованию dbt для создания модульных моделей данных с понимания того, как dbt обеспечивает повторное использование моделей через синтаксис Jinja с использованием ссылки на модели: {{ ref() }}.

Ссылки на модели данных

Используя функции dbt, такие как ссылки на модели (model referencing) и синтаксис Jinja, инженеры данных и аналитики могут устанавливать чёткие зависимости между моделями, повышать повторное использование кода и обеспечивать согласованность и точность своих конвейеров обработки данных.

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

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

Для того чтобы максимально использовать возможности dbt и обеспечить точное построение моделей, важно применять ссылки на модели с помощью синтаксиса {{ ref() }}. Используя этот способ, dbt может автоматически определять и устанавливать зависимости между моделями на основе вышестоящих таблиц. Это обеспечивает плавное и надёжное выполнение конвейера преобразования данных.

С другой стороны, синтаксис Jinja {{ source() }} следует использовать экономно, обычно ограничиваясь первоначальным выбором сырых данных из базы данных. Важно избегать прямых ссылок на таблицы, созданные не с помощью dbt, так как это может затруднить гибкость и модульность рабочего процесса dbt.

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

Пример: работа с ссылками на модели

Допустим, у нас есть две модели: orders и customers, где таблица orders содержит информацию о заказах клиентов, а таблица customers — данные о клиентах. Мы хотим выполнить объединение этих двух таблиц, чтобы обогатить данные заказов информацией о клиентах (Пример 2-15).

Пример 2-15. Ссылки на модели

Этот пример демонстрирует, как ссылаться на модели в SQL-запросе с использованием функции ref().

Сценарий включает два файла моделей: orders.sql и customers.sql.

В файле orders.sql записан оператор SELECT, чтобы извлечь информацию о заказах из модели orders. Выражение {{ ref('orders') }} создаёт ссылку на модель orders, позволяя запросу использовать данные, определённые в этой модели.

Запрос объединяет модель orders с моделью customers по столбцу customer_id, извлекая дополнительную информацию о клиентах, такую как имя и электронная почта.

В файле customers.sql

Оператор SELECT используется для извлечения информации о клиентах из таблицы raw_customers. Эта модель представляет необработанные данные о клиентах до выполнения каких-либо преобразований.

Этот механизм ссылок в dbt позволяет создавать модульные и взаимосвязанные модели, которые основываются друг на друге для получения значимых аналитических выводов и отчётов.

Чтобы показать необходимость такого подхода, представим практический пример: вы работаете со сложным набором данных, таким как еженедельные заказы продуктов. Без структурированного подхода управление такими данными быстро становится хаотичным. Вы можете столкнуться с запутанной сетью SQL-запросов, что затруднит отслеживание зависимостей, сопровождение кода и обеспечение точности данных.

Преимущества структурированного подхода

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

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

Слой промежуточных данных (Staging Data Models)

Слой промежуточных данных (или стейджинг) играет ключевую роль в моделировании данных, поскольку служит основой для модульного построения более сложных моделей данных. Каждая staging модель данных соответствует исходной таблице с отношением 1:1 к оригинальному источнику данных.

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

Допустимыми являются такие преобразования, как:

  • Преобразование типов данных,
  • Переименование столбцов,
  • Простые вычисления (например, преобразование единиц измерения),
  • Классификация с использованием условных операторов, таких как CASE WHEN.

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

Избежание сложных операций

Соединения (Joins): избегайте их на уровне staging, чтобы предотвратить избыточные или дублирующие вычисления. Соединения лучше выполнять на последующих слоях, где устанавливаются более сложные отношения.

Агрегации: их также следует избегать, так как они могут группировать данные и ограничивать доступ к ценным исходным данным.

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

Использование принципа DRY

Применение моделей staging данных в dbt позволяет использовать принцип «Don’t Repeat Yourself» (DRY) в коде. Следуя модульной и повторно используемой структуре dbt, мы стараемся переносить все преобразования, которые часто требуются для определённой модели, как можно ближе к источнику.

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

Пример промежуточной модели данных (staging data model)

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

В нашем проекте dbt можно создать новый файл модели dbt под названием stg_books.sql и определить логику для создания модели подготовки, как показано в Примере 2-16.

Пример 2-16. Модель промежуточных данных (Staging model)

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

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

Базовые модели данных (Base Data Models)

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

После создания staging моделей или базовых моделей другие модели в вашем проекте dbt могут ссылаться на них.

Изменение термина с base на staging модели в документации dbt отражает стремление не ограничиваться названием «base», которое подразумевает первый шаг в создании модели данных. Новая терминология обеспечивает большую гибкость в описании роли и цели этих моделей в рамках dbt.

Промежуточные/средние модели данных (Intermediate Data Models)

Промежуточный слой (intermediate layer) играет важную роль в моделировании данных, объединяя атомарные строительные блоки из слоя подготовки для создания более сложных и значимых моделей.

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

Чтобы сохранить разделение и оптимизировать производительность, рекомендуется хранить промежуточные модели в виде эфемерных моделей (ephemeral models). Эфемерные модели не создаются напрямую в базе данных или наборе данных, а их код вставляется в модели, которые ссылаются на них, как общее выражение таблицы (CTE — Common Table Expressions).

Иногда предпочтительнее материализовать их как представления (views). Однако стоит учитывать, что эфемерные модели невозможно выбрать напрямую, что затрудняет отладку. Кроме того, макросы, вызываемые через run-operation, не могут ссылаться на эфемерные модели.

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

Организация промежуточных моделей

Если вы решаете материализовать Intermediate модели как представления, полезно размещать их в пользовательской схеме за пределами основной схемы, указанной в вашем профиле dbt. Это помогает эффективно организовать модели и управлять правами доступа.

Основная цель Intermediate слоя — объединить различные сущности и упростить сложность итоговых моделей. Эти модели улучшают читаемость и гибкость общей структуры модели данных.

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

Эффективное использование промежуточного слоя

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

Предположим, у нас есть две модели подготовки данных, stg_books и stg_authors, представляющие данные о книгах и авторах соответственно. Теперь мы хотим создать промежуточную модель под названием int_book_authors, которая объединяет соответствующую информацию из обеих подготовительных моделей.

В нашем проекте dbt мы можем создать новый файл модели dbt под названием int_book_authors.sql, как показано в Примере 2-17, и определить логику для создания промежуточной модели.

Пример 2-17. Intermediate model

В Примере 2-17 модель int_book_authors ссылается на модели подготовки данных stg_books и stg_authors, используя синтаксис {{ ref() }} Jinja. Это гарантирует, что dbt сможет правильно определить зависимости модели и построить промежуточную модель на основе вышестоящих таблиц.

Модели витрин данных (Mart Models)

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

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

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

Рассмотрим пример витрины данных для анализа публикаций книг. У нас есть промежуточная модель int_book_authors, которая содержит необработанные данные о книгах, включая информацию об авторах каждой книги (Пример 2-18).

Пример 2-18. Модель витрины данных

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

Далее мы используем CTE под названием book_counts для агрегации данных о книгах. Мы выбираем столбец author_id и подсчитываем количество книг, связанных с каждым автором, из модели подготовки данных stg_books. В заключение, оператор SELECT извлекает агрегированные данные из CTE book_counts, возвращая author_id и соответствующее количество книг для каждого автора. Поскольку это материализованная таблица, модель может обновляться при необходимости, чтобы отразить изменения в исходных данных.

Тестирование моделей данных

Тестирование в dbt — важный аспект обеспечения точности и надёжности моделей данных и источников данных. dbt предоставляет комплексную структуру тестирования, позволяющую определять и выполнять тесты с использованием SQL-запросов. Эти тесты предназначены для выявления строк или записей, не соответствующих заданным критериям утверждений, а не для проверки корректности конкретных условий.

В dbt существует два основных типа тестов: единичные (singular) и общие (generic). Единичные тесты представляют собой специфические, целенаправленные тесты, написанные в виде SQL-запросов и хранящиеся в отдельных файлах SQL. Они позволяют проверять определённые аспекты ваших данных, такие как отсутствие NULL-значений в таблице фактов или валидацию определённых преобразований данных. Используя единичные тесты, можно задействовать мощь Jinja для динамического определения утверждений на основе данных и бизнес-требований.

Рассмотрим единичный тест в dbt, анализируя Пример 2-19.

Пример 2-19. Пример единичного теста в dbt

В этом примере мы определяем единичный тест под названием not_null_columns для модели dbt my_model. Этот тест проверяет, содержат ли определённые столбцы модели значения NULL. Параметр columns указывает столбцы для проверки на наличие NULL-значений. В данном случае указаны column1 и column2. Если какой-либо из этих столбцов содержит значения NULL, тест завершается с ошибкой.

С другой стороны, общие тесты (generic tests) более универсальны и могут быть применены к нескольким моделям или источникам данных. Они определяются в файлах проекта dbt с использованием специального синтаксиса. Эти тесты позволяют задавать более комплексные критерии проверки данных, такие как проверка консистентности данных между таблицами или обеспечение целостности определённых столбцов. Они обеспечивают гибкий и повторно используемый способ определения утверждений, которые могут быть применены ко всем моделям dbt. Общие тесты пишутся и хранятся в файлах YAML (.yml), что позволяет параметризовать запросы и легко использовать их в различных контекстах.

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

Рассмотрим один из таких общих тестов в Примере 2-20.

Пример 2-20. Пример общего теста в dbt

В этом примере общий тест определён под названием non_negative_values. Здесь указаны столбцы для проверки и критерии утверждения для каждого столбца. Тест проверяет, являются ли значения в столбцах amount и quantity неотрицательными. Общие тесты позволяют написать повторно используемую логику тестирования, которая может быть применена ко многим моделям в вашем проекте dbt.

Чтобы повторно использовать общий тест в нескольких моделях, мы можем ссылаться на него в разделе tests каждого отдельного YAML-файла модели, как показано в Примере 2-21.

Пример 2-21. Повторное использование общего теста

В этом примере определена модель my_model, а столбцы amount и quantity указаны с соответствующими тестами. Тесты ссылаются на общий тест non_negative_values из пространства имён my_project (предполагается, что my_project — это имя вашего проекта dbt).

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

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

Генерация документации данных

Ещё одним важным компонентом правильного моделирования данных является документация. В частности, обеспечение того, чтобы все в вашей организации, включая бизнес-пользователей, могли легко понимать и получать доступ к метрикам, таким как ARR (ежегодный повторяющийся доход), NPS (индекс потребительской лояльности) или MAU (ежемесячное количество активных пользователей), является ключевым для принятия решений на основе данных.

Используя возможности dbt, мы можем документировать, как определяются такие метрики и на каких исходных данных они основаны. Эта документация становится ценным ресурсом, доступным для всех, способствуя прозрачности и упрощая самостоятельное исследование данных.

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

Предположим, у нас есть проект dbt с моделью nps_metrics.sql, которая вычисляет индекс потребительской лояльности. Мы можем легко задокументировать эту метрику, используя комментарии внутри SQL-файла, дополненные синтаксисом Markdown, как показано в Примере 2-22.

В этом примере комментарии предоставляют важную информацию о метрике NPS. Они указывают зависимости модели nps_metrics, объясняют процесс расчёта и упоминают соответствующие таблицы, используемые в запросе.

После документирования модели мы можем сгенерировать документацию для нашего проекта dbt, используя интерфейс командной строки dbt (CLI) и выполнив следующую команду (Пример 2-23).

Пример 2-23. Генерация документации

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

Отладка и оптимизация моделей данных

Ценное предложение по оптимизации производительности dbt заключается в тщательном анализе и оптимизации самих запросов. Один из подходов — использовать возможности планировщика запросов, например, планировщика PostgreSQL (Postgres). Понимание работы планировщика запросов помогает выявить возможные узкие места и неэффективности в выполнении запросов.

Другим эффективным методом оптимизации является деконструкция сложных запросов, разбивая их на более мелкие компоненты, такие как CTE (общие табличные выражения). В зависимости от сложности и природы операций, эти CTE затем могут быть преобразованы либо в представления (views), либо в таблицы (tables). Для каждой операции можно задать желаемый способ материализации с помощью блока config в dbt.

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

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

Рассмотрим сложный запрос в Примере 2-24.

Этот запрос включает объединение таблиц, применение фильтров и выполнение агрегаций. Деконструируем его на несколько CTE перед созданием финальной модели (Пример 2-25).

Пример 2-25. Деконструкция сложного запроса 1

CTE join_query фокусируется на объединении необходимых таблиц, в то время как filter_query применяет условия фильтрации для сужения выборки строк. aggregate_query выполняет агрегацию и применяет финальное условие фильтрации.

Разбив сложный запрос на отдельные CTE, вы можете упростить и организовать логику для оптимизации выполнения. Такой подход улучшает читаемость, сопровождаемость и потенциально повышает производительность, так как СУБД может оптимизировать план выполнения для каждого CTE. Финальный запрос извлекает оптимизированные результаты, выбирая столбцы из CTE aggregate_query.

Процесс отладки материализованных моделей в dbt

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

Для упрощения отладки и проверки может потребоваться полное обновление всей таблицы, чтобы обработать её как нематериализованную. Это можно сделать с помощью команды dbt run --full-refresh, которая обновляет таблицу и запускает модель как при её первом выполнении.

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

Рассмотрим пример: у нас есть материализованная модель dbt, которая рассчитывает ежемесячную выручку на основе данных транзакций. Чтобы отладить и проверить эту модель, мы подозреваем, что значения, генерируемые материализованной моделью, могут не соответствовать ожидаемым результатам. Для устранения этой проблемы мы решаем полностью обновить таблицу, как если бы она не была инкрементальной. Используя команду dbt run --full-refresh, мы запускаем процесс, обновляющий всю таблицу и выполняющий модель с нуля.

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

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

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

Архитектура медальонов (Medallion Architecture Pattern)

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

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

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

Lakehouse

Lakehouse сочетает преимущества озёр данных и хранилищ данных, реализуя структуры данных и функции управления, характерные для хранилищ, непосредственно на экономически эффективном облачном хранилище в открытых форматах, таких как Apache Delta Lake, Iceberg или Apache Hudi. Эти форматы имеют ряд преимуществ перед традиционными форматами файлов, такими как CSV и JSON.

  • CSV: не поддерживает типизацию столбцов.
  • JSON: предлагает гибкость структуры, но отличается непоследовательной типизацией.
  • Parquet, Apache Avro, ORC: улучшают ситуацию, будучи колоночными и более строго типизированными, но не всегда соответствуют требованиям ACID (атомарность, согласованность, изолированность, долговечность).

Delta Lake, Iceberg и Hudi добавляют поддержку ACID и возможность служить двусторонними хранилищами данных, обеспечивая высокую пропускную способность модификаций и поддерживая большие объёмы аналитических запросов. Эти форматы особенно хорошо подходят для современных облачных систем обработки данных в отличие от Parquet, изначально разработанного для локальных систем на базе Hadoop.

Преимущества Lakehouse

  1. Поддержка транзакций: одновременное чтение и запись данных.
  2. Применение схем и управление: обеспечение согласованности данных.
  3. Прямая поддержка BI-инструментов.
  4. Разделение хранения и вычислений: масштабируемость.
  5. Открытость: стандартизированные форматы хранения и API для эффективного доступа.
  6. Поддержка различных типов данных: от структурированных до неструктурированных.
  7. Совместимость с разными нагрузками: машинное обучение, аналитика SQL, наука о данных.
  8. Возможности потоковой обработки: исключение необходимости в отдельных системах для приложений реального времени.

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

Архитектура медальонов

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

Архитектура обычно включает три уровня:

  • бронзовый,
  • серебряный и
  • золотой,

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

Бронзовый уровень (Bronze layer)

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

Серебряный уровень (Silver layer)

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

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

Золотой уровень (Gold layer)

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

Рисунок 2-6. Представление архитектуры медальонов и её связь с dbt

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

Дополнительные замечания

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

Роль аналитиков-инженеров

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

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

Итог

Моделирование данных значительно эволюционировало в области аналитики для удовлетворения разнообразных бизнес-запросов и требований к отчётности.

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

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

Эти усовершенствования направлены на решение определённых аналитических задач, будь то повышение производительности звёздной и снежинки, или гибкость Data Vault. По мере усложнения требований аналитики становится всё более важным выбирать правильный подход к моделированию данных, чтобы не только сделать их доступными, но и обеспечить их осмысленность и полезность для анализа.

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

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x