33 lines
1.3 KiB
SQL
33 lines
1.3 KiB
SQL
-- 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');
|