Этот документ описывает расширенные типы данных, поддерживаемые YMatrix.
В реляционной модели обычные типы данных представляют отдельные атрибуты в столбцах, такие как имя, рост и вес. Однако в сценариях временных рядов часто возникают следующие проблемы:
В таких случаях требуются расширенные типы данных, позволяющие хранить несколько атрибутов в одном столбце.
Существует множество способов реализации расширенных типов данных, например, использование пользовательских форматов сериализации, закодированных в столбцы типа строка. YMatrix предоставляет два расширенных типа данных:
Типы данных JSON и jsonb унаследованы от PostgreSQL. В отличие от хранения сырых JSON-строк в текстовых столбцах, JSON и jsonb предоставляют встроенные функции для распространённых операций, таких как извлечение пар ключ-значение, объединение и удаление элементов.
JSON и jsonb функционально схожи и могут быть взаимно преобразованы. Их различия заключаются в следующем:
Ниже приведены распространённые операции с JSON / jsonb:
Используйте оператор -> для извлечения значений по ключу:
SELECT '{"a":1, "b":2, "c":3}'::json->'a';
?column?
----------
1
(1 row)
Для вложенных JSON-структур объединяйте несколько операторов ->:
SELECT '{"a":1, "b":2, "c":{"d":2}}'::json->'c'->'d';
?column?
----------
2
(1 row)
Используйте оператор - для удаления ключа. Обратите внимание: операции записи требуют, чтобы значение имело тип jsonb:
SELECT '{"a":1, "b":2, "c":3}'::jsonb - 'a';
?column?
------------------
{"b": 2, "c": 3}
(1 row)
Используйте оператор || для объединения двух объектов jsonb:
SELECT '{"a":1, "b":2}'::jsonb || '{"c":3}'::jsonb;
?column?
--------------------------
{"a": 1, "b": 2, "c": 3}
(1 row)
При перекрытии ключей используйте || для обновления значений:
SELECT '{"a":1, "b":2}'::jsonb || '{"b":3}'::jsonb;
?column?
------------------
{"a": 1, "b": 3}
(1 row)
Для дополнительных операций с JSON обратитесь к документации PostgreSQL: документация.
Видеоурок по этой теме доступен по ссылке: YMatrix Data Modeling and Spatiotemporal Distribution Model
При использовании YMatrix для сбора данных временных рядов могут возникнуть следующие ситуации:
Традиционные решения включают:
Хотя эти подходы обеспечивают гибкость, они страдают от низкой производительности.
MXKV был разработан для решения этих проблем. MXKV — это высокопроизводительный и масштабируемый тип хранения, разработанный YMatrix. Он используется аналогично JSON, но обладает преимуществами: MXKV использует двоичное хранение и интегрирован с алгоритмами сжатия YMatrix, что приводит к уменьшению объёма хранения и повышению эффективности запросов.
Примечание!
Эта функция доступна только в корпоративной версии.
Тип данных MXKV входит в расширение MatrixTS. Сначала создайте расширение:
CREATE EXTENSION matrixts;
Проверьте, что MXKV включён:
mxadmin=# SELECT '{}'::mxkv_text;
mxkv_text
-----------
{}
(1 row)
Как показано выше, MXKV теперь активен.
Создайте новую таблицу и определите столбец MXKV с использованием целочисленного типа mxkv_int4 для хранения целочисленных пар ключ-значение:
CREATE TABLE data(
time timestamp with time zone,
tag_id int,
kv mxkv_int4
)
DISTRIBUTED BY (tag_id);
Перед использованием MXKV необходимо определить ключи для оптимизации сжатия и производительности запросов. Этот шаг заранее задаёт ожидаемый набор ключей в данных.
MXKV предоставляет UDF mxkv_import_keys для определения ключей.
Доступны два метода:
Укажите пример JSON-объекта вручную. MXKV автоматически извлечёт и зарегистрирует ключи.
Следующий SQL-запрос извлекает и определяет ключи 'a' и 'b':
mxadmin=# SELECT mxkv_import_keys('{"a": 1, "b": 2}');
mxkv_import_keys
------------------
a
b
(2 rows)
Предположим, существует таблица t_json с JSON-столбцом c2:
mxadmin=# SELECT c2 FROM t_json ;
c2
----------
{"k1":1}
{"k2":2}
(2 rows)
Из вывода видно, что c2 содержит ключи k1 и k2.
Используйте mxkv_import_keys для определения ключей из данных таблицы:
mxadmin=# SELECT mxkv_import_keys('t_json'::regclass, 'c2');
mxkv_import_keys
------------------
k1
k2
(2 rows)
Как показано выше, передайте имя таблицы и имя столбца в качестве параметров.
Этот метод удобнее и эффективнее, если в другой таблице уже имеются репрезентативные выборочные данные.
После определения ключей вставьте данные KV:
mxadmin=# INSERT INTO data VALUES(now(), 1, '{"a":1, "b":2}');
INSERT 0 1
Вставленные данные KV содержат ранее определённые ключи 'a' и 'b'.
Примечание!
Ключи должны быть определены до вставки. В противном случае возникнет ошибка:
Key not found in MXKV key registry
Чтение значений ключей из MXKV аналогично JSON и выполняется с помощью оператора ->:
mxadmin=# SELECT time, tag_id, kv->'a' as a, kv->'b' as b FROM data;
time | tag_id | a | b
-------------------------------+--------+---+---
2021-07-02 13:23:30.405473+00 | 1 | 1 | 2
(1 row)
Извлечённые значения ключей ведут себя как обычные столбцы и поддерживают сравнения и соединения. Например, создайте вторую таблицу data1 с такой же структурой и вставьте идентичные данные, затем выполните соединение:
mxadmin=# SELECT * FROM data, data1 WHERE data.kv->'a' = data1.kv->'a';
time | tag_id | kv | time | tag_id | kv
-------------------------------+--------+------------------+-------------------------------+--------+------------------
2021-07-02 13:23:30.405473+00 | 1 | {"a": 1, "b": 2} | 2021-07-02 13:26:31.828685+00 | 1 | {"a": 1, "b": 2}
(1 row)
Примечание!
В MXKV->и->>имеют одинаковый эффект.
В предыдущем примере использовался mxkv_int4. Ниже приведено подробное описание поддерживаемых типов данных MXKV:
mxkv_int4: Хранит 32-битные целые числа (int4 / int).mxkv_float4: Хранит 32-битные числа с плавающей точкой (float4 / real).mxkv_float8: Хранит 64-битные числа с плавающей точкой (float8 / float / double precision).mxkv_text: Хранит текстовые строки.Для mxkv_float4 и mxkv_float8 можно указать количество десятичных знаков. Например:
CREATE TABLE data(
time timestamp with time zone,
tag_id int,
kv mxkv_float4(2)
)
DISTRIBUTED BY (tag_id);
При таком определении цифры за пределами двух десятичных знаков округляются. Указание масштаба преобразует внутреннее хранение в целочисленный формат, улучшая сжатие и эффективность — но уменьшая общий диапазон значений.
mxkv_float4(scale), scale >= 0mxkv_float4(0): [-2147483500, 2147483500]mxkv_float4(2): [-21474835.00, 21474835.00]mxkv_float4(4): [-214748.3500, 214748.3500]mxkv_float8(scale), scale >= 0mxkv_float8(0): [-9223372036854775000, 9223372036854775000]mxkv_float8(2): [-92233720368547750.00, 92233720368547750.00]mxkv_float8(4): [-922337203685477.5000, 922337203685477.5000]Примечание!
MXKV поддерживает только плоские структуры ключ-значение. Вложенные объекты и массивы не допускаются.
Для более глубоких технических деталей см. блог-пост MXKV.