В сценарии работы с временными данными 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 выполняет преобразование партиций горячих и холодных данных, однако очистка исходной подтаблицы Heap должна выполняться вручную:
DROP TABLE heap_disk_20210401000000000_20210402000000000;
Движок 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;