SCD Type 2 полная историзация с версиями и суррогатным ключом
SCD Type 2 полная historization с версиями и суррогатным ключом — это один из наиболее востребованных подходов в архитектуре хранилищ данных, когда требуется сохранить полную историю изменений измеряемых сущностей в измерениях (dimensions). В реальных аналитических системах бывает критично понять not only how вещи выглядят сейчас, но и как они выглядели в прошлом: какие значения держал клиент в прошлом году, какие адреса изменялись и когда именно. SCD Type 2 позволяет это сделать без потери деталей и при этом обеспечить удобство аналитики.
Цель этой главы — дать понятное и полное объяснение концепций SCD Type 2: что это за механизм, почему он нужен, какие термины применяются, какие методологические подходы существуют, а также привести конкретные практические примеры реализации на открытых и на российских технологиях. Мы разберем теоретические основы, затем перейдем к практическим примерам, техническим деталям реализации, обсудим риски и ограничения и завершим разделами выводов и FAQ.
Что такое SCD и почему нужен Type 2
Slowly Changing Dimensions (SCD) — это набор паттернов работы с измерениями в хранилищах данных, где данные могут меняться со временем. В зависимости от потребностей бизнеса выбирают методику фиксации изменений. Типы SCD различаются по тому, как хранится история изменений.
- SCD Type 1: замена старого значения новым без сохранения истории. Легко реализуется, минимальные затраты на хранение, но аналитика по прошлому недоступна.
- SCD Type 2: полная historization. При изменении бизнес-значения создаются новые строки в измерении, а старая строка помечается как завершенная. В результате у нас есть неизменяемая полная история изменений по каждому бизнес-ключу.
- SCD Type 3: часть истории сохраняется через добавление новых полей (например, предыдущее значение), но полноту истории как у Type 2 обеспечивает не всегда.
- И далее существуют и более сложные подходы (Type 4, Type 6 и пр.), но Type 2 остается наиболее универсальным решением для большинства кейсов, где нужна история и возможность анализа по времени.
Основная идея Type 2 — не удалять и не ломать старые данные, а добавлять новые «версии» записи для каждого бизнес-ключа, сопровождая их временными метками и индикаторами актуальности. Это позволяет:
- анализировать динамику изменений по сущности (клиент, продукт, сотрудник и т. д.);
- поддерживать аудит и соответствие требованиям регуляторов;
- сохранять линейную историческую цепочку без сложных реконструкций.
Термины и концепции
- Бизнес-ключ (business key) — естественный ключ сущности в исходной системе (например, идентификатор клиента). В измерении он остается стабильным и не меняется со временем.
- Суррогатный ключ (surrogate key) — искусственный ключ в Dimension Table, обычно числовой (например, целочисленный). Он уникален внутри столбца dimension и никак не связан с бизнес-ключом напрямую. Его задача — однозначно идентифицировать конкретную версию записи измерения.
- Версия (version) — номер версии записи в измерении. При изменении бизнес-атрибутов версия инкрементируется.
- effective_from / valid_from (период действия) и effective_to / valid_to (конец периода действия) — временные границы, указывающие, когда запись была актуальной. В большинстве реализаций current запись имеет effective_to = очень большая дата (например, 9999-12-31) или специальный флаг is_current = true.
- is_current (или current_flag) — индикатор актуальности записи. В некоторых схемах предпочитают только флаг, в других — даты действия. Оба варианта применимы, но даты часто дают больше гибкости при аналитике и историческом запросе.
- Историзированная таблица измерения — таблица, в которой каждая новая версия бизнес-ключа имеет собственную строку с новым суррогатным ключом и временными маркерами.
- ETL-пайплайн — процесс извлечения данных из источников, их преобразования и загрузки в хранилище. В контексте SCD Type 2 ETL-слой несет ответственность за реконструкцию новой версии записи и корректировку старой.
- Вариации реализации: чаще всего используется подход «изменение существующей строки» и «вставка новой версии» в рамках одного бизнес-ключа. В некоторых системах могут применяться временные таблицы, MERGE-операции, CDC и т.п.
Модель данных для SCD Type 2
Типичная структура измерения с SCD Type 2 имеет следующие поля:
- суррогатный ключ (surrogate key, SK)
- бизнес-ключ (natural key, NK) — бизнес-ключ, по которому идентифицируется сущность в исходных системах
- набор атрибутов сущности (name, address, phone и т. д.)
- версия (version)
- is_current или current_flag
- effective_from / valid_from
- effective_to / valid_to
- дополнительные поля аудита (кто и когда загрузил, источник данных и пр.)
Важно: в целях аналитики чаще всего одной «актуальной» версии недостаточно — важно сохранить полную цепочку версий. Но либо только одна версия помечена как current, либо можно хранить и все версии, чтобы иметь доступ к истории на любой момент времени.
Почему именно SCD Type 2 часто предпочтительнее
- Полная история изменений — это ключ к правильной ретроспективной аналитике и сопоставлению трендов.
- Простая реализация на большинстве СУБД: можно реализовать через обычные INSERT/UPDATE без необходимости специальных функций потока.
- Универсальность: применяется как к клиентам, так и к продуктам, сотрудникам и другим характеристикам.
- Гибкость анализа по времени: можно выполнять запросы по определенным периодам, сравнивать показатели по годам/кварталам с сохранностью истории.
Методы реализации SCD Type 2
- Традиционная пакетная ETL: на каждом проходе сравнивается «сегмент» новой выборки с текущими актуальными записями в измерении, если есть изменения — обновляется текущая запись (end date и is_current) и вставляется новая версия.
- Использование хеша изменений: рассчитывается хеш набора неключевых атрибутов и сравнивается с хешем текущей версии — если отличается, создаётся новая версия.
- Потоковая обработка (CDC): события об изменениях поступают в поток, и обработчик конвертирует их в новые версии измерения.
Технические последствия
- Необходимо выбрать стратегию ключей и хранение версий, чтобы поддерживать целостность данных и консистентность запросов.
- Требуется адекватное индексирование и, возможно, временные партиции для ускорения запросов по диапазонам дат.
- Необходимо продумать обработку конфликта изменений в одном пакете загрузки (например, когда несколько источников пытаются обновить одну запись в одном батче).
Практические примеры
1) Простой пример на PostgreSQL (SCD Type 2 на примере клиента)
Цель: сохранить историю изменения адреса и телефона клиента.
Структура начальной таблицы измерения:
sk_customer (BIGINT, суррогатный ключ, PRIMARY KEY) customer_id (VARCHAR, бизнес-ключ) name (VARCHAR) address (VARCHAR) city (VARCHAR) region (VARCHAR) postal_code (VARCHAR) email (VARCHAR) phone (VARCHAR) version (INT) is_current (BOOLEAN) effective_from (DATE) effective_to (DATE)
Пример DDL:
CREATE TABLE dim_customer_scd2 ( sk_customer BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, customer_id VARCHAR(50) NOT NULL, name VARCHAR(200), address VARCHAR(255), city VARCHAR(100), region VARCHAR(100), postal_code VARCHAR(20), email VARCHAR(100), phone VARCHAR(50), version INT NOT NULL, is_current BOOLEAN NOT NULL, effective_from DATE NOT NULL, effective_to DATE NOT NULL ); -Уникальная запись на текущую версию по бизнес-ключу CREATE UNIQUE INDEX idx_dim_customer_scd2_current ON dim_customer_scd2 (customer_id) WHERE is_current = true;
Пример первоначальной загрузки (из staging):
-Допустим, staging_customer содержит поля: customer_id, name, address, city, region, postal_code, email, phone
INSERT INTO dim_customer_scd2 (
customer_id, name, address, city, region, postal_code, email, phone,
version, is_current, effective_from, effective_to
)
SELECT
s.customer_id, s.name, s.address, s.city, s.region, s.postal_code, s.email, s.phone,
1, true, CURRENT_DATE, DATE '9999-12-31'
FROM staging_customer s
WHERE NOT EXISTS (
SELECT 1 FROM dim_customer_scd2 d
WHERE d.customer_id = s.customer_id
AND d.is_current = true
);
Пояснение: создаются текущие версии для клиентов, которых нет в измерении как current. Версии начинаются с 1.
Изменение данных (пример обновления адреса и телефона для клиента с customer_id = 'C001')
Шаг 1: Найдем текущую версию
SELECT d.sk_customer, d.version FROM dim_customer_scd2 d WHERE d.customer_id = 'C001' AND d.is_current = true;
Шаг 2: Обновим текущую версию: end дату и флаг текущности
UPDATE dim_customer_scd2 SET effective_to = CURRENT_DATE INTERVAL '1 day', is_current = false WHERE customer_id = 'C001' AND is_current = true;
Шаг 3: Вставим новую версию с обновленными данными
INSERT INTO dim_customer_scd2 ( customer_id, name, address, city, region, postal_code, email, phone, version, is_current, effective_from, effective_to ) SELECT d.customer_id, 'Иванов Иван Иванович', -новое значение name (пример) 'ул. Примерная, д. 10', -новое значение address d.city, d.region, d.postal_code, d.email, '+7 999 123-45-67', -новое значение phone d.version + 1, true, CURRENT_DATE, DATE '9999-12-31' FROM dim_customer_scd2 d WHERE d.customer_id = 'C001' AND d.is_current = true;
Замечания:
- Здесь предполагается, что версия для Business Key нарастает на единицу.
- Важно обработать случай, когда несколько изменений приходят в одну загрузку. В этом случае полезно сначала определить изменения, затем обновить текущие версии и вставить новые версии последовательно, чтобы не нарушить целостность.
2) Применение хеширования для определения изменений
Идея: вычислять хеш атрибутов, которые подлежат отслеживанию, и сравнивать его с хешем текущей версии.
- В staging добавляем вычисляемый столбец: attrs_hash = md5(concat(name, address, city, region, postal_code, email, phone)).
- В dim_current ищем совпадение по customer_id и сравниваем хеши. Если хеш изменился — это признак изменения, и мы выполняем обычный процесс ветвления (end-date старой версии и вставка новой версии).
3) Пример на Apache Iceberg или Apache Hudi (управление версиями и upsert)
Эти форматы таблиц позволяют использовать эффективные upsert-операции и временные розы, что упрощает реализацию SCD Type 2 в больших объемах и в обработке через Spark.
Iceberg/Spark пример (псевдокод):
- У вас есть целевая таблица dim_customer_scd2 с колонками: sk, customer_id, name, address, city, region, postal_code, email, phone, version, is_current, effective_from, effective_to.
- У вас есть источник изменений staging_customer (new сведения по клиентам).
MERGE INTO dim_customer_scd2 AS t USING staging_customer AS s ON t.customer_id = s.customer_id AND t.is_current = true WHEN MATCHED AND (t.name <> s.name OR t.address <> s.address OR t.city <> s.city OR t.region <> s.region OR t.postal_code <> s.postal_code OR t.email <> s.email OR t.phone <> s.phone) THEN UPDATE SET t.is_current = false, t.effective_to = CURRENT_DATE INTERVAL '1' DAY WHEN NOT MATCHED OR (MATCHED AND t.is_current = false) THEN INSERT (customer_id, name, address, city, region, postal_code, email, phone, version, is_current, effective_from, effective_to) VALUES (s.customer_id, s.name, s.address, s.city, s.region, s.postal_code, s.email, s.phone, COALESCE((SELECT MAX(version) FROM dim_customer_scd2 d WHERE d.customer_id = s.customer_id), 0) + 1, true, CURRENT_DATE, DATE '9999-12-31');
Практические примеры: примеры российских и открытых решений
1) Открытые решения и подходы
- PostgreSQL + элегантная ETL-процедура на SQL: как выше, с нормализацией и триггерными сценариями.
- Apache Spark + Apache Iceberg или Apache Hudi: большие данные, потоковая загрузка и upsert-операции. Позволяют работать с большими объемами исторических данных и хранить исторические версии в формате, удобном для анализа.
- Apache NiFi / Apache Airflow: оркестрация загрузок, контроль качества данных и планирование ETL-пайплайнов. В сочетании с Iceberg/Hudi — мощная связка для реализации SCD Type 2 в больших системах.
- dbt: трансформации в слое аналитики, управление версиями моделей и документация. Может использоваться вместе с Iceberg/Hudi для организации точной и управляемой модели данных.
2) Российские или отечественные решения и контекст
- Яндекс.Облако и экосистема ClickHouse: ClickHouse — открытая база данных колоночного типа, разработанная в Российской Федерации. Хотя изначально это аналитическая база для быстрого агрегационного анализа больших массивов данных, современные версии поддерживают обновления (UPDATE/ALTER UPDATE) в ограниченном формате. Реализация SCD Type 2 в ClickHouse возможна через режимы обновления (ALTER UPDATE) для пометки текущей версии и вставки новой версии. Важно учитывать ограничения обновления в колоночных хранениях и требования к производительности.
- ClickHouse в связке с язьовыми инструментами: можно использовать переходные таблицы и пакетные загрузки из Kafka/потоков в ClickHouse с последующим применением ALTER UPDATE для версий. Это решение хорошо подходит для больших потоков изменений и быстрых запросов аналитики.
- Российские интеграционные решения и сервисы: в регионе широко используются open-source или ближние к open-source решения с локализацией, которые интегрируются с отечественными дата-центрами и сервисами обработки данных. В качестве примера часто встречаются конвейеры на Apache NiFi/Airflow плюс Iceberg/Hudi в рамках локальных развёртываний.
3) Особенности выбора подхода в зависимости от условий
- Мелкие и средние объемы данных, частые изменения в режиме пакетной загрузки — PostgreSQL + ETL-скрипты, хеширование изменений, простая реализация Type 2.
- Очень большие объемы данных, необходимость поддержки горизонтального масштабирования и высоких скоростей — Iceberg/Hudi на Spark/Fluent обработке с использованием MERGE-операций и временных таблиц.
- Потоки данных и real-time аналитика — комбинация CDC-подходов (например, Debezium) для захвата изменений и ICEBERG/Hudi для хранения версий с upsert.
- Архитектура на базе ClickHouse в регионах с акцентом на скорость агрегации: можно реализовать SCD Type 2 через обновления и вставки, но придётся учитывать ограничения на обновление больших таблиц.
Архитектура и проектирование
- Выберите стратегию суррогатного ключа: в большинстве случаев SK генерируется как IDENTITY/SEQUENCE в целевой таблице (dim_customer_scd2). NK — бизнес-ключ, по которому идентифицируется запись в источнике.
- Обеспечьте уникальность одной текущей версии по каждому NK: например, через частичный уникальный индекс (customer_id, is_current = true) или через ограничение (customer_id, version) и дополнительную логику для текущей версии.
- Введите поля аудита: источники данных, временные метки загрузки, пользователь, версия загрузчика. Это помогает в поддержке требований по аудитам и отладке.
- Придерживайтесь единого формата дат: используйте DATE или TIMESTAMP в зависимости от требований к точностям по времени для анализа.
Типовые DDL-структуры (пример для PostgreSQL)
Таблица Dimension SCD Type 2:
CREATE TABLE dim_customer_scd2 ( sk_customer BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, customer_id VARCHAR(50) NOT NULL, name VARCHAR(200), address VARCHAR(255), city VARCHAR(100), region VARCHAR(100), postal_code VARCHAR(20), email VARCHAR(100), phone VARCHAR(50), version INT NOT NULL, is_current BOOLEAN NOT NULL, effective_from DATE NOT NULL, effective_to DATE NOT NULL, -дополнительные поля аудита по желанию load_source VARCHAR(100), load_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE UNIQUE INDEX idx_dim_customer_scd2_current ON dim_customer_scd2 (customer_id) WHERE is_current = true;
Пример вставки новой версии после изменения:
Сначала помечаем текущую версию как не текущую и ограничиваем её по дате:
UPDATE dim_customer_scd2 SET is_current = false, effective_to = CURRENT_DATE INTERVAL '1 day' WHERE customer_id = 'C001' AND is_current = true;
Затем вставляем новую версию с обновлёнными данными:
INSERT INTO dim_customer_scd2 ( customer_id, name, address, city, region, postal_code, email, phone, version, is_current, effective_from, effective_to, load_source ) SELECT s.customer_id, s.name, s.address, s.city, s.region, s.postal_code, s.email, s.phone, COALESCE((SELECT MAX(version) FROM dim_customer_scd2 d WHERE d.customer_id = s.customer_id), 0) + 1, true, CURRENT_DATE, DATE '9999-12-31', 'staging_load' FROM staging_customer s WHERE s.customer_id = 'C001' AND ( SELECT name FROM dim_customer_scd2 d WHERE d.customer_id = s.customer_id AND d.is_current = true ) <> s.name OR ( SELECT address FROM dim_customer_scd2 d WHERE d.customer_id = s.customer_id AND d.is_current = true ) <> s.address OR ( SELECT phone FROM dim_customer_scd2 d WHERE d.customer_id = s.customer_id AND d.is_current = true ) <> s.phone;
Объяснение: старую текущую запись помечаем как не текущую и ограничиваем её датой завершения, затем вставляем новую версию с новым значением version и текущей меткой is_current = true.
Технические детали по индексации и производительности
- Разделение по времени (партирования по effective_from) ускоряет диапазонные запросы по времени.
- Индексы по бизнес-ключу (customer_id) и по is_current позволяют быстро найти текущую запись.
- В современных форматах таблиц (Iceberg/Hudi) используется встроенная поддержка time travel и upserts, что упрощает процесс и повышает производительность при больших объемах.
- В потоковой обработке полезно внедрять буферизацию изменений и методики дедупликации, чтобы совпадения изменений не приводили к конфликтам при параллельной загрузке.
Примеры практического SQL-подхода при пакетном обновлении
Пример сравнения изменений через простое сравнение атрибутов:
SELECT s.customer_id FROM staging_customer s JOIN dim_customer_scd2 d ON d.customer_id = s.customer_id AND d.is_current = true WHERE d.name IS DISTINCT FROM s.name OR d.address IS DISTINCT FROM s.address OR d.city IS DISTINCT FROM s.city OR d.region IS DISTINCT FROM s.region OR d.postal_code IS DISTINCT FROM s.postal_code OR d.email IS DISTINCT FROM s.email OR d.phone IS DISTINCT FROM s.phone;
В случае наличия изменений выполняем порядок операций, описанный выше.
Риски и ограничения
1) Сложности внедрения
- Необходимо тщательно спланировать стратегию ключей, чтобы избежать дублирования и конфликтов версий.
- Сложность поддержки параллельной загрузки: если несколько потоков пытаются обновлять одну и ту же бизнес-ключевую запись, нужно аккуратно синхронизировать операции или использовать транзакции/последовательность загрузок.
- Требуется продуманная обработка ошибок: откаты, повторные попытки, консистентность данных после сбоев.
2) Производительность и масштабирование
- В пакетной загрузке может быть высокий расход времени на поиск изменений и обновление старых версий.
- В больших системах размер измерения Type 2 может расти резко; нужно продумать партиционирование и архивирование устаревших данных.
- В поточной обработке задержки и контроль качества должны быть четко реализованы: задержки в CDC могут затрагивать согласованность версий.
3) Управление данными и соответствие требованиям
- GDPR и правила по праву на забывание: Type 2 сохраняет историю, что может конфликтовать с требованиями удаления данных. Необходимо определить политики архивирования, а также иметь механизмы по анонимизации или маскированию данных по запросу.
- Правила аудита и відповідь на запросы: нужны метки источников, версий, временных интервалов и логирования изменений.
4) Российская инфраструктура и локализация
- Прямые обновления в некоторых отечественных СУБД могут иметь ограничения по скорости и функциональности. В зависимости от выбранного движка (PostgreSQL, ClickHouse, Iceberg/Hudi через Spark) выбираются разные паттерны и подходы.
- Важна совместимость с локальными требованиями к хранению данных, репликации и резервному копированию.
SCD Type 2 полная historization с версиями и суррогатным ключом — мощный и практически необходимый механизм для сохранения полной истории изменений измерений в дата-слоях. Он обеспечивает гибкую аналитику по времени, аудит изменений и возможность ретроспективного анализа. Реализация может осуществляться разной технологической связкой: от простого PostgreSQL ETL до современных форматов Iceberg/Hudi в связке с Spark и распределенными обработчиками. Выбор подхода зависит от объема данных, требований к скорости обработки, инфраструктуры и регулятивных условий.
Практические аспекты требуют внимательной архитектуры: проектирования таблиц с суррогатными ключами и версиями, выбора вариантов хранения (effective_from/effective_to vs is_current), а также разработки надежного ETL-пайплайна, который корректно обрабатывает одновременные загрузки и изменения в одном батче. Важно также учитывать риски: сложность поддержки, производительность, требования к архивированию и соответствию требованиям по защите данных. Но при грамотной реализации SCD Type 2 становится основой мощной аналитической системы, где история изменений превращается в ценность для бизнеса.
FAQ (Вопрос–Ответ)
1) Что такое SCD Type 2 и чем он отличается от Type 1?
SCD Type 2 — это подход, который сохраняет полную историю изменений сущности. При изменении атрибутов создается новая версия записи с новым суррогатным ключом и актуальной датой начала действия, а предыдущая версия помечается как завершенная. Type 1 же просто заменяет старое значение новым без сохранения истории. В аналитике Type 2 позволяет видеть, как менялась сущность во времени.
2) Зачем нужен суррогатный ключ в SCD Type 2?
Суррогатный ключ служит уникальным идентификатором каждой версии записи измерения. Он отделен от бизнес-ключа ( NK ) и обеспечивает устойчивость данных к изменению бизнес-ключа, версий и временных атрибутов. Это важно для точной идентификации версий и для эффективной агрегации по времени.
3) Какие поля обычно используются в SCD Type 2?
Типичная структура включает: sk_customer (суррогатный ключ), customer_id (бизнес-ключ), набор атрибутов (name, address, city и пр.), version (номер версии), is_current (флаг актуальности), effective_from и effective_to (период действия). Дополнительно могут быть поля аудита: load_source, load_ts и т. д.
4) Как реализовать SCD Type 2 в PostgreSQL?
Реализация включает создание таблицы с суррогатным ключом, бизнес-ключом, атрибутами и версиями, затем пакетную загрузку:
- первоначальная загрузка: вставляется версия 1 с is_current = true.
- изменение: помечается текущая версия как неактуальная (is_current = false, effective_to = текущая дата 1 день), затем вставляется новая версия с incrementar version и is_current = true.
Можно использовать хеширование изменений для ускорения детекции изменений.
5) Какие альтернативные технологии подходят для SCD Type 2 на больших данных?
Open-source решения: Apache Iceberg и Apache Hudi в сочетании с Apache Spark — поддерживают upsert и time travel, что удобнее для крупных объемов. ETL-оркестрация через Apache NiFi или Apache Airflow. dbt может использоваться для трансформаций и управления моделями. ClickHouse (российское развитие) поддерживает обновления и может применяться в некоторых сценариях SCD Type 2, но следует учитывать ограничения обновления больших таблиц.
6) Какие риски основного внедрения SCD Type 2?
- Сложность управления параллельной загрузкой и конфликтами изменений.
- Растущий объем данных и необходимость архивирования.
- Требования соответствия (GDPR и пр.) и политика прав на забывание.
- Нагрузка на ETL-пайплайн и консистентность между источниками и приемником.
- Выбор правильной стратегии ключей и обеспечение уникальности текущей версии.
7) Какие практические шаги можно применить при внедрении SCD Type 2?
- Определите бизнес-ключи и суррогатные ключи, решите, какие поля будут использоваться для детекции изменений (атрибуты, хеши).
- Выберите архитектуру хранения (PostgreSQL vs Iceberg/Hudi) и подход к загрузкам: пакетные батчи против стриминга.
- Спроектируйте таблицу измерения с полями версий и датами действия, добавьте индексы и ограничения.
- Реализуйте ETL-пайплайн, который корректно обрабатывает обновления и вставки новых версий, в случае параллельности используйте транзакции либо оркестрацию процессов.
- Протестируйте на тестовых данных: сценарии добавления, изменения, одновременной загрузки, откатов и повторных загрузок.
- Учитывайте требования по хранению и архивированию устаревших данных.
8) Можно ли совместить SCD Type 2 с GDPR?
Да, но требует дополнительных подходов: политика архивирования и маскирование данных, чтобы удовлетворить требования на забывание. В некоторых случаях можно хранить данные в зашифрованном виде или выносить чувствительные поля в отдельные таблицы с ограничениями доступа.
9) Как выбрать между PostgreSQL и Iceberg/Hudi?
- PostgreSQL подходит для небольших и средних объемов данных, когда нужен простой и понятный подход, без необходимости масштабирования.
- Iceberg/Hudi — выбор для больших объемов, когда нужна интеграция с Spark, возможность upsert и time travel, и когда требуется горизонтальное масштабирование и продвинутая аналитика по времени.
10) Какие практические примеры стоит смотреть для обучения?
- Реализация SCD Type 2 в PostgreSQL с примером вставки и обновления версий.
- Пример MERGE-операции в Iceberg/Hudi через Spark для реализации SCD Type 2.
- Пример использования CDC потоков (Debezium, Kafka) для захвата изменений и их применения к измерению с SCD Type 2.
- Пример использования ClickHouse с обновлениями (ALTER UPDATE) для SCD Type 2 в российской инфраструктуре.



