Этот документ описывает расширенные типы данных, поддерживаемые YMatrix.
В реляционной модели обычные типы данных представляют один атрибут на столбец, например имя, рост или вес. Однако в сценариях временных рядов часто возникают следующие проблемы:
В таких случаях требуются расширенные типы данных — они позволяют хранить несколько атрибутов в одном столбце.
Существует множество способов реализации расширенных типов данных, например, использование пользовательских форматов сериализации, закодированных в столбцы типа text. 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)
Используйте оператор - для удаления ключа. При выполнении операций записи над объектами JSON сначала преобразуйте их в 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 и спatio-temporal модель распределения
При использовании YMatrix для сбора данных временных рядов могут возникнуть следующие сценарии:
Традиционные решения включают:
Хотя эти подходы упрощают операционную сложность, они страдают от низкой производительности.
MXKV был разработан для устранения этих ограничений. MXKV — это высокопроизводительный и масштабируемый тип хранения, разработанный YMatrix. Он используется аналогично JSON, но обладает преимуществами в эффективности: MXKV использует двоичное хранение и интегрируется с алгоритмами сжатия YMatrix для достижения компактного хранения и высокой производительности запросов.
Примечание!
Эта функция доступна только в корпоративной версии.
Тип данных MXKV входит в расширение MatrixTS. Сначала создайте расширение:
=# CREATE EXTENSION matrixts;
Убедитесь, что MXKV включён:
=# 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
)
USING MARS3
DISTRIBUTED BY (tag_id)
ORDER BY (time,tag_id);
Перед использованием MXKV определите набор ключей для оптимизации сжатия и производительности запросов. Этот шаг заранее задаёт ожидаемый набор ключей в данных.
MXKV предоставляет UDF mxkv_import_keys для определения ключей.
Доступны два метода:
Предоставьте пример объекта JSON. MXKV автоматически извлечёт и зарегистрирует ключи.
Следующий SQL извлекает и определяет ключи 'a' и 'b':
=# SELECT mxkv_import_keys('{"a": 1, "b": 2}');
mxkv_import_keys
------------------
a
b
(2 rows)
Предположим, существует таблица t_json с JSON-столбцом c2:
=# SELECT c2 FROM t_json ;
c2
----------
{"k1":1}
{"k2":2}
(2 rows)
Из результата видно, что c2 содержит ключи k1 и k2.
Используйте mxkv_import_keys для определения ключей из этой таблицы:
=# SELECT mxkv_import_keys('t_json'::regclass, 'c2');
mxkv_import_keys
------------------
k1
k2
(2 rows)
Как показано, передайте имя таблицы и имя столбца в качестве параметров.
Этот метод более удобен и эффективен, если образцы данных уже существуют в другой таблице.
После определения ключей вставьте KV-данные:
=# INSERT INTO data VALUES(now(), 1, '{"a":1, "b":2}');
INSERT 0 1
Вставленные KV-данные содержат ранее определённые ключи 'a' и 'b'.
Примечание!
Ключи должны быть определены до вставки. В противном случае возникнет ошибка:
DETAIL: The key is not imported yet HINT: Import the keys with the mxkv_import_keys() function
Чтение значений ключей из MXKV аналогично JSON и использует оператор ->:
=# 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)
Извлечённые значения ключей можно использовать как обычные столбцы — для сравнений или соединений с другими таблицами. Например, создайте таблицу data с такой же структурой, как data, вставьте идентичные данные и выполните соединение:
=# 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)
)
USING MARS3
DISTRIBUTED BY (tag_id)
ORDER BY (time,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_float4(2): [-92233720368547750.00, 92233720368547750.00]mxkv_float8(4): [-922337203685477.5000, 922337203685477.5000]Примечание!
MXKV поддерживает только плоские структуры ключ-значение. Вложенность и массивы не допускаются.
Для получения дополнительных технических деталей см. блог-пост MXKV.