规范化的最佳实践
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 | | |
将 host
和 location
规范化为单独的(非超)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');
当您决定时,如果最好将 host
和 location
值存储在 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;
我想知道是否有关于时间序列数据规范化的最佳实践。 我在 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 | | |
将 host
和 location
规范化为单独的(非超)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');
当您决定时,如果最好将 host
和 location
值存储在 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;