Этот тип позволяет хранить значения любых типов, не зная заранее полный их набор.
Чтобы объявить столбец типа Dynamic, используйте следующий синтаксис:
Где N — необязательный параметр в диапазоне от 0 до 254, который указывает, сколько различных типов данных может храниться в виде отдельных подстолбцов внутри столбца типа Dynamic в рамках одного отдельно хранимого блока данных (например, в пределах одной части данных для таблицы семейства MergeTree). Если этот предел превышен, все значения новых типов будут храниться вместе в специальной общей структуре данных в бинарной форме. Значение max_types по умолчанию — 32.
Использование типа 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:
В формате RowBinary значения типа Dynamic сериализуются следующим образом:
Последнее изменение 19 июня 2026 г.