Перейти к основному содержанию
Этот тип позволяет хранить значения любых типов, не зная заранее полный их набор. Чтобы объявить столбец типа Dynamic, используйте следующий синтаксис:
Где N — необязательный параметр в диапазоне от 0 до 254, который указывает, сколько различных типов данных может храниться в виде отдельных подстолбцов внутри столбца типа Dynamic в рамках одного отдельно хранимого блока данных (например, в пределах одной части данных для таблицы семейства MergeTree). Если этот предел превышен, все значения новых типов будут храниться вместе в специальной общей структуре данных в бинарной форме. Значение max_types по умолчанию — 32.

Создание типа Dynamic

Использование типа Dynamic в определении столбца таблицы:
Использование CAST с обычным столбцом:
Использование CAST со столбцом Variant:

Чтение вложенных типов Dynamic как подстолбцов

Тип Dynamic поддерживает чтение отдельного вложенного типа из столбца Dynamic, используя имя типа в качестве подстолбца. Так, если у вас есть столбец d Dynamic, вы можете прочитать подстолбец любого допустимого типа T, используя синтаксис d.T. Этот подстолбец будет иметь тип Nullable(T), если T может находиться внутри Nullable, и T в противном случае. Размер этого подстолбца будет таким же, как у исходного столбца Dynamic, и он будет содержать значения NULL (или пустые значения, если T не может находиться внутри Nullable) во всех строках, где исходный столбец Dynamic не имеет типа T. Подстолбцы Dynamic также можно читать с помощью функции dynamicElement(dynamic_column, type_name). Примеры:
Чтобы узнать, какой вариант хранится в каждой строке, можно использовать функцию dynamicType(dynamic_column). Она возвращает значение типа String с именем типа значения для каждой строки (или 'None', если строка — NULL). Пример:

Преобразования между столбцом типа Dynamic и другими столбцами

Для столбца Dynamic возможны 4 преобразования.

Преобразование обычного столбца в столбец типа Dynamic

Преобразование столбца String в столбец типа Dynamic с помощью разбора

Чтобы разобрать значения типа Dynamic из столбца String, можно включить настройку cast_string_to_dynamic_use_inference:

Преобразование столбца типа Dynamic в обычный столбец

Столбец Dynamic можно преобразовать в обычный столбец. В этом случае все вложенные типы будут преобразованы в целевой тип:

Преобразование столбца типа Variant в столбец типа Dynamic

Преобразование столбца Dynamic(max_types=N) в столбец Dynamic(max_types=K)

Если K >= N, то при преобразовании данные не меняются:
Если K < N, то значения с самыми редкими типами будут вставлены в один специальный подстолбец, но по-прежнему останутся доступными:
Функция isDynamicElementInSharedData возвращает true для строк, которые хранятся в специальной общей структуре данных внутри Dynamic, и, как видно, результирующий столбец содержит только 2 типа, которые не хранятся в общей структуре данных. Если K=0, все типы будут вставляться в один специальный подстолбец:

Чтение типа Dynamic из данных

Все текстовые форматы (TSV, CSV, CustomSeparated, Values, JSONEachRow и т. д.) поддерживают чтение типа Dynamic. При разборе данных ClickHouse пытается определить тип каждого значения и использовать его при вставке в столбец Dynamic. Пример:

Использование типа Dynamic в функциях

Большинство функций поддерживают аргументы типа Dynamic. В этом случае функция выполняется отдельно для каждого внутреннего типа данных, хранящегося в столбце Dynamic. Если тип результата функции зависит от типов аргументов, то результат такой функции, вызванной с аргументами типа Dynamic, будет иметь тип Dynamic. Если тип результата функции не зависит от типов аргументов — результат будет иметь тип Nullable(T), где T — обычный тип результата этой функции. Примеры:
Если функцию нельзя выполнить для какого-либо типа в столбце Dynamic, будет сгенерировано исключение:
Можно отфильтровать ненужные типы:
Или извлеките нужный тип в виде подстолбца:

