Основой для зарождения медленно изменяющиеся измерений стала модель — Звездная схема (star schema), которая была представлена в 1996 году Ральфом Кимболлом в его книге «The Data Warehouse Toolkit». Новая методика моделирования, предложенная Кимболлом, позволила сократить объем данных, хранящихся в хранилище данных, а также повысить производительность запросов.
В звездной схеме данные хранятся в виде таблиц фактов и таблиц измерений. Таблицы фактов содержат данные, которые фиксируют события, такие как транзакции в розничном магазине, бронирование гостя в отеле или посещения пациентов врача. Таблицы измерений хранят информацию, которая обогащает данные в таблицах фактов.
Примеры:
Факт |
Измерение |
Транзакции в розничном магазине |
Подробная информация о каждом проданном товаре в этом магазине |
Бронирование гостя в отеле |
Этаж, количество кроватей, ванных комнат для всех номеров в отеле |
Посещения пациентов врача |
Информация о пациенте, такая как адрес и номер телефона |
В то время как таблицы фактов постоянно изменяются, отражая бизнес-события, таблицы измерений изменяются не так часто. Но что происходит, когда они все же изменяются? Что, если измерение изменяется несколько раз? Как сохраняются исторические данные?
Здесь на помощь приходят медленно изменяющиеся измерения (Slowly Changing Dimensions, SCD).
Пример - модель данных о продажах
Модель данных о продажах можно создать с помощью звёздной схемы для отслеживания показателей продаж, таких как выручка, количество проданных товаров и прибыль. Фактическая таблица будет содержать данные о продажах, а таблицы измерений будут предоставлять контекст, например, по продуктам, клиентам, времени и географии.

Более подробно:
-
Таблица Фактов: Sales (Столбцы: SaleID, ProductID, DateID, StoreID, CustomerID, StateID, Revenue)
-
Таблицы измерений:
-
Таблицы, связанные с товарами:
-
Product (Столбцы: ProductID, ProductName, CategoryID, BrandID, Price)
-
Category (Столбцы: CategoryID, CategoryName, ParentCategoryID)
-
Brand (Столбцы: BrandID, BrandName, ManufacturerID)
-
Manufacturer (Столбцы: ManufacturerID, ManufacturerName, Country)
-
-
Таблицы, связанные с датами:
-
Date (Столбцы: DateID, Date, DayOfWeek, MonthID)
-
Month (Столбцы: MonthID, MonthName, Quarter, Year)
-
-
Таблицы, связанные с магазином:
-
Store (Столбцы: StoreID, StoreName, LocationID, ManagerID, OpeningDate)
-
Location (Столбцы: LocationID, City, StateID, PostalCode)
-
Manager (Столбцы: ManagerID, ManagerName, ContactNumber)
-
-
Таблицы, связанные с клиентами:
-
Customer (Столбцы: CustomerID, CustomerName, Gender, AgeGroup, MembershipTypeID)
-
MembershipType (Столбцы: MembershipTypeID, MembershipLevel, DiscountRate)
-
-
Таблицы, связанные с состоянием:
-
State (Столбцы: StateID, StateName, CountryID, Region)
-
Country (Столбцы: CountryID, CountryName, Continent)
-
-
Медленно меняющиеся измерения (от англ. Slowly Changing Dimensions, SCD)
Это подход к обновлению и поддержке данных, хранящихся в таблицах измерений, по мере их изменения. Существует несколько различных методов обработки изменяющихся измерений, и эти методы обычно называются «типами» SCD.
Традиционно архитекторы данных и инженеры данных работают рука об руку, чтобы спланировать, разработать и поддерживать модель данных, которая использует медленно изменяющиеся измерения. Затем исследователи и аналитики данных используют эти таблицы фактов и измерений, составляющие звездную схему, для обучения ML-моделей, наполнения дашбордов или выполнения множества других задач, связанных с данными. В профессиональной среде данных понимание основ медленно изменяющихся измерений и того, как использовать такие данные, помогает сократить время получения аналитических выводов, повышая эффективность и надежность.
SCD Тип 0 (Неизменное измерение):
Для данного типа данных, какие-либо изменения отсутствуют. Данные сохраняют свою идентичность на протяжении всего времени их существования. К таким данным можно отнести: дни рождения, город рождения, почтовые индексы, ИНН, ОГРН, СНИЛС, коды регионов России, исторические события (например, дата основания города), математические константы (например, число π (пи) или число e), код валюты RUB и т.д.
SCD Тип 1 (Перезапись):
При использовании SCD Типа 1, если запись в таблице измерений изменяется, существующая запись обновляется или перезаписывается. В противном случае новая запись вставляется в таблицу измерений. Это означает, что записи в таблице измерений всегда отражают текущее состояние, и исторические данные не сохраняются.
Например, таблица, хранящая информацию о товарах, продаваемых в продуктовом магазине, может обрабатывать изменения записей с использованием SCD Типа 1. Если запись для определенного товара уже существует в таблице, она будет обновлена новой информацией.
Пример. Если картошку перенесу из торгового ряда 11 в торговый ряд 6, то в SCD Типа 1 запись с картошкой просто перезапишут с новыми данными:

