timescaledb - 规范化的最佳实践
问题描述
我想知道是否有关于时间序列数据标准化的最佳实践。我在 TimescaleDB 中有一个超表,看起来像这样
Table "public.mainsfrequency"
Column | Type | Collation | Nullable | Default
----------+-----------------------------+-----------+----------+---------
time | timestamp without time zone | | not null |
host | text | | |
location | text | | |
freq | double precision | | |
host
规范化并location
分成单独的(非超)表并在上述超表中使用外键是一个好主意吗?我读过不支持使用外键引用超表,但是另一个方向呢?
解决方案
正确,它可以在超表内创建外键以引用普通(非超)表,但不相反。所以这将起作用:
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
值还是将其移动到单独的表中更好时,请考虑将存储多少数据、值的唯一性、如何查询数据以及如何使用超表。
例如,如果文本重复很多,则每行重复的主机名和位置文本将比存储在单独的表中占用更多的空间。但是,如果您将使用压缩,那么您可以节省大量空间,同时将值保留在超表中。
如果您将使用连续聚合来计算和存储聚合,那么您只能使用存储在超表中的值,因为连续聚合不支持连接。例如,如果您想具体化某些位置的聚合,那么如果该位置存储在单独的表中,则无法完成。
因此,以下查询不能放入连续聚合中:
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;
推荐阅读
- sql - 如何在 SQL 中使用 Min(date) 过滤掉 Case Statement 中的记录?
- angular - Angular:NgStyle使用input :: first-line突出显示文本框中的单词?
- node.js - 部署后 AWS 弹性 beanstalk Express 服务 502 Bad Gateway
- python - 无法抓取动态内容(带有启动设置的抓取)
- javascript - 来自存储过程的消息到视图中的警报框
- android - SYSTEM_ALERT_WINDOW 的替代方案,用于显示跨应用活动的覆盖
- node.js - 如何将 Cypher 查询导入我的 Node.js 逻辑?
- python - 无循环处理数据帧
- sql - Teradata SQL 格式化十进制字段
- python - 由嵌入的子节点产生的 Elementtree 重复