feat(dm): добавлена сверка покупок с заказами
- Зачем: - показать расхождения трекера и бэкенда на зерне заказа - сохранить отложенные покупки наблюдаемыми до следующего слепка - Что: - добавлены таблицы, представление и пересборка purchase_vs_orders - сумма покупки нормализована в Decimal на границе ODS - обновлены договоры и указатели на механику пересборки - Проверка: - `make config-test`, `make lint` - `cd generator && make docs lint typecheck test` - `make rebuild-storage`, явные `dds_transform` и `dm_transform` - `make smoke`, `make check-clickhouse`, `make check-services`
This commit is contained in:
1 parent
fb00bbe4c3
commit
20071c565f
15 files changed
+391
-38
No files matched your search
@@ -83,7 +83,7 @@ CREATE TABLE IF NOT EXISTS ods.event_rep ON CLUSTER clickstream_cluster
|
||||
GoalsReached Array(UInt32),
|
||||
ParsedParamsKey1 Array(String),
|
||||
purchaseID Array(String),
|
||||
purchaseRevenue Array(Float64),
|
||||
purchaseRevenue Array(Decimal(18, 2)),
|
||||
purchaseCurrency Array(String),
|
||||
purchaseCoupon Array(String),
|
||||
productID Array(String),
|
||||
|
||||
@@ -154,7 +154,11 @@ SELECT
|
||||
JSONExtract(raw, 'GoalsReached', 'Array(UInt32)') AS GoalsReached,
|
||||
JSONExtract(raw, 'ParsedParamsKey1', 'Array(String)') AS ParsedParamsKey1,
|
||||
JSONExtract(raw, 'purchaseID', 'Array(String)') AS purchaseID,
|
||||
JSONExtract(raw, 'purchaseRevenue', 'Array(Float64)') AS purchaseRevenue,
|
||||
-- Выгрузка несет JSON-числа типа Float64, но деньги хранятся в Decimal.
|
||||
-- JSONExtract разбирает их сразу, без промежуточного двоичного числа:
|
||||
-- синтаксис подтвержден документацией ClickHouse через Context7 и
|
||||
-- запросом к стендовому ClickHouse 26.3 при исполнении #155.
|
||||
JSONExtract(raw, 'purchaseRevenue', 'Array(Decimal(18, 2))') AS purchaseRevenue,
|
||||
JSONExtract(raw, 'purchaseCurrency', 'Array(String)') AS purchaseCurrency,
|
||||
JSONExtract(raw, 'purchaseCoupon', 'Array(String)') AS purchaseCoupon,
|
||||
JSONExtract(raw, 'productID', 'Array(String)') AS productID,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
-- DM: физические дневные витрины и донор партиций выручки.
|
||||
-- DM: физические дневные витрины и доноры их партиций.
|
||||
|
||||
-- Выручка хранится в зерне «день заказа × категория товара». День служит
|
||||
-- единицей пересборки, поэтому совпадает с ключом партиции.
|
||||
@@ -48,6 +48,51 @@ ENGINE = Distributed(
|
||||
cityHash64(product_category)
|
||||
);
|
||||
|
||||
-- Сверка хранит одну строку на заказ. День — единица пересборки: пока рядом
|
||||
-- живут два источника, строка может перейти из awaiting_order в обычный класс.
|
||||
CREATE TABLE IF NOT EXISTS dm.purchase_vs_orders_rep ON CLUSTER clickstream_cluster
|
||||
(
|
||||
order_day Date,
|
||||
order_id String,
|
||||
declared_revenue Nullable(Decimal(18, 2)),
|
||||
items_total Nullable(Decimal(18, 2)),
|
||||
status LowCardinality(Nullable(String)),
|
||||
mismatch_class LowCardinality(String),
|
||||
_load_id String,
|
||||
_load_ts DateTime64(3, 'UTC')
|
||||
)
|
||||
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/{database}/{table}', '{replica}')
|
||||
PARTITION BY order_day
|
||||
ORDER BY (order_day, order_id);
|
||||
|
||||
-- Ключ совпадает с DDS, поэтому строка заказа на всех слоях попадает на один
|
||||
-- шард.
|
||||
CREATE TABLE IF NOT EXISTS dm.purchase_vs_orders_dist ON CLUSTER clickstream_cluster
|
||||
AS dm.purchase_vs_orders_rep
|
||||
ENGINE = Distributed(
|
||||
'clickstream_cluster',
|
||||
'dm',
|
||||
'purchase_vs_orders_rep',
|
||||
cityHash64(order_id)
|
||||
);
|
||||
|
||||
-- Донор повторяет структуру и раскладку цели по правилу, разобранному у
|
||||
-- revenue_daily_stage_rep и в docs/architecture/storage.md.
|
||||
CREATE TABLE IF NOT EXISTS dm.purchase_vs_orders_stage_rep ON CLUSTER clickstream_cluster
|
||||
AS dm.purchase_vs_orders_rep
|
||||
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/{database}/{table}', '{replica}')
|
||||
PARTITION BY order_day
|
||||
ORDER BY (order_day, order_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dm.purchase_vs_orders_stage_dist ON CLUSTER clickstream_cluster
|
||||
AS dm.purchase_vs_orders_stage_rep
|
||||
ENGINE = Distributed(
|
||||
'clickstream_cluster',
|
||||
'dm',
|
||||
'purchase_vs_orders_stage_rep',
|
||||
cityHash64(order_id)
|
||||
);
|
||||
|
||||
-- Трафик пересчитывается целиком: новая связь куки с пользователем меняет
|
||||
-- прошлые дни. Версия запуска позволяет точному представлению скрыть строки
|
||||
-- прежних пересчетов без TRUNCATE и без партиций.
|
||||
|
||||
@@ -15,6 +15,22 @@ SELECT
|
||||
_load_ts
|
||||
FROM dm.revenue_daily_dist;
|
||||
|
||||
-- Непарные стороны остаются NULL. При join_use_nulls = 0 ClickHouse заполнил
|
||||
-- бы их нулями и пустыми строками, скрыв отсутствие источника.
|
||||
-- Служебные колонки называют запуск, который последним заменил день.
|
||||
CREATE VIEW IF NOT EXISTS dm.purchase_vs_orders_v ON CLUSTER clickstream_cluster
|
||||
AS
|
||||
SELECT
|
||||
order_day,
|
||||
order_id,
|
||||
declared_revenue,
|
||||
items_total,
|
||||
status,
|
||||
mismatch_class,
|
||||
_load_id,
|
||||
_load_ts
|
||||
FROM dm.purchase_vs_orders_dist;
|
||||
|
||||
-- Полный пересчет пишет новую версию каждого дня. FINAL оставляет текущие
|
||||
-- счетчики и прячет повторы запусков от потребителя.
|
||||
CREATE VIEW IF NOT EXISTS dm.daily_traffic_v ON CLUSTER clickstream_cluster
|
||||
|
||||
Reference in new issue
Block a user