-- ============================================================= -- V002__timescale_hypertables.sql -- EMS Platform – vytvoření TimescaleDB hypertable pro časové série -- Spouštět po V001 a po instalaci TimescaleDB extension -- ============================================================= CREATE EXTENSION IF NOT EXISTS timescaledb; -- Telemetrie střídače – 1min záznamy, partitioning po 1 týdnu SELECT create_hypertable( 'ems.telemetry_inverter', 'measured_at', chunk_time_interval => INTERVAL '1 week', if_not_exists => TRUE ); -- Telemetrie EV nabíječek SELECT create_hypertable( 'ems.telemetry_ev_charger', 'measured_at', chunk_time_interval => INTERVAL '1 week', if_not_exists => TRUE ); -- Telemetrie tepelného čerpadla SELECT create_hypertable( 'ems.telemetry_heat_pump', 'measured_at', chunk_time_interval => INTERVAL '1 week', if_not_exists => TRUE ); -- Spotové ceny – 15min záznamy, partitioning po 1 měsíci SELECT create_hypertable( 'ems.market_interval_price', 'interval_start', chunk_time_interval => INTERVAL '1 month', if_not_exists => TRUE ); -- FVE predikce – 15min záznamy SELECT create_hypertable( 'ems.forecast_pv_interval', 'interval_start', chunk_time_interval => INTERVAL '1 month', if_not_exists => TRUE ); -- Predikce počasí SELECT create_hypertable( 'ems.forecast_weather_interval', 'interval_start', chunk_time_interval => INTERVAL '1 month', if_not_exists => TRUE ); -- Audit SELECT create_hypertable( 'ems.audit_interval', 'interval_start', chunk_time_interval => INTERVAL '1 month', if_not_exists => TRUE ); -- Bazální spotřeba SELECT create_hypertable( 'ems.consumption_baseline_interval', 'interval_start', chunk_time_interval => INTERVAL '1 month', if_not_exists => TRUE ); -- ============================================================ -- Kompresní politiky pro staré chunky -- Telemetrie starší 30 dní komprimovat (čtení stačí) -- Nutné nejdřív zapnout kompresi na hypertable (TimescaleDB 2.x+ / Tiger Data), -- jinak add_compression_policy hlásí chybu o columnstore / compression. -- ============================================================ ALTER TABLE ems.telemetry_inverter SET ( timescaledb.compress, timescaledb.compress_orderby = 'measured_at DESC', timescaledb.compress_segmentby = 'site_id, inverter_id' ); ALTER TABLE ems.telemetry_ev_charger SET ( timescaledb.compress, timescaledb.compress_orderby = 'measured_at DESC', timescaledb.compress_segmentby = 'site_id, charger_id, connector_id' ); ALTER TABLE ems.telemetry_heat_pump SET ( timescaledb.compress, timescaledb.compress_orderby = 'measured_at DESC', timescaledb.compress_segmentby = 'site_id, heat_pump_id' ); ALTER TABLE ems.market_interval_price SET ( timescaledb.compress, timescaledb.compress_orderby = 'interval_start DESC', timescaledb.compress_segmentby = 'market_source' ); SELECT add_compression_policy('ems.telemetry_inverter', INTERVAL '30 days', if_not_exists => TRUE); SELECT add_compression_policy('ems.telemetry_ev_charger', INTERVAL '30 days', if_not_exists => TRUE); SELECT add_compression_policy('ems.telemetry_heat_pump', INTERVAL '30 days', if_not_exists => TRUE); SELECT add_compression_policy('ems.market_interval_price', INTERVAL '90 days', if_not_exists => TRUE);