替代 hypertable 和 'normal' table 之间的多对多关系
Alternative for a many to many relation between a hypertable and a 'normal' table
我正在尝试在名称为 'measurements' 的超级 table 和名称为 'recipe' 的 table 之间创建多对多关系。
一个测量可以有多个配方,一个配方可以连接到多个测量。
DROP TABLE IF EXISTS measurement_ms;
CREATE TABLE IF NOT EXISTS measurement_ms
(
id SERIAL,
value VARCHAR(255) NULL,
timestamp TIMESTAMP(6) NOT NULL,
machine_id INT NOT NULL,
measurement_type_id INT NOT NULL,
point_of_measurement_id INT NOT NULL,
FOREIGN KEY (machine_id) REFERENCES machine (id),
FOREIGN KEY (measurement_type_id) REFERENCES measurement_type (id),
FOREIGN KEY (point_of_measurement_id) REFERENCES point_of_measurement (id),
PRIMARY KEY (id, timestamp)
);
CREATE INDEX ON measurement_ms (machine_id, timestamp ASC);
CREATE INDEX ON measurement_ms (measurement_type_id, timestamp ASC);
CREATE INDEX ON measurement_ms (point_of_measurement_id, timestamp ASC);
-- --------------------------------------------------------------------------
-- Create timescale hypertable
-- --------------------------------------------------------------------------
SELECT create_hypertable('measurement_ms', 'timestamp', chunk_time_interval => interval '1 day');
DROP TABLE IF EXISTS recipe;
CREATE TABLE IF NOT EXISTS recipe
(
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
type VARCHAR(255) NOT NULL,
code INT NOT NULL
);
DROP TABLE IF EXISTS measurement_recipe;
CREATE TABLE IF NOT EXISTS measurement_recipe
(
id SERIAL PRIMARY KEY,
measurement_id INT NOT NULL,
recipe_id INT NOT NULL
FOREIGN KEY (recipe_id) REFERENCES recipe(id),
FOREIGN KEY (measurement_id) REFERENCES measurement_ms(id)
);
CREATE INDEX fk_measurement_recipe_measurement ON measurement_recipe (measurement_id ASC);
CREATE INDEX fk_measurement_recipe_recipe ON measurement_recipe (recipe_id ASC);
如上所示的SQL脚本就是我要连接的table。由于时间尺度的限制,上述解决方案不起作用。
Timescale 具有不能使用 hypertable 值作为外键的约束。
是否有替代解决方案可以在 table 之间创建多对多关系而不实际使用多对多关系。
TimescaleDB 专为时间序列数据而设计,其中每个点通常附加到某个时刻并包含所有相关数据。 link 每个指向已经存在的元数据是很常见的,但是,相反的做法并不常见。 TimescaleDB 通过分块数据针对时间序列数据进行了优化,因此 DML 和许多 select 查询不需要触及所有块。但是,将外键约束维护到 hypertable 中可能需要在每次插入引用时触及所有块 table measurement_recipe
.
问题的用例是具有复杂测量值的时间序列。提议的模式似乎是原始模式的规范化。我想它简化了测量数据的查询。我看到两种处理复杂测量的方法:
- 在JSONB 或数组等复杂结构的帮助下,保持数据非规范化并将配方和测量值存储在
measurement
table 中的单行或几行中。缺点是有些查询将很难编写,并且可能无法定义一些连续聚合。
- 按照问题中的建议进行规范化,但不要强制外键约束。它将允许存储引用值,可用于连接 tables。由于规范化是作为转换输入的复杂数据的一个步骤自动完成的,如果转换代码中没有错误,约束将被保留。可以通过回归测试来防止错误。仍然使用规范化模式,将不可能使用连续聚合,因为不允许连接(维护具有连接的连续聚合可能需要接触所有块)。
我的建议是选择选项 1 并尝试在其中变得聪明。我没有好的建议,因为不清楚 JSON 中的原始数据结构是什么,以及查询是什么。
我正在尝试在名称为 'measurements' 的超级 table 和名称为 'recipe' 的 table 之间创建多对多关系。
一个测量可以有多个配方,一个配方可以连接到多个测量。
DROP TABLE IF EXISTS measurement_ms;
CREATE TABLE IF NOT EXISTS measurement_ms
(
id SERIAL,
value VARCHAR(255) NULL,
timestamp TIMESTAMP(6) NOT NULL,
machine_id INT NOT NULL,
measurement_type_id INT NOT NULL,
point_of_measurement_id INT NOT NULL,
FOREIGN KEY (machine_id) REFERENCES machine (id),
FOREIGN KEY (measurement_type_id) REFERENCES measurement_type (id),
FOREIGN KEY (point_of_measurement_id) REFERENCES point_of_measurement (id),
PRIMARY KEY (id, timestamp)
);
CREATE INDEX ON measurement_ms (machine_id, timestamp ASC);
CREATE INDEX ON measurement_ms (measurement_type_id, timestamp ASC);
CREATE INDEX ON measurement_ms (point_of_measurement_id, timestamp ASC);
-- --------------------------------------------------------------------------
-- Create timescale hypertable
-- --------------------------------------------------------------------------
SELECT create_hypertable('measurement_ms', 'timestamp', chunk_time_interval => interval '1 day');
DROP TABLE IF EXISTS recipe;
CREATE TABLE IF NOT EXISTS recipe
(
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
type VARCHAR(255) NOT NULL,
code INT NOT NULL
);
DROP TABLE IF EXISTS measurement_recipe;
CREATE TABLE IF NOT EXISTS measurement_recipe
(
id SERIAL PRIMARY KEY,
measurement_id INT NOT NULL,
recipe_id INT NOT NULL
FOREIGN KEY (recipe_id) REFERENCES recipe(id),
FOREIGN KEY (measurement_id) REFERENCES measurement_ms(id)
);
CREATE INDEX fk_measurement_recipe_measurement ON measurement_recipe (measurement_id ASC);
CREATE INDEX fk_measurement_recipe_recipe ON measurement_recipe (recipe_id ASC);
如上所示的SQL脚本就是我要连接的table。由于时间尺度的限制,上述解决方案不起作用。
Timescale 具有不能使用 hypertable 值作为外键的约束。 是否有替代解决方案可以在 table 之间创建多对多关系而不实际使用多对多关系。
TimescaleDB 专为时间序列数据而设计,其中每个点通常附加到某个时刻并包含所有相关数据。 link 每个指向已经存在的元数据是很常见的,但是,相反的做法并不常见。 TimescaleDB 通过分块数据针对时间序列数据进行了优化,因此 DML 和许多 select 查询不需要触及所有块。但是,将外键约束维护到 hypertable 中可能需要在每次插入引用时触及所有块 table measurement_recipe
.
问题的用例是具有复杂测量值的时间序列。提议的模式似乎是原始模式的规范化。我想它简化了测量数据的查询。我看到两种处理复杂测量的方法:
- 在JSONB 或数组等复杂结构的帮助下,保持数据非规范化并将配方和测量值存储在
measurement
table 中的单行或几行中。缺点是有些查询将很难编写,并且可能无法定义一些连续聚合。 - 按照问题中的建议进行规范化,但不要强制外键约束。它将允许存储引用值,可用于连接 tables。由于规范化是作为转换输入的复杂数据的一个步骤自动完成的,如果转换代码中没有错误,约束将被保留。可以通过回归测试来防止错误。仍然使用规范化模式,将不可能使用连续聚合,因为不允许连接(维护具有连接的连续聚合可能需要接触所有块)。
我的建议是选择选项 1 并尝试在其中变得聪明。我没有好的建议,因为不清楚 JSON 中的原始数据结构是什么,以及查询是什么。