Files
clickstream-ch-kafka-supers…/sql/ddl/dds/30_dds.sql
T
ddadmin 9e340bb729 refactor(sql): reorganize sql files into structured directory hierarchy
Move DDL files from flat ddl/ directory to sql/ddl/ with layer-based
subdirectories (stg, ods, dds, dm). Move batch transformation SQL from
jobs/ to sql/ layer directories. Update scripts and documentation to
reflect new paths for improved organization and Airflow integration.
2026-02-07 20:51:51 +03:00

80 lines
5.8 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ============================================================================
-- Слой DDS (Detailed Data Store) — детальные сущности для аналитики
-- ============================================================================
-- Назначение:
-- - Собранные "чистые" сущности из ODS для JOIN'ов и аналитики
-- - click: объединяет device + geo (контекст сессии пользователя)
-- - event: объединяет browser + location (контекст события)
--
-- Загрузка:
-- Batch SQL (не MV!) — для согласованности при late arrivals
-- См. sql/dds/30_ods_to_dds.sql
--
-- Почему не MV:
-- - MV с JOIN даёт eventual consistency (данные приходят в разное время)
-- - Batch позволяет сделать снапшот через argMax и корректно джойнить
-- - Контроль: можно проверить SQL, откатить, перезапустить
-- ============================================================================
-- ----------------------------------------------------------------------------
-- Сущность: dds.click (контекст сессии пользователя)
-- ----------------------------------------------------------------------------
-- Объединяет данные из ods.device_by_click + ods.geo_by_click
-- Связь с event через click_id (LEFT JOIN, не все события имеют device/geo)
-- ----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS dds.click
(
click_id UUID, -- UUID сессии/клика (PK)
user_domain_id Nullable(UUID), -- UUID пользователя в системе
user_custom_id Nullable(String), -- Email/username
device_type LowCardinality(Nullable(String)), -- Mobile, Computer, Tablet
device_is_mobile Nullable(UInt8), -- 1 = мобильное, 0 = десктоп
os_name LowCardinality(Nullable(String)), -- Windows, iOS, Android и т.д.
os Nullable(String), -- Полное название ОС
os_timezone LowCardinality(Nullable(String)), -- Таймзона пользователя
geo_country LowCardinality(Nullable(String)), -- Код страны (RU, US)
geo_region_name Nullable(String), -- Регион/город
geo_timezone LowCardinality(Nullable(String)), -- Таймзона по гео
geo_latitude Nullable(Float64), -- Широта
geo_longitude Nullable(Float64), -- Долгота
ip_address Nullable(String), -- IP адрес
dds_update_ts DateTime64(3), -- Время загрузки в DDS (версия)
ods_parse_errors Array(LowCardinality(String)) -- Ошибки из ODS + метки о пропусках
)
ENGINE = ReplacingMergeTree(dds_update_ts) -- Дедупликация по версии
PARTITION BY toYYYYMM(toDate(dds_update_ts)) -- Партиция по месяцу загрузки
ORDER BY (click_id) -- Ключ сортировки
SETTINGS allow_nullable_key = 1; -- Разрешаем NULL (на всякий случай)
-- ----------------------------------------------------------------------------
-- Сущность: dds.event (контекст события)
-- ----------------------------------------------------------------------------
-- Объединяет данные из ods.browser_event + ods.location_event
-- Связь с click через click_id (может быть NULL, если нет device/geo)
-- ----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS dds.event
(
event_id UUID, -- UUID события (PK)
event_ts Nullable(DateTime64(6)), -- Время события
event_date Date MATERIALIZED ifNull(toDate(event_ts), toDate(dds_update_ts)), -- Дата для партиций
event_type LowCardinality(Nullable(String)), -- pageview, click, purchase и т.д.
click_id Nullable(UUID), -- Связь с dds.click (может быть NULL)
page_url Nullable(String), -- Полный URL
page_url_path LowCardinality(Nullable(String)), -- Путь (/home, /product)
referer_url Nullable(String), -- Откуда пришёл
referer_medium LowCardinality(Nullable(String)), -- Тип referer
utm_medium LowCardinality(Nullable(String)), -- UTM medium
utm_source LowCardinality(Nullable(String)), -- UTM source
utm_content LowCardinality(Nullable(String)), -- UTM content
utm_campaign LowCardinality(Nullable(String)), -- UTM campaign
browser_name LowCardinality(Nullable(String)), -- Chrome, Firefox
browser_user_agent Nullable(String), -- User-Agent
browser_language LowCardinality(Nullable(String)), -- Язык браузера
dds_update_ts DateTime64(3), -- Время загрузки в DDS (версия)
ods_parse_errors Array(LowCardinality(String)) -- Ошибки из ODS
)
ENGINE = ReplacingMergeTree(dds_update_ts) -- Дедупликация по версии
PARTITION BY toYYYYMM(event_date) -- Партиция по дате события (важно для фильтров)
ORDER BY (event_id) -- Ключ сортировки
SETTINGS allow_nullable_key = 1; -- Разрешаем NULL