From 97d55ac2672487c8eb6c074584d25d961e7cee04 Mon Sep 17 00:00:00 2001 From: dr0zd Date: Thu, 29 Jan 2026 04:46:45 +0700 Subject: [PATCH] OS-314 fixes because I've broken full git struct --- mdrozdov/greenplum/core_layer.sql | 111 ++++++++++++++++++++++++++++++ mdrozdov/greenplum/dm_layer.sql | 71 +++++++++++++++++++ mdrozdov/greenplum/raw_layer.sql | 44 ++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 mdrozdov/greenplum/core_layer.sql create mode 100644 mdrozdov/greenplum/dm_layer.sql create mode 100644 mdrozdov/greenplum/raw_layer.sql diff --git a/mdrozdov/greenplum/core_layer.sql b/mdrozdov/greenplum/core_layer.sql new file mode 100644 index 0000000..557e771 --- /dev/null +++ b/mdrozdov/greenplum/core_layer.sql @@ -0,0 +1,111 @@ +-- Измерение пользователей + CREATE TABLE core.dim_user ( + user_id INT PRIMARY KEY, + name TEXT, + age INT, + email TEXT, + registration_date DATE + ) + distributed by (user_id); + + -- Измерение курсов + CREATE TABLE core.dim_course ( + course_id INT PRIMARY KEY, + title TEXT, + category TEXT + ) + distributed by (course_id); + + -- Измерение уроков + CREATE TABLE core.dim_lesson ( + lesson_id INT PRIMARY KEY, + title TEXT, + duration_min INT, + course_id INT REFERENCES core.dim_course(course_id) + ) + distributed by (lesson_id); + + -- Опционально: измерение времени + CREATE TABLE core.dim_date ( + date DATE PRIMARY KEY, + year INT, + month INT, + day INT, + weekday TEXT + ) + distributed replicated; + + -- Таблицы фактов: + CREATE TABLE core.fact_lesson_views ( + user_id INT REFERENCES core.dim_user(user_id), + lesson_id INT REFERENCES core.dim_lesson(lesson_id), + course_id INT REFERENCES core.dim_course(course_id), + viewed_at TIMESTAMP + ) + distributed by (course_id); + + CREATE TABLE core.enrollments ( + user_id INT REFERENCES core.dim_user(user_id), + course_id INT REFERENCES core.dim_course(course_id), + enrolled_at TIMESTAMP + ) + distributed by (course_id); + + --ETL переброс данных из raw в core + INSERT INTO core.dim_user (user_id, name, age, email, registration_date) + SELECT DISTINCT + id::INT, + name::TEXT, + age::INT, + email::TEXT, + registration_date::DATE + FROM raw.users; + + INSERT INTO core.dim_course (course_id, title, category) + SELECT DISTINCT + id::INT, + title::TEXT, + category::TEXT + FROM raw.courses; + + INSERT INTO core.dim_lesson (lesson_id, title, duration_min, course_id) + SELECT DISTINCT + id::INT, + title::TEXT, + duration_min::INT, + course_id::INT + FROM raw.lessons; + + INSERT INTO core.dim_lesson (lesson_id, title, duration_min, course_id) + SELECT DISTINCT + id::INT, + title::TEXT, + duration_min::INT, + course_id::INT + FROM raw.lessons; + + -- Заполнение таблицы фактов + insert into core.fact_lesson_views (user_id, lesson_id, course_id, viewed_at) + select + lw.user_id, + lw.lesson_id, + l.course_id, + lw.viewed_at + from raw.lessons_views lw + join raw.lessons l on lw.lesson_id = l.id; + + insert into core.enrollments (user_id, lesson_id, course_id, viewed_at) + select + lw.user_id, + lw.lesson_id, + l.course_id, + lw.viewed_at + from raw.lessons_views lw + join raw.lessons l on lw.lesson_id = l.id; + + insert into enrollments (user_id, course_id, enrolled_at) + select + user_id, + course_id, + enrolled_at + from raw.enrollments; \ No newline at end of file diff --git a/mdrozdov/greenplum/dm_layer.sql b/mdrozdov/greenplum/dm_layer.sql new file mode 100644 index 0000000..991db90 --- /dev/null +++ b/mdrozdov/greenplum/dm_layer.sql @@ -0,0 +1,71 @@ +--lesson_popularity_summary data mart + create materialized view dm.lesson_popularity_summary as + select + dl.lesson_id, + dl.title as lesson_title, + dl.course_id, + dc.title as course_title, + count(flv.lesson_id) as total_views, + count(distinct flv.user_id) as unique_users, + min(flv.viewed_at) as first_view, + max(flv.viewed_at) as last_view + from core.dim_lesson dl + left join core.dim_course dc + on dl.course_id = dc.course_id + left join core.fact_lesson_views flv + on dl.lesson_id = flv.lesson_id + group by dl.lesson_id, dl.title, dl.course_id, dc.title + + -- inactive_users_summary data mart + create materialized view dm.inactive_users_summary as + select + du.user_id, + du.name as user_name, + du.email, + du.age, + count(e.course_id) as enrollments_count, + du.registration_date + from core.dim_user du + left join core.enrollments e + on du.user_id = e.user_id + left join core.fact_lesson_views flv + on du.user_id = flv.user_id + where flv.user_id is null + group by du.user_id, du.name, du.email, du.age, du.registration_date + + -- course_completion_rate data mart + create materialized view dm.course_completion_rate as + with total_lessons_per_course as( + select + course_id, + count(*) as lessons_in_course + from core.dim_lesson + group by course_id + ), lessons_viewed as ( + select + user_id, + course_id, + count(*) as lessons_viewed + from fact_lesson_views flv + group by user_id, course_id + ) + select + du.user_id as user_id, + du.name as user_name, + dc.course_id as course_id, + dc.title as course_title, + tlpc.lessons_in_course, + coalesce(lv.lessons_viewed, 0) as lessons_viewed, + round( + coalesce( + coalesce(lv.lessons_viewed, 0)*1.0/nullif(tlpc.lessons_in_course, 0), 0 + ), 2) as completion_rate + from core.enrollments e + join core.dim_user du + on e.user_id = du.user_id + join total_lessons_per_course tlpc + on tlpc.course_id = e.course_id + join core.dim_course dc + on e.course_id = dc.course_id + left join lessons_viewed lv + on du.user_id = lv.user_id and dc.course_id = lv.course_id \ No newline at end of file diff --git a/mdrozdov/greenplum/raw_layer.sql b/mdrozdov/greenplum/raw_layer.sql new file mode 100644 index 0000000..d2ab8c9 --- /dev/null +++ b/mdrozdov/greenplum/raw_layer.sql @@ -0,0 +1,44 @@ +create schema raw; + create schema core; + create schema dm; + + create table raw.users( + id INT, + name varchar(50), + age INT, + email varchar(50), + registration_date date + ) + distributed by (id); + + create table raw.courses ( + id INT, + title text, + category varchar(40), + created_at date + ) + distributed by (id); + + create table raw.lessons ( + id INT, + course_id INT, + title TEXT, + duration_min INT + ) + distributed by (course_id); + + create table raw.enrollments ( + id INT, + user_id INT, + course_id INT, + enrolled_at date + ) + distributed by (user_id); + + create table raw.lessons_views( + id int, + user_id int, + lesson_id int, + viewed_at timestamp + ) + distributed by (user_id) \ No newline at end of file