Этот документ описывает расширенные типы данных, поддерживаемые YMatrix, которые можно использовать для построения моделей широких/узких таблиц.
YMatrix — это реляционная база данных со схемой. Все таблицы должны иметь предварительно определённую схему, заданную с помощью DDL-заявлений. Каждый столбец в схеме представляет атрибутное значение, например, имя, рост или вес. Однако в некоторых бизнес-сценариях часто возникают следующие проблемы:
Для решения этих проблем несколько атрибутов могут быть сериализованы и сохранены в полях переменной длины.
В таких случаях требуются расширенные типы данных — они позволяют хранить несколько атрибутов в одном столбце.
Существует множество способов реализации расширенных типов данных. Например, можно определить пользовательские форматы сериализации и методы кодирования и хранить их в столбцах типа строка. YMatrix предоставляет следующие расширенные типы данных:
Сравнение:
| Тип данных | Формат хранения | Поддерживаемые форматы хранения | Поддерживаемые форматы данных |
|---|---|---|---|
| JSON | Текст | Все форматы | INT/NUMERIC/BOOLEAN/NULL и др. Поддерживает хранение различных типов данных в массивах внутри одного столбца JSON |
| JSONB | Бинарный | Все форматы | INT/NUMERIC/BOOLEAN/NULL и др. Поддерживает хранение различных типов данных в массивах внутри одного столбца JSON |
| MXKV | Бинарный | Все форматы | MXKV_INT4/MXKV_FLOAT4/MXKV_FLOAT8/MXKV_TEXT Поддерживает только плоскую структуру ключ-значение; вложенность и массивы не допускаются. Для хранения метрик разных типов требуются несколько столбцов |
| MXKV2 | Бинарный | MARS2/3 | MXKV_INT8/MXKV_FLOAT8/MXKV_TEXT/MXKV_BOOL Поддерживает только плоскую структуру ключ-значение; вложенность и массивы не допускаются. Для хранения метрик разных типов требуются несколько столбцов |
Типы данных JSON и JSONB унаследованы от PostgreSQL. В отличие от прямого хранения строк JSON в текстовых столбцах, типы JSON/JSONB предоставляют встроенные функции для распространённых операций с JSON, таких как извлечение ключей и значений, объединение и удаление.
JSON и JSONB используются аналогично и могут взаимно преобразовываться. Их различия:
Ниже приведены распространённые операции с типами JSON/JSONB:
=# SELECT '{"a":1, "b":2, "c":3}'::json->'a';
?column?
----------
1
(1 row)
Для вложенных структур JSON/JSONB используйте -> несколько раз:
=# 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 здесь.
MXKV и MXKV2 — это разработанные YMatrix высокопроизводительные и масштабируемые типы хранения, используемые аналогично JSON/JSONB. Их преимущество заключается в бинарном хранении в сочетании с алгоритмами сжатия цепочки кодирования YMatrix, что обеспечивает меньший объём хранения и более высокую эффективность запросов.
Помимо различий, указанных в таблице сравнения, MXKV и MXKV2 отличаются следующим:
Обучающие видео по этому разделу доступны в Моделировании данных YMatrix и спatio-temporal моделях
Примечание!
Эта функция доступна только в корпоративной версии.
Пользовательские типы данных MXKV и MXKV2 включены в расширение MatrixTS. Сначала создайте расширение:
=# CREATE EXTENSION matrixts;
Проверьте, что MXKV/MXKV2 включены:
// MXKV
=# SELECT '{}'::mxkv_text;
mxkv_text
-----------
{}
(1 row)
// MXKV2
=# SELECT '{}'::mxkv2_text;
mxkv2_text
-----------
{}
(1 row)
Как показано, MXKV включён.
Создайте новую таблицу и определите столбец целочисленного типа для хранения KV-данных с целочисленными значениями:
// MXKV
=# CREATE TABLE data_1(
time timestamp with time zone,
tag_id int,
kv mxkv_int4
)
USING MARS3
DISTRIBUTED BY (tag_id)
ORDER BY (time,tag_id);
// MXKV2
=# CREATE TABLE data_2(
time timestamp with time zone,
tag_id int,
kv mxkv2_int8 encoding(compresstype=mxcustom,encodechain='auto')
)
USING MARS3
DISTRIBUTED BY (tag_id)
ORDER BY (time,tag_id);
Перед использованием MXKV необходимо определить ключи для оптимизации сжатия и производительности запросов. Этот шаг предварительно задаёт набор ожидаемых ключей в данных.
MXKV предоставляет UDF mxkv_import_keys для определения ключей.
Доступны два метода:
Предоставьте пример KV в формате JSON. MXKV автоматически извлечёт и определит ключи.
Следующий SQL-запрос извлекает и определяет ключи 'a' и 'b' из JSON:
=# 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)
Результат показывает два ключа: k1 и k2.
Используйте mxkv_import_keys для определения ключей из данных таблицы:
=# SELECT mxkv_import_keys('t_json'::regclass, 'c2');
mxkv_import_keys
------------------
k1
k2
(2 rows)
Как показано, передайте имя таблицы и имя столбца в качестве параметров.
Этот метод удобнее и быстрее, но требует, чтобы выборочные данные уже существовали в другой таблице.
Примечание!
Ключи в MXKV должны быть определены до вставки данных. В противном случае возникнет следующая ошибка:
DETAIL: The key is not imported yet HINT: Import the keys with the mxkv_import_keys() function
После определения ключей вставьте KV-данные:
// MXKV
=# INSERT INTO data_1 VALUES(now(), 1, '{"a":1, "b":2}');
INSERT 0 1
// MXKV2
=# INSERT INTO data_2 VALUES(now(), 1, '{"a":1, "b":2}');
INSERT 0 1
Как показано, вставленные KV-данные содержат ранее определённые ключи 'a' и 'b'.
Чтение ключей и значений в MXKV использует тот же оператор ->, что и в JSON:
// MXKV
=# SELECT time, tag_id, kv->'a' as a, kv->'b' as b FROM data_1;
time | tag_id | a | b
-------------------------------+--------+---+---
2023-10-19 10:20:05.334169+00 | 1 | 1 | 2
(1 row)
// MXKV2
=# SELECT time, tag_id, kv->'a' as a, kv->'b' as b FROM data_2;
time | tag_id | a | b
-------------------------------+--------+---+---
2023-10-19 10:20:05.334169+00 | 1 | 1 | 2
(1 row)
Извлечённые ключи и значения можно использовать как обычные столбцы — для сравнений или соединений с другими таблицами. Например, создайте таблицу data_1/data_2 с такой же структурой, как data_1, и вставьте идентичные данные. Следующий SQL-запрос выполняет соединение:
// MXKV
=# SELECT * FROM data_1, data_3 WHERE data_1.kv->'a' = data_3.kv->'a';
time | tag_id | kv | time | tag_id | kv
-------------------------------+--------+------------------+-------------------------------+--------+------------------
2023-10-19 10:20:05.334169+00 | 1 | {"a": 1, "b": 2} | 2023-10-19 10:20:05.334169+00 | 1 | {"a": 1, "b": 2}
(1 row)
// MXKV2
=# SELECT * FROM data_2, data_3 WHERE data_2.kv->'a' = data_3.kv->'a';
time | tag_id | kv | time | tag_id | kv
-------------------------------+--------+------------------+-------------------------------+--------+------------------
2023-10-19 10:20:05.334169+00 | 1 | {"a": 1, "b": 2} | 2023-10-19 10:20:05.334169+00 | 1 | {"a": 1, "b": 2}
(1 row)
Примечание!
В MXKV/MXKV2->и->>эквивалентны.
| Тип данных | Поддерживаемые форматы данных |
|---|---|
| MXKV | MXKV_INT4: хранит 32-битные целые числа (INT4/INT) MXKV_FLOAT4: хранит 32-битные числа с плавающей точкой (FLOAT4/REAL) MXKV_FLOAT8: хранит 64-битные числа с плавающей точкой (FLOAT8/FLOAT/DOUBLE PRECISION) MXKV_TEXT: хранит строки TEXT |
| MXKV2 | MXKV2_INT8: хранит 64-битные целые числа (INT8/INT) MXKV2_FLOAT8: хранит 64-битные числа с плавающей точкой (FLOAT8/FLOAT/DOUBLE PRECISION) MXKV2_TEXT: хранит строки TEXT MXKV2_BOOL: хранит логические значения BOOLEAN |
MXKV_FLOAT4 и MXKV_FLOAT8 поддерживают указание масштаба десятичных знаков. Например:
=# CREATE TABLE data_4(
time timestamp with time zone,
tag_id int,
kv mxkv_float4(2)
)
USING MARS3
DISTRIBUTED BY (tag_id)
ORDER BY (time,tag_id);
При таком определении цифры после двух десятичных знаков округляются.
Указание масштаба преобразует внутреннее хранение в целочисленный формат, улучшая сжатие и эффективность. Однако диапазон значений соответственно уменьшается.
Примечание!
MXKV и MXKV2 поддерживают только плоские структуры ключ-значение. Вложенность и массивы не допускаются.
Для получения дополнительных технических деталей см. блог MXKV.