Skip to content

Выбор одного значения #122

@hugarin

Description

@hugarin

Здравствуйте. Разрабатываем новое хранилище данных для нашего завода. Хотим использовать ваше секционирование.

Приведу кусочек структуры нашей БД.

Таблица oss.object_properties хранит идентификаторы свойств, вторичные ключи указывают на объекты, которым принадлежат эти свойства.

CREATE TABLE oss.object_properties
(
  object_property integer NOT NULL DEFAULT oss.next_id('object_property'),
  facet integer NOT NULL,
  property integer NOT NULL,
  CONSTRAINT pk_oss_object_properties PRIMARY KEY (object_property),
  CONSTRAINT fk_oss_object_properties_facet FOREIGN KEY (facet)
      REFERENCES oss.facets(facet) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE NO ACTION,
  CONSTRAINT fk_oss_object_properties_property FOREIGN KEY (property)
      REFERENCES oss.properties(property) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE NO ACTION
);

Таблица oss.partitioned_storage - главная архивная таблица (далее - архив) с секционированием по диапазонам поля mark, которая хранит значения всех свойств растянутых по времени.

CREATE TABLE oss.partitioned_storage
(
  object_property integer NOT NULL,
  mark timestamptz NOT NULL,
  value text,
  CONSTRAINT pk_oss_partitioned_storage PRIMARY KEY (object_property, mark),
  CONSTRAINT fk_oss_partitioned_storage_object_property FOREIGN KEY (object_property)
      REFERENCES oss.object_properties(object_property) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE NO ACTION
);

Проблемы

  1. Как определить содержит ли архив хотя бы одно значение для конкретного свойства object_property?

Подобные выборки приводят к тому, что в память будут загружены индексы всех секций. Как вариант решения проблемы можно добавить в таблицу oss.object_properties дополнительный столбец-флаг, который будет нам говорить о том, есть данные по этому свойству или нет. Издержки здесь в том, что придется постоянно при вставке и удалении свойств проверять этот флаг. Но при удалении одного значения напрашивается вопрос: а вдруг это последнее и флаг нужно сбросить и мы снова попадаем в похожую ситуацию. Рассуждаем дальше. Тогда вместо флага мы добавим два столбца с временными границами всех значений по свойству left и right. Издержки - границы постоянно нужно будет держать актуальными при вставке, обновлении, удалении. Это повлечет за собой регулярное обслуживание таблицы oss.object_properties с полным перестроением. Хотя, возможно это будет приемлемым вариантом.

  1. Как выбрать значение конкретного свойства object_property левее(по полю mark) известной отметки времени?
  2. Как выбрать последнее значение конкретного свойства object_property? Это может быть частным случаем проблемы 2, если известной отметкой времени считать infinity.

Выборки данных для ответов на вопросы 2 и 3 затрагивают все секции архива, а хотелось бы чтобы этого не происходило.

select *
from oss.partitioned_storage
where object_property = 1
and mark < '2017-01-01 10:22'
order by mark desc
limit 1

План к этому запросу затрагивает все секции. Возможно ли сделать так, чтобы executor пошел по секциям в нужном нам порядке и при нахождении первого значения в ближайшей к нужной нам отметке времени секции завершил запрос и вернул эту строку? Возможно, можно построить запрос по другому.

Частично эту проблему решает дополнительный столбец в таблице oss.partitioned_storage, который будет указывать на предыдущее значение конкретного свойства.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions