Dynamic, используйте следующий синтаксис:
N — необязательный параметр в диапазоне от 0 до 254, который указывает, сколько различных типов данных может храниться в виде отдельных подстолбцов внутри столбца типа Dynamic в рамках одного отдельно хранимого блока данных (например, в пределах одной части данных для таблицы семейства MergeTree). Если этот предел превышен, все значения новых типов будут храниться вместе в специальной общей структуре данных в бинарной форме. Значение max_types по умолчанию — 32.
Создание типа Dynamic
Dynamic в определении столбца таблицы:
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 из данных
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 может хранить лишь ограниченное число различных типов данных в виде отдельных подстолбцов. По умолчанию этот предел равен 32, но его можно изменить в объявлении типа, используя синтаксис Dynamic(max_types=N), где N — число от 0 до 254 (из-за подробностей реализации невозможно иметь более 254 различных типов данных, которые могут храниться в Dynamic как отдельные подстолбцы).
Когда этот предел достигнут, все новые типы данных, вставляемые в столбец Dynamic, будут помещаться в единую общую структуру данных, которая хранит значения разных типов данных в двоичной форме.
Посмотрим, что происходит при достижении этого предела в разных сценариях.
Достижение лимита при разборе данных
Dynamic из данных, когда для текущего блока данных достигается лимит, все новые значения будут помещаться в общую структуру данных:
Int64, Array(Int64) и String — все новые типы были помещены в специальную общую структуру данных.
Во время слияния частей данных в движках таблиц MergeTree
Dynamic в результирующей части данных может достичь ограничения на число различных типов данных, которые могут храниться в отдельных подстолбцах, и тогда не сможет хранить все типы из исходных частей в виде подстолбцов.
В этом случае ClickHouse выбирает, какие типы останутся в виде отдельных подстолбцов после слияния, а какие будут помещены в общую структуру данных. В большинстве случаев ClickHouse старается сохранить наиболее часто встречающиеся типы, а самые редкие хранить в общей структуре данных, но это зависит от реализации.
Рассмотрим пример такого слияния. Сначала создадим таблицу со столбцом Dynamic, зададим ограничение на число различных типов данных равным 3 и вставим значения 5 разных типов:
Dynamic, содержащим значения только одного типа:
UInt64 и Array(UInt64) в виде подстолбцов, а все остальные типы поместил в общие данные.
Функции JSONExtract с типом Dynamic
JSONExtract* поддерживают тип Dynamic:
Бинарный формат вывода
Dynamic сериализуются следующим образом: