-- TimescaleDB schema for MQTT telemetry ingestion. -- Executed automatically on first container start. CREATE EXTENSION IF NOT EXISTS timescaledb; CREATE TABLE IF NOT EXISTS telemetry ( time TIMESTAMPTZ NOT NULL, topic TEXT NOT NULL, device_id TEXT, payload JSONB NOT NULL ); -- Convert to hypertable for time-series storage. SELECT create_hypertable('telemetry', 'time', if_not_exists => TRUE); -- Indexes for common query patterns. -- (topic, time) and (device_id, time) serve the filtered API queries; -- a bare (time) index serves the unfiltered /telemetry/latest lookup, -- which would otherwise require a full backward scan of the hypertable. CREATE INDEX IF NOT EXISTS idx_telemetry_topic_time ON telemetry (topic, time DESC); CREATE INDEX IF NOT EXISTS idx_telemetry_device_time ON telemetry (device_id, time DESC); CREATE INDEX IF NOT EXISTS idx_telemetry_time ON telemetry (time DESC); -- Compression: older chunks are squeezed on a background schedule. ALTER TABLE telemetry SET ( timescaledb.compress, timescaledb.compress_segmentby = 'topic, device_id' ); -- Compress chunks older than 7 days, drop data older than 1 year. SELECT add_compression_policy('telemetry', INTERVAL '7 days'); SELECT add_retention_policy('telemetry', INTERVAL '365 days');