Перейти к основному содержимому
Версия: 2.0.x

dict_mapping

Возвращает значение, сопоставленное с указанным ключом в таблице словаря.

Эта функция в основном используется для упрощения применения глобальной таблицы словаря. При загрузке данных в целевую таблицу Selena автоматически получает значение, сопоставленное с указанным ключом из таблицы словаря, используя входные параметры этой функции, а затем загружает значение в целевую таблицу.

Начиная с версии 3.2.5, Selena поддерживает эту функцию. Также обратите внимание, что в настоящее время режим shared-data в Selena не поддерживает эту функцию.

Синтаксис

dict_mapping("[<db_name>.]<dict_table>", key_column_expr_list [, <value_column> ] [, <null_if_not_exist>] )

key_column_expr_list ::= key_column_expr [, key_column_expr ... ]

key_column_expr ::= <column_name> | <expr>

Параметры

  • Обязательные параметры:

    • [<db_name>.]<dict_table>: имя таблицы словаря, которая должна быть таблицей с первичным ключом. Поддерживаемый тип данных - VARCHAR.

    • key_column_expr_list: список выражений для ключевых столбцов в таблице словаря, включающий одно или несколько key_column_expr. key_column_expr может быть именем ключевого столбца в таблице словаря или конкретным ключом или выражением ключа.

      Этот список выражений должен включать все столбцы первичного ключа таблицы словаря, то есть общее количество выражений должно соответствовать общему количеству столбцов первичного ключа в таблице словаря. Поэтому когда таблица словаря использует составной первичный ключ, выражения в этом списке должны соответствовать столбцам первичного ключа, определённым в схеме таблицы, по порядку. Несколько выражений в этом списке разделяются запятыми (,). Если key_column_expr является конкретным ключом или выражением ключа, его тип должен соответствовать типу соответствующего столбца первичного ключа в таблице словаря.

  • Необязательные параметры:

    • <value_column>: имя столбца значения, который также является столбцом сопоставления. Если столбец значения не указан, столбцом значения по умолчанию является столбец AUTO_INCREMENT таблицы словаря. Столбец значения также может быть определён как любой столбец в таблице словаря, исключая автоинкрементные столбцы и первичные ключи. Тип данных столбца не имеет ограничений.
    • <null_if_not_exist> (необязательный): возвращать ли NULL, если ключ не существует в таблице словаря. Допустимые значения:
      • true: возвращает NULL, если ключ не существует.
      • false (по умолчанию): генерирует исключение, если ключ не существует.

Возвращаемое значение

Тип данных возвращаемых значений соответствует типу данных столбца значения. Если столбец значения является автоинкрементным столбцом таблицы словаря, тип данных возвращаемых значений - BIGINT.

Однако когда значение, сопоставленное с указанным ключом, не найдено, если параметр <null_if_not_exist> установлен в true, возвращается NULL. Если параметр установлен в false (по умолчанию), возвращается ошибка query failed if record not exist in dict table.

Примеры

Пример 1: Прямой запрос значения, сопоставленного с ключом, из таблицы словаря.

  1. Создайте таблицу словаря и загрузите тестовые данные.

    MySQL [test]> CREATE TABLE dict (
    order_uuid STRING,
    order_id_int BIGINT AUTO_INCREMENT
    )
    PRIMARY KEY (order_uuid)
    DISTRIBUTED BY HASH (order_uuid);
    Query OK, 0 rows affected (0.02 sec)

    MySQL [test]> INSERT INTO dict (order_uuid) VALUES ('a1'), ('a2'), ('a3');
    Query OK, 3 rows affected (0.12 sec)
    {'label':'insert_9e60b0e4-89fa-11ee-a41f-b22a2c00f66b', 'status':'VISIBLE', 'txnId':'15029'}

    MySQL [test]> SELECT * FROM dict;
    +------------+--------------+
    | order_uuid | order_id_int |
    +------------+--------------+
    | a1 | 1 |
    | a3 | 3 |
    | a2 | 2 |
    +------------+--------------+
    3 rows in set (0.01 sec)

    ПРИМЕЧАНИЕ

    В настоящее время оператор INSERT INTO не поддерживает частичные обновления. Поэтому убедитесь, что значения, вставляемые в ключевой столбец dict, не дублируются. В противном случае вставка одного и того же значения ключевого столбца в таблицу словаря несколько раз приведёт к изменению сопоставленного значения в столбце значений.

  2. Запросите значение, сопоставленное с ключом a1, в таблице словаря.

    MySQL [test]> SELECT dict_mapping('dict', 'a1');
    +----------------------------+
    | dict_mapping('dict', 'a1') |
    +----------------------------+
    | 1 |
    +----------------------------+
    1 row in set (0.01 sec)

