规范化的最佳实践

Best practice on normalization

我想知道是否有关于时间序列数据规范化的最佳实践。 我在 TimescaleDB 中有一个 hyper table 看起来像这样

                      Table "public.mainsfrequency"
  Column  |            Type             | Collation | Nullable | Default
----------+-----------------------------+-----------+----------+---------
 time     | timestamp without time zone |           | not null |
 host     | text                        |           |          |
 location | text                        |           |          |
 freq     | double precision            |           |          |

hostlocation 规范化为单独的(非超)table 并在上述超 table 中使用外键是否是个好主意?我读到不支持使用外键引用超级 table,但是另一个方向呢?

正确,它可以在 hypertable 中创建外键以引用普通(非 hyper)table,但不是相反。所以这会起作用:

CREATE TABLE host(
  id INT PRIMARY KEY,
  host TEXT,
  location TEXT
);
CREATE TABLE mainsfrequency(
  time TIMESTAMP NOT NULL,
  host_id INT REFERENCES hosts(host_id),
  freq DOUBLE PRECISION
);
SELECT create_hypertable('mainsfrequency','time');

当您决定时,如果最好将 hostlocation 值存储在 hypertable 中或将其移动到单独的 table 中,请考虑需要多少数据存储、值的唯一性、查询数据的方式以及 hypertables 的使用方式。

例如,如果文本重复很多,则每行重复主机名和位置的文本将比存储在单独的 table 中占用更多 space。但是,如果您将使用 compression,那么您可以节省很多 space,同时保留 hypertable.

中的值

如果您将使用 continuous aggregates 来计算和存储聚合,那么您只能使用存储在 hypertable 中的值,因为连续聚合不支持连接。例如,如果您想具体化某些位置的聚合,那么如果该位置存储在单独的 table.

中则无法完成

因此不能将以下查询放入连续聚合中:

SELECT time_bucket(INTERVAL '1h', time), host, AVG(freq)
FROM mainsfrequency, host
WHERE host_id = id AND location = 'NY'
GROUP BY 1, 2;

要在连续聚合中进行此类查询,它将是:

CREATE TABLE mainsfrequency(
  time TIMESTAMP NOT NULL,
  host TEXT,
  location TEXT,
  freq DOUBLE PRECISION
);
SELECT create_hypertable('mainsfrequency','time');

CREATE MATERIALIZED VIEW mainsfrequency_hourly
WITH (timescaledb.continuous) AS
SELECT time_bucket(INTERVAL '1h', time), host, AVG(freq)
FROM mainsfrequency
WHERE location = 'NY'
GROUP BY 1, 2;