-
Notifications
You must be signed in to change notification settings - Fork 69
Description
Здравствуйте. Разрабатываем новое хранилище данных для нашего завода. Хотим использовать ваше секционирование.
Приведу кусочек структуры нашей БД.
Таблица 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
);
Проблемы
- Как определить содержит ли архив хотя бы одно значение для конкретного свойства object_property?
Подобные выборки приводят к тому, что в память будут загружены индексы всех секций. Как вариант решения проблемы можно добавить в таблицу oss.object_properties дополнительный столбец-флаг, который будет нам говорить о том, есть данные по этому свойству или нет. Издержки здесь в том, что придется постоянно при вставке и удалении свойств проверять этот флаг. Но при удалении одного значения напрашивается вопрос: а вдруг это последнее и флаг нужно сбросить и мы снова попадаем в похожую ситуацию. Рассуждаем дальше. Тогда вместо флага мы добавим два столбца с временными границами всех значений по свойству left и right. Издержки - границы постоянно нужно будет держать актуальными при вставке, обновлении, удалении. Это повлечет за собой регулярное обслуживание таблицы oss.object_properties с полным перестроением. Хотя, возможно это будет приемлемым вариантом.
- Как выбрать значение конкретного свойства object_property левее(по полю mark) известной отметки времени?
- Как выбрать последнее значение конкретного свойства 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, который будет указывать на предыдущее значение конкретного свойства.