Пример 2: Столбец сопоставления в таблице настроен как генерируемый столбец с использованием функции dict_mapping. Таким образом, Selena может автоматически получать значения, сопоставленные с ключами, при загрузке данных в эту таблицу.

  1. Создайте таблицу данных и настройте столбец сопоставления как генерируемый столбец с использованием dict_mapping('dict', order_uuid).

    CREATE TABLE dest_table1 (
    id BIGINT,
    -- Этот столбец записывает номер заказа типа STRING, соответствующий столбцу order_uuid в таблице dict из Примера 1.
    order_uuid STRING,
    batch int comment 'используется для различения разных пакетных загрузок',
    -- Этот столбец записывает номер заказа типа BIGINT, сопоставленный со столбцом order_uuid.
    -- Поскольку этот столбец является генерируемым столбцом, настроенным с dict_mapping, значения в этом столбце автоматически получаются из таблицы dict из Примера 1 во время загрузки данных.
    -- Впоследствии этот столбец можно напрямую использовать для дедупликации и JOIN-запросов.
    order_id_int BIGINT AS dict_mapping('dict', order_uuid)
    )
    DUPLICATE KEY (id, order_uuid)
    DISTRIBUTED BY HASH(id);
  2. При загрузке тестовых данных в эту таблицу, где столбец order_id_int настроен как dict_mapping('dict', 'order_uuid'), Selena автоматически загружает значения в столбец order_id_int на основе сопоставления между ключами и значениями в таблице dict.

    MySQL [test]> INSERT INTO dest_table1(id, order_uuid, batch) VALUES (1, 'a1', 1), (2, 'a1', 1), (3, 'a3', 1), (4, 'a3', 1);
    Query OK, 4 rows affected (0.05 sec)
    {'label':'insert_e191b9e4-8a98-11ee-b29c-00163e03897d', 'status':'VISIBLE', 'txnId':'72'}

    MySQL [test]> SELECT * FROM dest_table1;
    +------+------------+-------+--------------+
    | id | order_uuid | batch | order_id_int |
    +------+------------+-------+--------------+
    | 1 | a1 | 1 | 1 |
    | 4 | a3 | 1 | 3 |
    | 2 | a1 | 1 | 1 |
    | 3 | a3 | 1 | 3 |
    +------+------------+-------+--------------+
    4 rows in set (0.02 sec)

    Использование dict_mapping в этом примере может ускорить вычисления дедупликации и JOIN-запросы. По сравнению с предыдущими решениями для построения глобального словаря для ускорения точной дедупликации, решение с использованием dict_mapping более гибкое и удобное для пользователя. Поскольку сопоставленные значения напрямую получаются из таблицы словаря на этапе "загрузки сопоставлений между ключами и значениями в таблицу". Вам не нужно писать операторы для соединения с таблицей словаря для получения сопоставленных значений. Кроме того, это решение поддерживает различные методы загрузки данных.

Пример 3: Если столбец сопоставления в таблице не настроен как генерируемый столбец, необходимо явно настроить функцию dict_mapping для столбца сопоставления при загрузке данных в таблицу, чтобы получить значения, сопоставленные с ключами.