SCD Тип 1 гарантирует, что в таблице не будет дублирующихся записей, и данные отражают самое актуальное состояние измерений. Это особенно полезно для реального времени (например, для дашбордов) и прогнозного моделирования, где важно только текущее состояние.
Однако, поскольку в таблице хранится только самая последняя информация, аналитики данных не могут сравнивать изменения измерений с течением времени. Например, аналитик данных не сможет определить, как изменилась выручка от продажи картошки после их перемещения в шестой торговый ряд, без дополнительной информации.
SCD Тип 1 упрощает отчетность и аналитику текущего состояния, но имеет ограничения при выполнении исторического анализа.
SCD Тип 2 (Добавление новой строки):
Хотя таблица, отражающая только текущее состояние, может быть полезной, бывают случаи, когда необходимо отслеживать исторические изменения измерений. В SCD Типе 2 исторические данные сохраняются путем добавления новой строки контроля изменении измерения, при этом новая строка помечается как текущая (True = 1), а предыдущая запись помечается как историческая (False = 0).
Пример:
Продолжая использовать таблицу продуктового магазина, мы добавим дополнительный столбец is_current, который хранит булево значение: true, если запись отражает текущее значение, и false в противном случае.
И если картошка так же, как и в случае рассмотрения примера SCD Типа 1, перемещается в 6-ой торговый ряд. При использовании SCD Типа 2 для фиксации этого изменения создадим таблицу, которая выглядит следующим образом:

Новая строка добавлена для отражения изменения местоположения картошки, при этом в столбце is_current установлено значение True. Чтобы сохранить исторические данные и точно отразить текущее состояние, в столбце is_current для предыдущей записи установлено значение False.
Но что, если вы хотите изучить, как изменились продажи картошки после изменения их местоположения? Это довольно сложно сделать, используя только один столбец, если для одного товара есть несколько исторических записей. К счастью, есть простой способ это сделать.
Для этого, мы возьмем таблицу измерений содержащую ту же информацию, что и раньше. Но вместо столбца is_current, добавим в неё столбцы start_date и end_date. Эти даты представляют период времени, в течение которого измерение было актуальным. Поскольку данные в этой таблице самые свежие, end_date установлен далеко в будущем.
Если картошка переместилась в ряд 6, 4 января 2025 года, обновленная таблица будет выглядеть так:

Обратите внимание, что end_date для первой строки обновлен до последнего дня, когда картошка находилась в проходе 11. Новая запись добавлена, и теперь картошка находится в проходе 6. Столбцы start_date и end_date помогают показать, когда произошло изменение, и обозначить, какая запись является текущей.
Использование этой техники для реализации SCD Типа 2 не только сохраняет исторические данные, но и предоставляет информацию о том, когда данные изменились. Это позволяет аналитикам данных изучать операционные изменения, проводить A/B-тестирование и принимать обоснованные решения.
SCD Тип 3 (Добавление нового атрибута):
В случаях, когда количество изменений измерений предопределено и неизменно, и по большому счету изменятся только один раз. Или, когда нам необходимо представлять только последнюю историческую запись, SCD Тип 3 оказывается весьма полезным. Вместо обновления измерения или хранения изменения в виде новой строки, SCD Тип 3 использует столбец для отражения изменения. Это немного сложно объяснить, поэтому давайте сразу перейдем к примеру.
В таблице ниже содержится информация о спортивных командах по всей территории России. Здесь таблица содержит два столбца для хранения текущего и предыдущего названия стадиона. Поскольку каждая из этих команд использует оригинальное название стадиона, столбец previous_stadium_name заполнен значениями NULL.
Если команда Спартак Москва решает заключить новый спонсорский контракт на 25 лет, обновленная таблица будет выглядеть следующим образом:

Чтобы учесть новое название стадиона, «Открытие Арена» перемещается в столбец previous_stadium_name, а «Газпром Арена» занимает его место в столбце current_stadium_name. Новый спонсорский контракт, рассчитанный на 25 лет, скорее всего, переживет модель, которая строится, а значит, запись вряд ли изменится снова.
Использование SCD Типа 3 делает сравнение текущих данных с историческими довольно простым. Для каждой команды существует только одна строка, а текущие и исторические данные находятся рядом в двух разных столбцах. Однако это означает, что можно сохранить только одну историческую запись для одного атрибута измерения, что может быть ограничением, особенно если данные изменяются чаще, чем ожидалось.
SCD Тип 4 (Таблица истории):
Четвертый тип больше схож с вторым типом, где мы так же хранили историю измерений в рамках одной таблицы, добавляя в измерение другую версию строки. Однако если изменения происходят быстро, SCD 2-го типа будет формировать множество лишних записей создавая трудности для масштабирования. Этот метод похож на методы сбора данных об изменениях и таблицы аудита баз данных.
На примере все той же таблицы продуктового магазина, для обработки изменений записей с использованием SCD Типа 4. Мы создадим дополнительную таблицу, в которую будут поступать все изменения. А в основной таблице будут находиться строго актуальные данные:

В этом методе быстро меняющийся столбец удаляется из измерения и переносится в новую таблицу измерений. Как видите в таблице с историей мы фиксируем факт изменений, со старой и новой ценой на товар, а также дату изменения:
Приведённая выше реализация медленно изменяющихся измерений 4-го типа в хранилище данных позволяет устранить ненужный объём в основном измерении. И при этом вы по-прежнему можете выполнять необходимый анализ.
SCD Тип 5 (Комбинированный подход) :
Гибридный подход, который сочетает в себе SCD Тип 4 с использование отдельной таблицы для хранения исторических изменений и SCD Тип 1 для ведения вспомогательных данных.
Для примера SCD Типа 5 рассмотрим вариант с таблицей продуктового магазина в которой мы отразим два типа:
-
SCD Тип 1 для отслеживания изменений стоимости.
-
SCD Тип 4 для хранения исторических сведений.
Продолжая работу на все той же таблицей продуктового магазина, допустим мы хотим не только вести таблицу с историей, но и сразу видеть сколько раз изменялась цена на данный товар. Для этого в таблицу с фактами мы добавим дополнительный столбец с отображением текущей версии цены, который будет перезаписывать каждый раз при ее изменении и переносе в таблицу с историей:

