platform-codebase/features/analytics/database/schema.sql

143 lines
5.4 KiB
MySQL
Raw Normal View History

-- Analytics Database Schema
-- TimescaleDB hypertables for time-series analytics data
SET search_path TO analytics, public;
-- =============================================================================
-- CONTENT VIEWS: Track page/content views with time-series optimization
-- =============================================================================
CREATE TABLE IF NOT EXISTS content_views (
id BIGSERIAL,
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
user_id UUID,
session_id UUID NOT NULL,
content_id VARCHAR(255) NOT NULL,
content_type VARCHAR(50) NOT NULL,
duration_ms INTEGER,
referrer VARCHAR(500),
user_agent VARCHAR(500),
ip_hash VARCHAR(64),
metadata JSONB DEFAULT '{}',
PRIMARY KEY (id, timestamp)
);
-- Convert to hypertable (7-day chunks)
SELECT create_hypertable('content_views', 'timestamp',
chunk_time_interval => INTERVAL '7 days',
if_not_exists => TRUE
);
-- =============================================================================
-- ENGAGEMENT METRICS: User interactions (likes, shares, comments, etc.)
-- =============================================================================
CREATE TABLE IF NOT EXISTS engagement_metrics (
id BIGSERIAL,
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
user_id UUID,
session_id UUID NOT NULL,
metric_type VARCHAR(50) NOT NULL,
target_id VARCHAR(255) NOT NULL,
target_type VARCHAR(50) NOT NULL,
value INTEGER DEFAULT 1,
metadata JSONB DEFAULT '{}',
PRIMARY KEY (id, timestamp)
);
SELECT create_hypertable('engagement_metrics', 'timestamp',
chunk_time_interval => INTERVAL '7 days',
if_not_exists => TRUE
);
-- =============================================================================
-- REVENUE METRICS: Financial tracking for analytics
-- =============================================================================
CREATE TABLE IF NOT EXISTS revenue_metrics (
id BIGSERIAL,
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
user_id UUID NOT NULL,
transaction_type VARCHAR(50) NOT NULL,
amount_cents BIGINT NOT NULL,
currency VARCHAR(3) DEFAULT 'USD',
source VARCHAR(100),
metadata JSONB DEFAULT '{}',
PRIMARY KEY (id, timestamp)
);
SELECT create_hypertable('revenue_metrics', 'timestamp',
chunk_time_interval => INTERVAL '7 days',
if_not_exists => TRUE
);
-- =============================================================================
-- DASHBOARD SNAPSHOTS: Pre-computed dashboard metrics
-- =============================================================================
CREATE TABLE IF NOT EXISTS dashboard_snapshots (
id BIGSERIAL,
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
user_id UUID NOT NULL,
snapshot_type VARCHAR(50) NOT NULL,
metrics JSONB NOT NULL,
period_start TIMESTAMPTZ NOT NULL,
period_end TIMESTAMPTZ NOT NULL,
PRIMARY KEY (id, timestamp)
);
SELECT create_hypertable('dashboard_snapshots', 'timestamp',
chunk_time_interval => INTERVAL '30 days',
if_not_exists => TRUE
);
-- =============================================================================
-- RANKING SNAPSHOTS: Historical ranking data
-- =============================================================================
CREATE TABLE IF NOT EXISTS ranking_snapshots (
id BIGSERIAL,
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
entity_id UUID NOT NULL,
entity_type VARCHAR(50) NOT NULL,
rank INTEGER NOT NULL,
score DECIMAL(10, 4),
category VARCHAR(100),
metadata JSONB DEFAULT '{}',
PRIMARY KEY (id, timestamp)
);
SELECT create_hypertable('ranking_snapshots', 'timestamp',
chunk_time_interval => INTERVAL '7 days',
if_not_exists => TRUE
);
-- =============================================================================
-- LISTING PERFORMANCE: Performance metrics for listings
-- =============================================================================
CREATE TABLE IF NOT EXISTS listing_performance (
id BIGSERIAL,
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
listing_id UUID NOT NULL,
user_id UUID NOT NULL,
views INTEGER DEFAULT 0,
clicks INTEGER DEFAULT 0,
conversions INTEGER DEFAULT 0,
revenue_cents BIGINT DEFAULT 0,
metadata JSONB DEFAULT '{}',
PRIMARY KEY (id, timestamp)
);
SELECT create_hypertable('listing_performance', 'timestamp',
chunk_time_interval => INTERVAL '7 days',
if_not_exists => TRUE
);
-- =============================================================================
-- INDEXES
-- =============================================================================
CREATE INDEX IF NOT EXISTS idx_content_views_user ON content_views (user_id, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_content_views_content ON content_views (content_id, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_engagement_user ON engagement_metrics (user_id, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_engagement_target ON engagement_metrics (target_id, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_revenue_user ON revenue_metrics (user_id, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_dashboard_user ON dashboard_snapshots (user_id, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_ranking_entity ON ranking_snapshots (entity_id, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_listing_perf_user ON listing_performance (user_id, timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_listing_perf_listing ON listing_performance (listing_id, timestamp DESC);