ПРИМЕЧАНИЕ

Разница между Примером 3 и Примером 2 заключается в том, что при импорте в таблицу данных необходимо изменить команду импорта, чтобы явно настроить выражение dict_mapping для столбца сопоставления.

  1. Создайте таблицу.

    CREATE TABLE dest_table2 (
    id BIGINT,
    order_uuid STRING,
    order_id_int BIGINT NULL,
    batch int comment 'используется для различения разных пакетных загрузок'
    )
    DUPLICATE KEY (id, order_uuid, order_id_int)
    DISTRIBUTED BY HASH(id);
  2. При загрузке тестовых данных в эту таблицу вы получаете сопоставленные значения из таблицы словаря, настроив dict_mapping.

    MySQL [test]> INSERT INTO dest_table2 VALUES (1, 'a1', dict_mapping('dict', 'a1'), 1);
    Query OK, 1 row affected (0.35 sec)
    {'label':'insert_19872ab6-8a96-11ee-b29c-00163e03897d', 'status':'VISIBLE', 'txnId':'42'}

    MySQL [test]> SELECT * FROM dest_table2;
    +------+------------+--------------+-------+
    | id | order_uuid | order_id_int | batch |
    +------+------------+--------------+-------+
    | 1 | a1 | 1 | 1 |
    +------+------------+--------------+-------+
    1 row in set (0.02 sec)

Пример 4: Включение режима null_if_not_exist

Когда режим <null_if_not_exist> отключён и запрашивается значение, сопоставленное с ключом, который не существует в таблице словаря, возвращается ошибка вместо NULL. Это гарантирует, что ключ строки данных сначала загружается в таблицу словаря и генерируется его сопоставленное значение (ID словаря) перед загрузкой этой строки данных в целевую таблицу.

MySQL [test]>  SELECT dict_mapping('dict', 'b1', true);
ERROR 1064 (HY000): Query failed if record not exist in dict table.

Пример 5: Если таблица словаря использует составные первичные ключи, при запросе должны быть указаны все первичные ключи.

  1. Создайте таблицу словаря с составными первичными ключами и загрузите в неё тестовые данные.

    MySQL [test]> CREATE TABLE dict2 (
    order_uuid STRING,
    order_date DATE,
    order_id_int BIGINT AUTO_INCREMENT
    )
    PRIMARY KEY (order_uuid,order_date) -- Составной первичный ключ
    DISTRIBUTED BY HASH (order_uuid,order_date)
    ;
    Query OK, 0 rows affected (0.02 sec)

    MySQL [test]> INSERT INTO dict2 VALUES ('a1','2023-11-22',default), ('a2','2023-11-22',default), ('a3','2023-11-22',default);
    Query OK, 3 rows affected (0.12 sec)
    {'label':'insert_9e60b0e4-89fa-11ee-a41f-b22a2c00f66b', 'status':'VISIBLE', 'txnId':'15029'}


    MySQL [test]> select * from dict2;
    +------------+------------+--------------+
    | order_uuid | order_date | order_id_int |
    +------------+------------+--------------+
    | a1 | 2023-11-22 | 1 |
    | a3 | 2023-11-22 | 3 |
    | a2 | 2023-11-22 | 2 |
    +------------+------------+--------------+
    3 rows in set (0.01 sec)
  2. Запросите значение, сопоставленное с ключом, в таблице словаря. Поскольку таблица словаря имеет составные первичные ключи, в dict_mapping должны быть указаны все первичные ключи.

    SELECT dict_mapping('dict2', 'a1', cast('2023-11-22' as DATE));

    Обратите внимание, что ошибка возникает, если указан только один первичный ключ.

    MySQL [test]> SELECT dict_mapping('dict2', 'a1');
    ERROR 1064 (HY000): Getting analyzing error. Detail message: dict_mapping function param size should be 3 - 5.