SCD Тип 6 (Комбинированный подход):
Это гибридный подход, сочетающий в себе все три основных метода SCD, отсюда и название 1+2+3 = 6. Тип 6 особенно удобен, если вы хотите сохранить полную историю, как в случае с типом 2, а также иметь простой способ повлиять на текущую версию, как в случае с типом 3.
Для примера SCD Типа 6 рассмотрим вариант с таблицей сотрудников компании в которой мы отразим три типа:
-
SCD Тип 2 для отслеживания изменений должности.
-
SCD Тип 3 для хранения текущего отдела.
-
SCD Тип 1 для обновления текущего отдела.
И для начала мы поменяем должность сотрудника Ивана с "Менеджер" на "Старший менеджер". Поскольку мы используем SCD Тип 2, то создается новая строка с обновленной должностью, а предыдущая должность сохраняется в столбце "PreviousPosition". После этого мы поменяем отдел с "Маркетинг" на "Продажи". А так как это SCD Тип 1, столбец "CurrentDepartment" обновляется в текущей строке.

Этот подход позволяет компании эффективно управлять изменениями в данных о сотрудниках, сохраняя как историческую, так и текущую информацию.
Командам, работающим с хранилищами данных, довольно часто приходится сохранять исторические атрибуты, а также поддерживать возможность предоставления исторических данных о производительности в соответствии с текущими значениями атрибутов. SCD Type 6 — это решение для таких задач.
Если вы хотите увидеть исторические факты на основе текущих значений атрибутов, мы отфильтруем или обобщим данные по текущим атрибутам. Если мы обобщим данные по историческому атрибуту, мы увидим факты в виде их совокупности на определённый момент времени.
Ограничения медленно изменяющихся измерений в Data Science
Хотя SCD являются важной частью хранилищ данных, позволяя сохранять исторические данные вместе с изменениями, с ними связаны некоторые ограничения, такие как:
-
Объем хранилища: Набор данных с большим количеством входных признаков может быстро увеличить требования к хранилищу. Это особенно актуально для SCD Типа 2, который предполагает добавление новой строки для каждого изменения.
-
Обслуживание: С увеличением количества атрибутов или измерений отслеживание изменений становится сложнее. Это может привести к увеличению вероятности ошибок.
-
Производительность: По мере роста объема данных для отслеживания исторических изменений производительность моделей машинного обучения может ухудшаться.
-
Масштабируемость: С увеличением объема данных и накопленных изменений некоторые типы SCD могут не масштабироваться эффективно. Это влияет на хранение, вычисления и визуализацию.
-
Избыточность: Большинство медленно изменяющихся измерений в Data Science связаны с избыточностью. Например, в SCD Типа 2 новая строка добавляется для каждого изменения в измерении. В итоге это приводит к множеству строк для одной и той же сущности и увеличению размерности. Методы сокращения размерности помогают выявлять и управлять такой избыточностью.
Как реализовать медленно изменяющиеся измерения (Slowly Changing Dimensions) в хранилище данных?
В идеале, если вы учтёте медленно изменяющиеся измерения (SCD) еще на этапе проектирования базы данных. Если вы только начинаете строить свою инфраструктуру данных или работаете в стартапе, это будет проще всего.
Для существующих баз данных начните с оценки данных, которые уже есть в вашей базе. Документируйте различные типы измерений и их взаимосвязи. Если в базе есть измерения типа 0, которые не должны быть таковыми, начните с них. И, если необходимо, добавьте отслеживание исторических данных как можно быстрей.
Затем определите, какие типы SCD (2, 3 или 4) подходят для вашего бизнеса. Задайте себе следующие вопросы:
-
Как часто изменяются эти измерения?
-
Будете ли вы использовать столбец с временной меткой или флаговый столбец?
-
Стоит ли добавить историческую таблицу для хранения большого количества записей?
Такой процесс потребует участия аналитиков, архитекторов, разработчиков и специалистов по анализу данных.
Еще один важный момент — как вы хотите обрабатывать исторические записи, которые ранее не отслеживались. Можно, конечно, отказаться от исторических данных и внедрить SCD только для будущих операций, но лучше всего собрать старые записи и создать свою версию столбца с временной меткой или флагом.
Автор: theden_m37