В сценарии работы с временными данными MatrixDB поддерживает два распространённых типа таблиц:
| Тип | Описание |
|---|---|
| Heap | Таблица Heap — это тип хранения, предоставляемый традиционными базами данных PostgreSQL, также известный как кучные таблицы. Этот тип таблиц поддерживает большое количество одновременных операций чтения и записи, транзакции, индексы и другие функции. |
| Mars | Mars-таблица — это собственный тип хранения, разработанный MatrixDB. Поддерживает сжатие, колоночное хранение и предварительную агрегацию, обеспечивая чрезвычайно высокую производительность в аналитических сценариях. Однако данные должны вставляться по порядку, а операции обновления и удаления пока не поддерживаются. |
Следовательно, для максимальной эффективности при записи временных рядов и анализе запросов в рабочей среде необходимо использовать оба типа таблиц. При записи данных сначала используется таблица Heap, потому что:
В MatrixDB технология партиционирования используется для объединения двух типов таблиц и разделения данных по временным меткам. Горячие данные сначала записываются в «горячую» партицию типа Heap. После подтверждения того, что доступ к данным больше не будет изменяться, и более ранние данные больше не будут поступать, «горячая» партиция Heap преобразуется в «холодную» партицию Mars.
Продолжительность партиции зависит от объема данных. Например: если объем данных большой, размер партиции должен быть небольшим — можно разделять по дням или часам; если объем данных мал, размер партиции можно увеличить — разделять по неделям или месяцам.
MatrixDB предоставляет пользовательские функции (UDF) для управления партициями. Перед использованием необходимо установить соответствующие расширения:
CREATE EXTENSION matrixts;
CREATE EXTENSION mars;
Рассмотрим на примере записи объёма операций чтения и записи на диске использование горячего и холодного хранилища:
CREATE TABLE disk(
time timestamp with time zone,
tag_id int,
read float,
write float
)
Distributed by (tag_id)
Partition by range(time);
С помощью приведённого выше SQL-запроса создаётся таблица временных данных с партиционированием по временным меткам, ключ распределения — tag_id.
После создания таблицы временных данных шаблон партиции создаётся вызовом функции build_timeseries_table, предоставляемой расширением mars:
SELECT mars.build_timeseries_table('disk','tagkey="tag_id", timekey="time", timebucket="1 day"');
При создании шаблона партиции необходимо указать имена столбцов ключей тегов и временных меток, а также единицы времени.
Таблица шаблона партиции не удаляется автоматически при обычной команде DROP TABLE и требует ручной очистки. Если требуется удалить исходную таблицу, правильная последовательность действий следующая:
SELECT mars.destroy_timeseries_table('disk'); DROP TABLE disk;
После создания шаблона партиции вызывается функция add_partition, предоставляемая расширением mars, чтобы создать партицию:
SELECT mars.add_partition('disk', '2021-04-01', '2021-05-01','1 day');
Как указано выше, SQL-запрос создаёт партицию с 1 апреля 2021 года по 1 мая 2021 года с временной единицей в один день.
После создания партиции вызовите функцию list_partition для просмотра информации о партициях:
ymatrix=# SELECT * from mars.list_partition('disk');
relname | storage
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
heap_disk_20210401000000000_20210402000000000 | heap
heap_disk_20210402000000000_20210403000000000 | heap
heap_disk_20210403000000000_20210404000000000 | heap
heap_disk_20210404000000000_20210405000000000 | heap
heap_disk_20210405000000000_20210406000000000 | heap
heap_disk_20210406000000000_20210407000000000 | heap
heap_disk_20210407000000000_20210408000000000 | heap
heap_disk_20210408000000000_20210409000000000 | heap
heap_disk_20210409000000000_20210410000000000 | heap
heap_disk_20210410000000000_20210411000000000 | heap
heap_disk_20210411000000000_20210412000000000 | heap
heap_disk_20210412000000000_20210413000000000 | heap
heap_disk_20210413000000000_20210414000000000 | heap
heap_disk_20210414000000000_20210415000000000 | heap
heap_disk_20210415000000000_20210416000000000 | heap
heap_disk_20210416000000000_20210417000000000 | heap
heap_disk_20210417000000000_20210418000000000 | heap
heap_disk_20210418000000000_20210419000000000 | heap
heap_disk_20210419000000000_20210420000000000 | heap
heap_disk_20210420000000000_20210421000000000 | heap
heap_disk_20210421000000000_20210422000000000 | heap
heap_disk_20210422000000000_20210423000000000 | heap
heap_disk_20210423000000000_20210424000000000 | heap
heap_disk_20210424000000000_20210425000000000 | heap
heap_disk_20210425000000000_20210426000000000 | heap
heap_disk_20210426000000000_20210427000000000 | heap
heap_disk_20210427000000000_20210428000000000 | heap
heap_disk_20210428000000000_20210429000000000 | heap
heap_disk_20210429000000000_20210430000000000 | heap
heap_disk_20210430000000000_20210501000000000 | heap
(30 rows)
Как показано в SQL-запросе выше, отображаются все подтаблицы партиций, входящие в таблицу disk, включая имена подтаблиц и типы хранения.
insert into disk values(now(), ...., ..., ...);
Так как таблица партиционирована по времени, достаточно просто вставлять данные в основную таблицу — они автоматически попадут в соответствующую партицию.
После завершения сбора данных временных рядов за 1 апреля становится ясно, что новые данные за этот день больше поступать не будут. Данные за 1 апреля необходимо преобразовать из горячей партиции в холодную.
Расширение Mars предоставляет функцию compress_partition, которая используется для преобразования партиций:
ymatrix=# select mars.compress_partition('heap_disk_20210401000000000_20210402000000000');
compress_partition
----------------------------------------------------------------------------------------------------------------------------------
mars_disk_20210401000000000_20210402000000000
(1 row)
Как указано выше, SQL-запрос преобразует соответствующую партицию за 1 апреля. После преобразования вызовите функцию list_partition, чтобы просмотреть имя и тип хранения преобразованной партиции:
ymatrix=# SELECT * from mars.list_partition('disk');
relname | storage
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
heap_disk_20210402000000000_20210403000000000 | heap
heap_disk_20210403000000000_20210404000000000 | heap
heap_disk_20210404000000000_20210405000000000 | heap
heap_disk_20210405000000000_20210406000000000 | heap
heap_disk_20210406000000000_20210407000000000 | heap
heap_disk_20210407000000000_20210408000000000 | heap
heap_disk_20210408000000000_20210409000000000 | heap
heap_disk_20210409000000000_20210410000000000 | heap
heap_disk_20210410000000000_20210411000000000 | heap
heap_disk_20210411000000000_20210412000000000 | heap
heap_disk_20210412000000000_20210413000000000 | heap
heap_disk_20210413000000000_20210414000000000 | heap
heap_disk_20210414000000000_20210415000000000 | heap
heap_disk_20210415000000000_20210416000000000 | heap
heap_disk_20210416000000000_20210417000000000 | heap
heap_disk_20210417000000000_20210418000000000 | heap
heap_disk_20210418000000000_20210419000000000 | heap
heap_disk_20210419000000000_20210420000000000 | heap
heap_disk_20210420000000000_20210421000000000 | heap
heap_disk_20210421000000000_20210422000000000 | heap
heap_disk_20210422000000000_20210423000000000 | heap
heap_disk_20210423000000000_20210424000000000 | heap
heap_disk_20210424000000000_20210425000000000 | heap
heap_disk_20210425000000000_20210426000000000 | heap
heap_disk_20210426000000000_20210427000000000 | heap
heap_disk_20210427000000000_20210428000000000 | heap
heap_disk_20210428000000000_20210429000000000 | heap
heap_disk_20210429000000000_20210430000000000 | heap
heap_disk_20210430000000000_20210501000000000 | heap
mars_disk_20210401000000000_20210402000000000 | mars
(30 rows)
Как видно, префикс имени преобразованной партиции изменился с heap на mars, и тип хранения также изменился соответственно. Старые партиции удаляются автоматически.
Функция compress_partition также имеет необязательный параметр временного диапазона, позволяющий объединить партицию с предыдущей партицией Mars. Как показано ниже, система автоматически рассчитывает на основе временного диапазона и даты текущей партиции — преобразует партицию и объединяет её с предыдущей, либо создаёт новую партицию.
SELECT mars.compress_partition('heap_disk_20210401000000000_20210402000000000', '10 days');
Движок Mars можно использовать не только в партиционированных таблицах, но и отдельно — создавать и использовать его автономно.
Когда у пользователя есть набор статических данных, которым необходимо воспользоваться преимуществами высокого сжатия и высокой производительности движка Mars для оптимизации запросов, он может вручную создать таблицу Mars, отсортировать данные и выполнить их импорт.
Сначала создайте расширение:
CREATE EXTENSION matrixts;
CREATE EXTENSION mars;
Затем создайте таблицу Mars. При создании таблицы используйте USING Mars, чтобы указать движок хранения:
CREATE TABLE disk_mars(
time timestamp with time zone,
tag_id int,
read float,
write float
)
USING Mars
WITH (tagkey="tag_id", timekey="time", timebucket="8 hours")
Distributed by (tag_id);
Метаданные таблицы Mars указываются в ключевом слове WITH, включая:
Таблица Mars поддерживает колоночное сжатие. Сжатие позволяет не только уменьшить занимаемое пространство, но и снизить затраты на выполнение запросов.
Таблица Mars поддерживает 4 типа сжатия:
При создании таблицы Mars тип сжатия столбца указывается через compressiontype. Одновременно необходимо указать уровень сжатия (от 0 до 9) через compresslevel. Чем выше уровень, тем выше степень сжатия, меньше занимаемое место, но выше нагрузка на вычислительные ресурсы.
SQL-запрос ниже создаёт таблицу Mars, указывая различные типы сжатия для разных столбцов:
CREATE TABLE disk_mars (
time timestamp with time zone ENCODING (compresstype=rle_type, compresslevel=1),
tag_id int ENCODING (compresstype=zstd, compresslevel=1),
read float ENCODING (compresstype=zlib, compresslevel=1),
write float ENCODING (compresstype=lz4, compresslevel=1)
)
USING Mars
WITH (tagkey="tag_id", timekey="time", timebucket="8 hours")
Distributed by (tag_id);
Таблица Mars требует, чтобы данные были отсортированы по tag_id и временной метке перед загрузкой, иначе возможны ошибки в результатах запросов.
Импортируйте данные из таблицы Heap в таблицу Mars:
INSERT INTO disk_mars SELECT * FROM disk_heap ORDER BY tag_id, time;
Вы также можете импортировать данные из внешней таблицы в таблицу Mars:
INSERT INTO disk_mars SELECT * FROM ext ORDER BY tag_id, time;