Поведение при несовпадении типов

Параметр dynamic_throw_on_type_mismatch определяет, что происходит, когда функция применяется к столбцу Dynamic, а фактический тип данных в строке несовместим с этой функцией:
  • true (по умолчанию) — сгенерировать исключение (ILLEGAL_TYPE_OF_ARGUMENT) при первой несовместимой строке.
  • false — возвращать NULL для несовместимых строк, сохраняя результат для совместимых.
Пример:

Использование типа Dynamic в ORDER BY и GROUP BY

При ORDER BY и GROUP BY значения типа Dynamic сравниваются аналогично значениям типа Variant: Результат оператора < для значений d1 с внутренним типом T1 и d2 с внутренним типом T2 типа Dynamic определяется следующим образом:
  • Если T1 = T2 = T, результатом будет d1.T < d2.T (будут сравниваться внутренние значения).
  • Если T1 != T2, результатом будет T1 < T2 (будут сравниваться имена типов).
По умолчанию тип Dynamic нельзя использовать в ключах GROUP BY/ORDER BY; если вы хотите его использовать, учитывайте его особое правило сравнения и включите настройки allow_suspicious_types_in_group_by/allow_suspicious_types_in_order_by. Примеры:
Примечание: значения типа Dynamic с разными числовыми типами считаются разными и не сравниваются между собой; вместо этого сравниваются имена их типов. Пример:
Примечание: описанное правило сравнения не применяется при выполнении функций сравнения, таких как </>/= и других, из-за особенностей работы функций с типом Dynamic

Достижение предела количества различных типов данных, хранимых в Dynamic

Тип данных Dynamic может хранить лишь ограниченное число различных типов данных в виде отдельных подстолбцов. По умолчанию этот предел равен 32, но его можно изменить в объявлении типа, используя синтаксис Dynamic(max_types=N), где N — число от 0 до 254 (из-за подробностей реализации невозможно иметь более 254 различных типов данных, которые могут храниться в Dynamic как отдельные подстолбцы). Когда этот предел достигнут, все новые типы данных, вставляемые в столбец Dynamic, будут помещаться в единую общую структуру данных, которая хранит значения разных типов данных в двоичной форме. Посмотрим, что происходит при достижении этого предела в разных сценариях.

Достижение лимита при разборе данных

При разборе значений Dynamic из данных, когда для текущего блока данных достигается лимит, все новые значения будут помещаться в общую структуру данных:
Как мы видим, после вставки 3 различных типов данных — Int64, Array(Int64) и String — все новые типы были помещены в специальную общую структуру данных.

Во время слияния частей данных в движках таблиц MergeTree

При слиянии нескольких частей данных в таблице семейства MergeTree столбец Dynamic в результирующей части данных может достичь ограничения на число различных типов данных, которые могут храниться в отдельных подстолбцах, и тогда не сможет хранить все типы из исходных частей в виде подстолбцов. В этом случае ClickHouse выбирает, какие типы останутся в виде отдельных подстолбцов после слияния, а какие будут помещены в общую структуру данных. В большинстве случаев ClickHouse старается сохранить наиболее часто встречающиеся типы, а самые редкие хранить в общей структуре данных, но это зависит от реализации. Рассмотрим пример такого слияния. Сначала создадим таблицу со столбцом Dynamic, зададим ограничение на число различных типов данных равным 3 и вставим значения 5 разных типов:
Каждая вставка создаст отдельную часть данных со столбцом Dynamic, содержащим значения только одного типа:
Теперь давайте объединим все части в одну часть и посмотрим, что произойдёт:
Как мы видим, ClickHouse сохранил наиболее часто встречающиеся типы UInt64 и Array(UInt64) в виде подстолбцов, а все остальные типы поместил в общие данные.

Функции JSONExtract с типом Dynamic

Все функции JSONExtract* поддерживают тип Dynamic:

Бинарный формат вывода

В формате RowBinary значения типа Dynamic сериализуются следующим образом:
Последнее изменение 19 июня 2026 г.