FEAT : conf objets timescale OK
This commit is contained in:
parent
6f5293d325
commit
aaa63a4a8d
141
notes.md
141
notes.md
@ -14,53 +14,9 @@ exit
|
|||||||
cd /tmp
|
cd /tmp
|
||||||
scp grab-4:/tmp/backup_postgres.dump .
|
scp grab-4:/tmp/backup_postgres.dump .
|
||||||
pg_restore -c -x -t mesure -d postgres -h localhost -U postgres -W backup_postgres.dump
|
pg_restore -c -x -t mesure -d postgres -h localhost -U postgres -W backup_postgres.dump
|
||||||
pg_restore -c -x -I mesure_idx1 -d postgres -h localhost -U postgres -W backup_postgres.dump
|
# pg_restore -c -x -I mesure_idx1 -d postgres -h localhost -U postgres -W backup_postgres.dump
|
||||||
pg_restore -c -x -I mesure_idx2 -d postgres -h localhost -U postgres -W backup_postgres.dump
|
# pg_restore -c -x -I mesure_idx2 -d postgres -h localhost -U postgres -W backup_postgres.dump
|
||||||
```
|
pg_restore -c -x -t captation -d postgres -h localhost -U postgres -W backup_postgres.dump
|
||||||
|
|
||||||
### Création d'une hypertable
|
|
||||||
|
|
||||||
```sql
|
|
||||||
CREATE TABLE mesure_ng (
|
|
||||||
"date" TIMESTAMPTZ,
|
|
||||||
id_captation INT NOT NULL,
|
|
||||||
valeur float4 NOT NULL
|
|
||||||
) WITH (
|
|
||||||
tsdb.hypertable,
|
|
||||||
timescaledb.segmentby = 'id_captation',
|
|
||||||
timescaledb.orderby='date DESC'
|
|
||||||
)
|
|
||||||
|
|
||||||
INSERT INTO mesure_ng ("date", id_captation, valeur)
|
|
||||||
SELECT "date", id_captation, valeur
|
|
||||||
FROM mesure
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compression des données (stockage en colonnes)
|
|
||||||
|
|
||||||
`SELECT add_columnstore_policy('mesure_ng', INTERVAL '15 days')`
|
|
||||||
|
|
||||||
|
|
||||||
### Ex. de requête
|
|
||||||
|
|
||||||
```sql
|
|
||||||
SELECT
|
|
||||||
time_bucket('1 hour', "date") AS heure,
|
|
||||||
round(
|
|
||||||
average(
|
|
||||||
time_weight('linear', "date", valeur)
|
|
||||||
)
|
|
||||||
) AS moyenne_conso,
|
|
||||||
COUNT(*) AS nombre_de_mesures
|
|
||||||
FROM
|
|
||||||
mesure_ng
|
|
||||||
WHERE
|
|
||||||
"date" BETWEEN '2026-03-01 00:00:00' AND '2026-03-31 23:59:59'
|
|
||||||
and id_captation = 59 -- puissance PAC
|
|
||||||
GROUP BY
|
|
||||||
heure
|
|
||||||
ORDER BY
|
|
||||||
heure;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Exploit
|
### Exploit
|
||||||
@ -73,40 +29,73 @@ WHERE hypertable_name = 'mesure_ng'
|
|||||||
|
|
||||||
`SELECT * FROM timescaledb_information.jobs`
|
`SELECT * FROM timescaledb_information.jobs`
|
||||||
|
|
||||||
### Continuous aggregates (WIP)
|
### WIP
|
||||||
|
|
||||||
<https://www.tigerdata.com/docs/use-timescale/latest/continuous-aggregates/create-a-continuous-aggregate>
|
#### Grafana
|
||||||
|
|
||||||
* CREATE MATERIALIZED VIEW
|
mixe de
|
||||||
* CALL add_continuous_aggregate_policy
|
|
||||||
* supprimer les "vieilles" données de mesure_ng (add_retention_policy ?)
|
|
||||||
|
|
||||||
#### Exemples
|
sur le range :
|
||||||
|
|
||||||
##### Gauges
|
```sql
|
||||||
|
SELECT *
|
||||||
CREATE MATERIALIZED VIEW sensor_hourly
|
FROM (
|
||||||
WITH (timescaledb.continuous)
|
|
||||||
AS
|
|
||||||
SELECT
|
|
||||||
time_bucket('1 hour', time) AS bucket,
|
|
||||||
sensor_id,
|
|
||||||
average(
|
|
||||||
time_weight('linear', "date", valeur)
|
|
||||||
) AS moyenne_temporelle,
|
|
||||||
percentile_agg(value) AS pct
|
|
||||||
FROM sensor_data
|
|
||||||
GROUP BY bucket, sensor_id;
|
|
||||||
|
|
||||||
Puis
|
|
||||||
|
|
||||||
SELECT
|
SELECT
|
||||||
bucket,
|
"date" AS time,
|
||||||
sensor_id,
|
valeur
|
||||||
approx_percentile(0.95, pct) AS p95,
|
FROM mesure_gauge
|
||||||
approx_percentile(0.99, pct) AS p99
|
WHERE $__timeFilter("date")
|
||||||
FROM sensor_hourly;
|
AND $__range_s < 86400
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
"date" AS time,
|
||||||
|
average(valeur_temporelle)
|
||||||
|
FROM mesure_gauge_heure
|
||||||
|
WHERE $__timeFilter("date")
|
||||||
|
AND $__range_s BETWEEN 86400 AND 2592000
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
"date" AS time,
|
||||||
|
average(valeur_temporelle)
|
||||||
|
FROM mesure_gauge_jour
|
||||||
|
WHERE $__timeFilter("date")
|
||||||
|
AND $__range_s > 2592000
|
||||||
|
|
||||||
|
) t
|
||||||
|
ORDER BY time
|
||||||
|
```
|
||||||
|
|
||||||
|
et où est dans le passé
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT *
|
||||||
|
FROM (
|
||||||
|
|
||||||
|
-- données récentes → brut
|
||||||
|
SELECT
|
||||||
|
mg."date" AS time,
|
||||||
|
mg.valeur
|
||||||
|
FROM mesure_gauge mg
|
||||||
|
WHERE $__timeFilter(mg."date")
|
||||||
|
AND $__to > now() - interval '7 days'
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
-- données anciennes → agrégées
|
||||||
|
SELECT
|
||||||
|
mgh."date" AS time,
|
||||||
|
average(mgh.valeur_temporelle) AS valeur
|
||||||
|
FROM mesure_gauge_heure mgh
|
||||||
|
WHERE $__timeFilter(mgh."date")
|
||||||
|
AND $__to <= now() - interval '7 days'
|
||||||
|
|
||||||
|
) t
|
||||||
|
ORDER BY time;
|
||||||
|
```
|
||||||
|
|
||||||
##### Index
|
|
||||||
|
|
||||||
delta(counter_agg(time, value))
|
|
||||||
3
sql/1_type_captation.sql
Normal file
3
sql/1_type_captation.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-- pour différencier les capteurs (Gauges) des index (Compteurs)
|
||||||
|
ALTER TABLE public.captation ADD "type" varchar DEFAULT 'G' NOT NULL;
|
||||||
|
COMMENT ON COLUMN public.captation."type" IS 'G pour Gauge, C pour Compteur (index)';
|
||||||
71
sql/2_gauge.sql
Normal file
71
sql/2_gauge.sql
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
CREATE TABLE mesure_gauge ( -- TODO ; revoir précudes d'injection de données pour faire la différence entre gauge et compteur
|
||||||
|
"date" TIMESTAMPTZ,
|
||||||
|
id_captation INT NOT NULL,
|
||||||
|
valeur float4 NOT NULL
|
||||||
|
) WITH (
|
||||||
|
tsdb.hypertable,
|
||||||
|
timescaledb.segmentby = 'id_captation',
|
||||||
|
timescaledb.orderby='date DESC'
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO mesure_gauge ("date", id_captation, valeur)
|
||||||
|
SELECT m."date", m.id_captation, m.valeur
|
||||||
|
FROM mesure m
|
||||||
|
WHERE m.id_captation IN (
|
||||||
|
SELECT c.id_captation
|
||||||
|
FROM captation c
|
||||||
|
WHERE c."type" = 'G' -- TODO : prévoir cette info dans captation
|
||||||
|
);
|
||||||
|
|
||||||
|
SELECT add_retention_policy('mesure_gauge', INTERVAL '6 months'); -- on ne garde les données brutes que 6 mois
|
||||||
|
|
||||||
|
CREATE MATERIALIZED VIEW mesure_gauge_heure -- valeurs par heure
|
||||||
|
WITH (timescaledb.continuous) AS
|
||||||
|
SELECT
|
||||||
|
id_captation,
|
||||||
|
time_bucket(INTERVAL '1 HOUR', mg."date") AS "date",
|
||||||
|
time_weight('linear', mg."date", mg.valeur) AS valeur_temporelle,
|
||||||
|
MAX(mg.valeur),
|
||||||
|
MIN(mg.valeur)
|
||||||
|
FROM mesure_gauge mg
|
||||||
|
GROUP BY id_captation, time_bucket(INTERVAL '1 hour', mg."date");
|
||||||
|
|
||||||
|
SELECT add_continuous_aggregate_policy( -- On met à jour les données tt les h en relisant les données brutes entre 1 mois et 1 jour
|
||||||
|
'mesure_gauge_heure',
|
||||||
|
start_offset => INTERVAL '1 month',
|
||||||
|
end_offset => INTERVAL '1 day',
|
||||||
|
schedule_interval => INTERVAL '1 hour'
|
||||||
|
);
|
||||||
|
|
||||||
|
SELECT add_retention_policy('mesure_gauge_heure', INTERVAL '5 years'); -- on ne garde les données par h que 5 ans
|
||||||
|
|
||||||
|
CREATE MATERIALIZED VIEW mesure_gauge_jour -- valeurs par jour
|
||||||
|
WITH (timescaledb.continuous) AS
|
||||||
|
SELECT
|
||||||
|
id_captation,
|
||||||
|
time_bucket(INTERVAL '1 DAY', mg."date") AS "date",
|
||||||
|
rollup(valeur_temporelle) AS valeur_temporelle,
|
||||||
|
MAX(mg.max),
|
||||||
|
MIN(mg.min)
|
||||||
|
FROM mesure_gauge_heure mg
|
||||||
|
GROUP BY id_captation, time_bucket(INTERVAL '1 DAY', mg."date");
|
||||||
|
|
||||||
|
SELECT add_continuous_aggregate_policy( -- On met à jour les données tt les h en relisant les données brutes entre 1 mois et 1 jour
|
||||||
|
'mesure_gauge_jour',
|
||||||
|
start_offset => INTERVAL '1 month',
|
||||||
|
end_offset => INTERVAL '1 day',
|
||||||
|
schedule_interval => INTERVAL '1 hour'
|
||||||
|
);
|
||||||
|
|
||||||
|
SELECT add_retention_policy('mesure_gauge_jour', INTERVAL '20 years'); -- on ne garde les données par h que 20 ans
|
||||||
|
|
||||||
|
-- ex. select
|
||||||
|
select
|
||||||
|
mgh.id_captation,
|
||||||
|
time_bucket(INTERVAL '1 DAY', mgh."date") AS "date", -- 1 jour et pas seulement une heure
|
||||||
|
average(rollup(valeur_temporelle)) AS moyenne -- rollup pour avour le concaténation des valeur_temporelle
|
||||||
|
from mesure_gauge_heure mgh
|
||||||
|
where mgh.id_captation = 59 -- puissance PAC
|
||||||
|
group by mgh.id_captation, time_bucket(INTERVAL '1 DAY', mgh."date")
|
||||||
|
order by "date" desc
|
||||||
|
limit 1000;
|
||||||
70
sql/3_compteur.sql
Normal file
70
sql/3_compteur.sql
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
CREATE TABLE mesure_compteur ( -- TODO ; revoir précudes d'injection de données pour faire la différence entre gauge et compteur
|
||||||
|
"date" TIMESTAMPTZ,
|
||||||
|
id_captation INT NOT NULL,
|
||||||
|
valeur float4 NOT NULL
|
||||||
|
) WITH (
|
||||||
|
tsdb.hypertable,
|
||||||
|
timescaledb.segmentby = 'id_captation',
|
||||||
|
timescaledb.orderby='date DESC'
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO mesure_compteur ("date", id_captation, valeur)
|
||||||
|
SELECT m."date", m.id_captation, m.valeur
|
||||||
|
FROM mesure m
|
||||||
|
WHERE m.id_captation IN (
|
||||||
|
SELECT c.id_captation
|
||||||
|
FROM captation c
|
||||||
|
WHERE c."type" = 'C' -- TODO : prévoir cette info dans captation
|
||||||
|
);
|
||||||
|
|
||||||
|
SELECT add_retention_policy('mesure_compteur', INTERVAL '6 months'); -- on ne garde les données brutes que 6 mois
|
||||||
|
|
||||||
|
CREATE MATERIALIZED VIEW mesure_compteur_heure -- valeurs par heure
|
||||||
|
WITH (timescaledb.continuous) AS
|
||||||
|
SELECT
|
||||||
|
id_captation,
|
||||||
|
time_bucket(INTERVAL '1 hour', mc."date") AS "date",
|
||||||
|
counter_agg(mc."date", mc.valeur) AS valeur_temporelle
|
||||||
|
FROM mesure_compteur mc
|
||||||
|
GROUP BY
|
||||||
|
id_captation,
|
||||||
|
time_bucket(INTERVAL '1 hour', mc."date");
|
||||||
|
|
||||||
|
SELECT add_continuous_aggregate_policy('mesure_compteur_heure', -- On met à jour les données tt les h en relisant les données brutes entre 1 mois et 1 jour
|
||||||
|
start_offset => INTERVAL '1 month',
|
||||||
|
end_offset => INTERVAL '1 day',
|
||||||
|
schedule_interval => INTERVAL '1 hour');
|
||||||
|
|
||||||
|
SELECT add_retention_policy('mesure_compteur_heure', INTERVAL '5 years'); -- on ne garde les données par h que 5 ans
|
||||||
|
|
||||||
|
CREATE MATERIALIZED VIEW mesure_compteur_jour -- valeurs par jour
|
||||||
|
WITH (timescaledb.continuous) AS
|
||||||
|
SELECT
|
||||||
|
id_captation,
|
||||||
|
time_bucket(INTERVAL '1 DAY', mg."date") AS "date",
|
||||||
|
rollup(valeur_temporelle) AS valeur_temporelle
|
||||||
|
FROM mesure_compteur_heure mg
|
||||||
|
GROUP BY id_captation, time_bucket(INTERVAL '1 DAY', mg."date");
|
||||||
|
|
||||||
|
SELECT add_continuous_aggregate_policy( -- On met à jour les données tt les h en relisant les données brutes entre 1 mois et 1 jour
|
||||||
|
'mesure_compteur_jour',
|
||||||
|
start_offset => INTERVAL '1 month',
|
||||||
|
end_offset => INTERVAL '1 day',
|
||||||
|
schedule_interval => INTERVAL '1 hour'
|
||||||
|
);
|
||||||
|
|
||||||
|
SELECT add_retention_policy('mesure_compteur_jour', INTERVAL '20 years'); -- on ne garde les données par h que 20 ans
|
||||||
|
|
||||||
|
-- ex. select
|
||||||
|
SELECT
|
||||||
|
mch.id_captation,
|
||||||
|
time_bucket(INTERVAL '1 DAY', mch."date") AS "date", -- 1 jour et pas seulement une heure
|
||||||
|
delta(rollup(mch.valeur_temporelle)) AS consommation,
|
||||||
|
rate(rollup(mch.valeur_temporelle)) * 3600 AS debit_moyen,
|
||||||
|
irate_left(rollup(mch.valeur_temporelle)) * 3600 AS debit_instantane,
|
||||||
|
first_val(rollup(mch.valeur_temporelle)) AS index_debut,
|
||||||
|
last_val(rollup(mch.valeur_temporelle)) AS index_fin
|
||||||
|
FROM mesure_compteur_heure mch
|
||||||
|
where mch.id_captation = 89 -- HP
|
||||||
|
group by mch.id_captation, time_bucket(INTERVAL '1 DAY', mch."date")
|
||||||
|
order by "date" desc
|
||||||
7
sql/4_drop.sql
Normal file
7
sql/4_drop.sql
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
DROP MATERIALIZED VIEW IF EXISTS mesure_gauge_jour;
|
||||||
|
DROP MATERIALIZED VIEW IF EXISTS mesure_gauge_heure;
|
||||||
|
DROP TABLE IF EXISTS mesure_gauge;
|
||||||
|
|
||||||
|
DROP MATERIALIZED VIEW IF EXISTS mesure_compteur_jour;
|
||||||
|
DROP MATERIALIZED VIEW IF EXISTS mesure_compteur_jour;
|
||||||
|
DROP TABLE IF EXISTS mesure_compteur;
|
||||||
Loading…
Reference in New Issue
Block a user