cloud creation

This commit is contained in:
Первов Артем
2026-06-17 09:36:58 +03:00
commit 123bd97018
46 changed files with 12285 additions and 0 deletions

View File

@@ -0,0 +1,199 @@
CREATE EXTENSION IF NOT EXISTS timescaledb;
CREATE TABLE IF NOT EXISTS edge (
id text PRIMARY KEY,
name text NOT NULL,
parent_id text REFERENCES edge(id) ON DELETE RESTRICT,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS tag (
id text PRIMARY KEY,
name text NOT NULL,
tag_group text,
min_value double precision,
max_value double precision,
unit_of_measurement text,
comment text,
precision smallint,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS edge_tag (
edge_id text NOT NULL REFERENCES edge(id) ON DELETE CASCADE,
tag_id text NOT NULL REFERENCES tag(id) ON DELETE CASCADE,
created_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (edge_id, tag_id)
);
CREATE TABLE IF NOT EXISTS history_points (
time timestamptz NOT NULL,
edge_id text NOT NULL,
tag_id text NOT NULL,
value double precision NOT NULL,
received_at timestamptz NOT NULL DEFAULT now()
);
SELECT create_hypertable(
'history_points',
'time',
chunk_time_interval => INTERVAL '1 day',
if_not_exists => TRUE
);
CREATE INDEX IF NOT EXISTS history_points_edge_tag_time_desc_idx
ON history_points (edge_id, tag_id, time DESC)
INCLUDE (value);
CREATE INDEX IF NOT EXISTS history_points_time_brin_idx
ON history_points USING brin (time);
CREATE TABLE IF NOT EXISTS current_values (
edge_id text NOT NULL,
tag_id text NOT NULL,
value double precision NOT NULL,
time timestamptz NOT NULL,
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (edge_id, tag_id)
);
CREATE INDEX IF NOT EXISTS current_values_updated_at_idx
ON current_values (updated_at DESC);
ALTER TABLE history_points SET (
timescaledb.compress,
timescaledb.compress_segmentby = 'edge_id,tag_id',
timescaledb.compress_orderby = 'time DESC'
);
SELECT add_compression_policy(
'history_points',
INTERVAL '7 days',
if_not_exists => TRUE
);
CREATE MATERIALIZED VIEW IF NOT EXISTS history_1m
WITH (timescaledb.continuous) AS
SELECT
time_bucket(INTERVAL '1 minute', time) AS bucket,
edge_id,
tag_id,
first(value, time) AS first_value,
min(value) AS min_value,
max(value) AS max_value,
avg(value) AS avg_value,
last(value, time) AS last_value,
count(*)::integer AS point_count
FROM history_points
GROUP BY bucket, edge_id, tag_id
WITH NO DATA;
CREATE MATERIALIZED VIEW IF NOT EXISTS history_5m
WITH (timescaledb.continuous) AS
SELECT
time_bucket(INTERVAL '5 minutes', time) AS bucket,
edge_id,
tag_id,
first(value, time) AS first_value,
min(value) AS min_value,
max(value) AS max_value,
avg(value) AS avg_value,
last(value, time) AS last_value,
count(*)::integer AS point_count
FROM history_points
GROUP BY bucket, edge_id, tag_id
WITH NO DATA;
CREATE MATERIALIZED VIEW IF NOT EXISTS history_1h
WITH (timescaledb.continuous) AS
SELECT
time_bucket(INTERVAL '1 hour', time) AS bucket,
edge_id,
tag_id,
first(value, time) AS first_value,
min(value) AS min_value,
max(value) AS max_value,
avg(value) AS avg_value,
last(value, time) AS last_value,
count(*)::integer AS point_count
FROM history_points
GROUP BY bucket, edge_id, tag_id
WITH NO DATA;
CREATE MATERIALIZED VIEW IF NOT EXISTS history_1d
WITH (timescaledb.continuous) AS
SELECT
time_bucket(INTERVAL '1 day', time) AS bucket,
edge_id,
tag_id,
first(value, time) AS first_value,
min(value) AS min_value,
max(value) AS max_value,
avg(value) AS avg_value,
last(value, time) AS last_value,
count(*)::integer AS point_count
FROM history_points
GROUP BY bucket, edge_id, tag_id
WITH NO DATA;
CREATE INDEX IF NOT EXISTS history_1m_edge_tag_bucket_idx
ON history_1m (edge_id, tag_id, bucket DESC);
CREATE INDEX IF NOT EXISTS history_5m_edge_tag_bucket_idx
ON history_5m (edge_id, tag_id, bucket DESC);
CREATE INDEX IF NOT EXISTS history_1h_edge_tag_bucket_idx
ON history_1h (edge_id, tag_id, bucket DESC);
CREATE INDEX IF NOT EXISTS history_1d_edge_tag_bucket_idx
ON history_1d (edge_id, tag_id, bucket DESC);
DO $$
BEGIN
PERFORM add_continuous_aggregate_policy(
'history_1m',
start_offset => INTERVAL '7 days',
end_offset => INTERVAL '1 minute',
schedule_interval => INTERVAL '1 minute'
);
EXCEPTION
WHEN duplicate_object THEN NULL;
END $$;
DO $$
BEGIN
PERFORM add_continuous_aggregate_policy(
'history_5m',
start_offset => INTERVAL '30 days',
end_offset => INTERVAL '5 minutes',
schedule_interval => INTERVAL '5 minutes'
);
EXCEPTION
WHEN duplicate_object THEN NULL;
END $$;
DO $$
BEGIN
PERFORM add_continuous_aggregate_policy(
'history_1h',
start_offset => INTERVAL '180 days',
end_offset => INTERVAL '1 hour',
schedule_interval => INTERVAL '15 minutes'
);
EXCEPTION
WHEN duplicate_object THEN NULL;
END $$;
DO $$
BEGIN
PERFORM add_continuous_aggregate_policy(
'history_1d',
start_offset => INTERVAL '5 years',
end_offset => INTERVAL '1 day',
schedule_interval => INTERVAL '1 hour'
);
EXCEPTION
WHEN duplicate_object THEN NULL;
END $$;

View File

@@ -0,0 +1,4 @@
CREATE TABLE IF NOT EXISTS app_migrations (
id text PRIMARY KEY,
applied_at timestamptz NOT NULL DEFAULT now()
);