Альтернатива отношения многих ко многим между гипертаблицей и `` нормальной '' таблицей - PullRequest
0 голосов
/ 18 июня 2020

Я пытаюсь создать отношение «многие ко многим» между гипертаблицей с именем «измерения» и таблицей с именем «рецепт».

Измерение может иметь несколько рецептов, и рецепт может быть связан с несколько измерений.

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, показанный выше, - это таблицы, которые я хочу подключить. Приведенное выше решение не работает из-за ограничения по шкале времени.

Шкала времени имеет ограничение, заключающееся в том, что вы не можете использовать значения гипертаблиц в качестве внешнего ключа. Есть ли альтернативное решение для создания отношений «многие ко многим» между таблицами без фактического использования отношения «многие ко многим».

1 Ответ

1 голос
/ 19 июня 2020

TimescaleDB предназначен для данных временных рядов, где каждая точка обычно привязана к некоторому моменту времени и содержит все соответствующие данные. Обычно каждую точку связывают с метаданными, которые уже есть, однако обратное - редкость. TimescaleDB оптимизирован для данных временных рядов путем разделения данных на части, поэтому DML и многие запросы на выборку не требуют касаться всех фрагментов. Однако поддержание ограничений внешнего ключа в гипертаблице может потребовать касания всех фрагментов при каждой вставке в ссылочную таблицу measurement_recipe.

Пример использования вопроса - временной ряд со сложными измерениями. Предлагаемая схема кажется нормализацией исходной схемы. Я думаю, это упрощает запрос данных измерений. Я вижу два подхода к работе со сложными измерениями:

  1. Сохраняйте денормализованные данные и сохраняйте рецепты и измерения в таблице measurement в одной строке или нескольких строках с помощью сложных структур, таких как JSONB или массив . Недостатком является то, что некоторые запросы будет сложно написать, а определение некоторых непрерывных агрегатов может оказаться невозможным.
  2. Выполните нормализацию, как предлагается в вопросе, но не форсируйте ограничения внешнего ключа. Это позволит хранить ссылочные значения, которые можно использовать для объединения таблиц. Поскольку нормализация выполняется автоматически на этапе преобразования входящих сложных данных, ограничения будут сохранены, если в коде преобразования нет ошибок. Ошибки можно предотвратить с помощью регрессионного тестирования. По-прежнему с нормализованной схемой будет невозможно использовать непрерывные агрегаты, поскольку соединения не разрешены (для поддержания непрерывных агрегатов с соединениями может потребоваться коснуться всех фрагментов).

Я предлагаю go для вариант 1 и постарайтесь там поумниться. У меня нет хорошего предложения, так как неясно, какова исходная структура данных в JSON и каковы запросы.

...