106 lines
4.1 KiB
SQL
106 lines
4.1 KiB
SQL
-- Migration: Create database schema for play-life project
|
||
-- This script creates all tables and materialized views needed for the project
|
||
|
||
-- ============================================
|
||
-- Table: projects
|
||
-- ============================================
|
||
CREATE TABLE IF NOT EXISTS projects (
|
||
id SERIAL PRIMARY KEY,
|
||
name VARCHAR(255) NOT NULL,
|
||
priority SMALLINT,
|
||
CONSTRAINT unique_project_name UNIQUE (name)
|
||
);
|
||
|
||
-- ============================================
|
||
-- Table: entries
|
||
-- ============================================
|
||
-- This table stores entries with creation dates
|
||
-- Used in weekly_report_mv for grouping by week
|
||
CREATE TABLE IF NOT EXISTS entries (
|
||
id SERIAL PRIMARY KEY,
|
||
text TEXT NOT NULL,
|
||
created_date TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
-- ============================================
|
||
-- Table: nodes
|
||
-- ============================================
|
||
-- This table stores nodes linked to projects and entries
|
||
-- Contains score information used in weekly reports
|
||
CREATE TABLE IF NOT EXISTS nodes (
|
||
id SERIAL PRIMARY KEY,
|
||
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
||
entry_id INTEGER NOT NULL REFERENCES entries(id) ON DELETE CASCADE,
|
||
score NUMERIC(8,4)
|
||
);
|
||
|
||
-- Create index on project_id for better join performance
|
||
CREATE INDEX IF NOT EXISTS idx_nodes_project_id ON nodes(project_id);
|
||
-- Create index on entry_id for better join performance
|
||
CREATE INDEX IF NOT EXISTS idx_nodes_entry_id ON nodes(entry_id);
|
||
|
||
-- ============================================
|
||
-- Table: weekly_goals
|
||
-- ============================================
|
||
-- This table stores weekly goals for projects
|
||
CREATE TABLE IF NOT EXISTS weekly_goals (
|
||
id SERIAL PRIMARY KEY,
|
||
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
||
goal_year INTEGER NOT NULL,
|
||
goal_week INTEGER NOT NULL,
|
||
min_goal_score NUMERIC(10,4) NOT NULL DEFAULT 0,
|
||
max_goal_score NUMERIC(10,4),
|
||
actual_score NUMERIC(10,4) DEFAULT 0,
|
||
priority SMALLINT,
|
||
CONSTRAINT weekly_goals_project_id_goal_year_goal_week_key UNIQUE (project_id, goal_year, goal_week)
|
||
);
|
||
|
||
-- Create index on project_id for better join performance
|
||
CREATE INDEX IF NOT EXISTS idx_weekly_goals_project_id ON weekly_goals(project_id);
|
||
|
||
-- ============================================
|
||
-- Materialized View: weekly_report_mv
|
||
-- ============================================
|
||
CREATE MATERIALIZED VIEW IF NOT EXISTS weekly_report_mv AS
|
||
SELECT
|
||
p.id AS project_id,
|
||
agg.report_year,
|
||
agg.report_week,
|
||
-- Используем COALESCE для установки total_score в 0.0000, если нет данных (NULL)
|
||
COALESCE(agg.total_score, 0.0000) AS total_score
|
||
FROM
|
||
projects p
|
||
LEFT JOIN
|
||
(
|
||
-- 1. Предварительная агрегация: суммируем score по неделям
|
||
SELECT
|
||
n.project_id,
|
||
EXTRACT(YEAR FROM e.created_date)::INTEGER AS report_year,
|
||
EXTRACT(WEEK FROM e.created_date)::INTEGER AS report_week,
|
||
SUM(n.score) AS total_score
|
||
FROM
|
||
nodes n
|
||
JOIN
|
||
entries e ON n.entry_id = e.id
|
||
GROUP BY
|
||
1, 2, 3
|
||
) agg
|
||
-- 2. Присоединяем агрегированные данные ко ВСЕМ проектам
|
||
ON p.id = agg.project_id
|
||
ORDER BY
|
||
p.id, agg.report_year, agg.report_week;
|
||
|
||
-- Create index on materialized view for better query performance
|
||
CREATE INDEX IF NOT EXISTS idx_weekly_report_mv_project_year_week
|
||
ON weekly_report_mv(project_id, report_year, report_week);
|
||
|
||
-- ============================================
|
||
-- Comments for documentation
|
||
-- ============================================
|
||
COMMENT ON TABLE projects IS 'Projects table storing project information with priority';
|
||
COMMENT ON TABLE entries IS 'Entries table storing entry creation timestamps';
|
||
COMMENT ON TABLE nodes IS 'Nodes table linking projects, entries and storing scores';
|
||
COMMENT ON TABLE weekly_goals IS 'Weekly goals for projects';
|
||
COMMENT ON MATERIALIZED VIEW weekly_report_mv IS 'Materialized view aggregating weekly scores by project';
|
||
|