Перейти к основному содержимому

MAP

MAP — это сложный тип данных, который хранит набор пар ключ-значение, например, {a:1, b:2, c:3}. Ключи в карте должны быть уникальными. Вложенная карта может содержать до 14 уровней вложенности.

Тип данных MAP поддерживается начиная с версии 1.5.0. В v3.1 вы можете определять столбцы MAP при создании таблицы Selena, загружать данные MAP в эту таблицу и запрашивать данные MAP.

Начиная с версии 1.5.0, Selena поддерживает запросы сложных типов данных MAP и STRUCT из озер данных. Вы можете использовать external catalog, предоставляемые Selena, для запроса данных MAP и STRUCT из Apache Hive™, Apache Hudi и Apache Iceberg. Вы можете запрашивать данные только из файлов ORC и Parquet. Для получения дополнительной информации о том, как использовать external catalog для запроса внешних источников данных, см. Обзор каталогов и темы, связанные с требуемым типом catalog.

Синтаксис

MAP<key_type,value_type>
  • key_type: тип данных ключа. Ключ должен быть примитивного типа, поддерживаемого Selena, такого как числовой, строковый или тип даты. Он не может быть типом HLL, JSON, ARRAY, MAP, BITMAP или STRUCT.
  • value_type: тип данных значения. Значение может быть любого поддерживаемого типа.

Ключи и значения изначально допускают NULL.

Определение столбца MAP в Selena

Вы можете определить столбец MAP при создании таблицы и загрузить данные MAP в этот столбец.

-- Определение одномерной карты.
CREATE TABLE t0(
c0 INT,
c1 MAP<INT,INT>
)
DUPLICATE KEY(c0);

-- Определение вложенной карты.
CREATE TABLE t1(
c0 INT,
c1 MAP<DATE, MAP<VARCHAR(10), INT>>
)
DUPLICATE KEY(c0);

-- Определение карты NOT NULL.
CREATE TABLE t2(
c0 INT,
c1 MAP<INT,DATETIME> NOT NULL
)
DUPLICATE KEY(c0);

Столбцы с типом MAP имеют следующие ограничения:

  • Не могут использоваться как ключевые столбцы в таблице. Они могут использоваться только как столбцы значений.
  • Не могут использоваться как столбцы ключа разделения (столбцы после PARTITION BY) в таблице.
  • Не могут использоваться как столбцы группировки (столбцы после DISTRIBUTED BY) в таблице.

Создание карт в SQL

Карты можно создавать в SQL, используя следующие два синтаксиса:

  • map{key_expr:value_expr, ...}: Элементы карты разделяются запятой (,), а ключи и значения разделяются двоеточием (:), например, map{a:1, b:2, c:3}.

  • map(key_expr, value_expr ...): Выражения ключей и значений должны быть в парах, например, map(a,1,b,2,c,3).

Selena может выводить типы данных ключей и значений из всех входных ключей и значений.

select map{1:1, 2:2, 3:3} as numbers;
select map(1,1,2,2,3,3) as numbers; -- Возвращает {1:1,2:2,3:3}.
select map{1:"apple", 2:"orange", 3:"pear"} as fruit;
select map(1, "apple", 2, "orange", 3, "pear") as fruit; -- Возвращает {1:"apple",2:"orange",3:"pear"}.
select map{true:map{3.13:"abc"}, false:map{}} as nest;
select map(true, map(3.13, "abc"), false, map{}) as nest; -- Возвращает {1:{3.13:"abc"},0:{}}.

Если ключи или значения имеют разные типы, Selena автоматически выводит подходящий тип (супертип).

select map{1:2.2, 1.2:21} as floats_floats; -- Возвращает {1.0:2.2,1.2:21.0}.
select map{12:"a", "100":1, NULL:NULL} as string_string; -- Возвращает {"12":"a","100":"1",null:null}.

Вы также можете определить тип данных, используя <> при создании карты. Входные ключи или значения должны быть приводимы к указанным типам.

select map<FLOAT,INT>{1:2}; -- Возвращает {1:2}.
select map<INT,INT>{"12": "100"}; -- Возвращает {12:100}.

Ключи и значения могут быть NULL.

select map{1:NULL};

Создание пустых карт.

select map{} as empty_map;
select map() as empty_map; -- Возвращает {}.

Загрузка данных MAP в Selena

Вы можете загружать данные карт в Selena двумя способами: INSERT INTO и загрузка ORC/Parquet.

Обратите внимание, что Selena удалит дублирующиеся ключи каждой карты при загрузке данных MAP.

INSERT INTO

  CREATE TABLE t0(
c0 INT,
c1 MAP<INT,INT>
)
DUPLICATE KEY(c0);

INSERT INTO t0 VALUES(1, map{1:2,3:NULL});

Загрузка данных MAP из файлов ORC и Parquet

Тип данных MAP в Selena соответствует структуре карты в формате ORC или Parquet. Дополнительных спецификаций не требуется. Вы можете загружать данные MAP из файлов ORC или Parquet, следуя инструкциям в загрузке ORC/Parquet.

Доступ к данным MAP

Пример 1: Запрос столбца MAP c1 из таблицы t0.

mysql> select c1 from t0;
+--------------+
| c1 |
+--------------+
| {1:2,3:null} |
+--------------+

Пример 2: Используйте оператор [ ] для получения значений из карты по ключу или используйте функцию element_at(any_map, any_key).

Следующий пример запрашивает значение, соответствующее ключу 1.

mysql> select map{1:2,3:NULL}[1];
+-----------------------+
| map(1, 2, 3, NULL)[1] |
+-----------------------+
| 2 |
+-----------------------+

mysql> select element_at(map{1:2,3:NULL},1);
+--------------------+
| map{1:2,3:NULL}[1] |
+--------------------+
| 2 |
+--------------------+

Если ключ не существует в карте, возвращается NULL.

Следующий пример запрашивает значение, соответствующее ключу 2, который не существует.

mysql> select map{1:2,3:NULL}[2];
+-----------------------+
| map(1, 2, 3, NULL)[2] |
+-----------------------+
| NULL |
+-----------------------+

Пример 3: Запрос многомерных карт рекурсивно.

Следующий пример сначала запрашивает значение, соответствующее ключу 1, которое является map{2:1}, а затем рекурсивно запрашивает значение, соответствующее ключу 2 в map{2:1}.

mysql> select map{1:map{2:1},3:NULL}[1][2];

+----------------------------------+
| map(1, map(2, 1), 3, NULL)[1][2] |
+----------------------------------+
| 1 |
+----------------------------------+

Ссылки