sql—超级表和“普通”表之间的多对多关系的替代方法

yfwxisqw  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(311)

我试图在名为“measurements”的超表和名为“recipe”的表之间创建一个多对多关系。
一个测量可以有多个配方,并且一个配方可以连接到多个测量。

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脚本是我要连接的表。由于时间尺度的限制,上述解决方案不起作用。
时间刻度有一个限制,即不能将超表值用作外键。有没有其他解决方案可以在表之间创建多对多关系而不实际使用多对多关系。

cnwbcb6i

cnwbcb6i1#

timescaledb是为时间序列数据而设计的,其中每个点通常与某个时间点相连,并包含所有相关数据。将每个点链接到已经存在的元数据是很常见的,但是相反的做法并不常见。timescaledb通过分块数据对时间序列数据进行了优化,因此dmls和许多select查询不需要接触所有的分块。然而,在hypertable中维护外键约束可能需要接触引用表中每个插入的所有块 measurement_recipe .
这个问题的用例是具有复杂度量的时间序列。提出的模式似乎是原始模式的规范化。我想它简化了测量数据的查询。我看到了两种处理复杂测量的方法:
保持数据非规范化,并将配方和测量值存储在 measurement 借助复杂结构(如jsonb或array)将表放在一行或几行中。缺点是有些查询将很难编写,并且可能无法定义某些连续聚合。
按照问题中的建议进行规范化,但不要强制使用外键约束。它将允许存储可用于连接表的引用值。由于标准化是作为转换传入的复杂数据的一个步骤自动完成的,因此如果转换代码中没有bug,则约束将被保留。这些缺陷可以通过回归测试来预防。尽管使用规范化模式,但仍然不可能使用连续聚合,因为不允许连接(使用连接维护连续聚合可能需要接触所有块)。
我的建议是选择方案1,在那里尽量聪明。我没有好的建议,因为不清楚json中的原始数据结构是什么,以及查询是什么。

相关问题