替代 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.

问题的用例是具有复杂测量值的时间序列。提议的模式似乎是原始模式的规范化。我想它简化了测量数据的查询。我看到两种处理复杂测量的方法:

  1. 在JSONB 或数组等复杂结构的帮助下,保持数据非规范化并将配方和测量值存储在measurement table 中的单行或几行中。缺点是有些查询将很难编写,并且可能无法定义一些连续聚合。
  2. 按照问题中的建议进行规范化,但不要强制外键约束。它将允许存储引用值,可用于连接 tables。由于规范化是作为转换输入的复杂数据的一个步骤自动完成的,如果转换代码中没有错误,约束将被保留。可以通过回归测试来防止错误。仍然使用规范化模式,将不可能使用连续聚合,因为不允许连接(维护具有连接的连续聚合可能需要接触所有块)。

我的建议是选择选项 1 并尝试在其中变得聪明。我没有好的建议,因为不清楚 JSON 中的原始数据结构是什么,以及查询是什么。