Pular para o conteúdo principal
Esse tipo permite armazenar valores de qualquer tipo sem precisar conhecer todos eles antecipadamente. Para declarar uma coluna do tipo Dynamic, use a seguinte sintaxe:
Onde N é um parâmetro opcional entre 0 e 254 que indica quantos tipos de dados diferentes podem ser armazenados como subcolunas separadas dentro de uma coluna do tipo Dynamic em um único bloco de dados armazenado separadamente (por exemplo, em uma única parte de dados de uma tabela MergeTree). Se esse limite for excedido, todos os valores com novos tipos serão armazenados juntos em uma estrutura de dados compartilhada especial em formato binário. O valor padrão de max_types é 32.

Criando Dynamic

Usando o tipo Dynamic na definição de uma coluna da tabela:
Usando CAST em uma coluna comum:
Usando CAST na coluna Variant:

Lendo tipos aninhados de Dynamic como subcolunas

O tipo Dynamic oferece suporte à leitura de um único tipo aninhado de uma coluna Dynamic usando o nome do tipo como subcoluna. Assim, se você tiver a coluna d Dynamic, poderá ler uma subcoluna de qualquer tipo válido T usando a sintaxe d.T. Essa subcoluna terá o tipo Nullable(T) se T puder estar dentro de Nullable; caso contrário, terá o tipo T. Essa subcoluna terá o mesmo tamanho da coluna Dynamic original e conterá valores NULL (ou valores vazios, se T não puder estar dentro de Nullable) em todas as linhas em que a coluna Dynamic original não tiver o tipo T. As subcolunas de Dynamic também podem ser lidas usando a função dynamicElement(dynamic_column, type_name). Exemplos:
Para saber qual variante está armazenada em cada linha, pode-se usar a função dynamicType(dynamic_column). Ela retorna String contendo o nome do tipo do valor para cada linha (ou 'None' se a linha for NULL). Exemplo:

Conversão entre a coluna Dynamic e outras colunas

Há 4 conversões possíveis que podem ser feitas com a coluna Dynamic.

Convertendo uma coluna comum em uma coluna Dynamic

Convertendo uma coluna String em uma coluna Dynamic por meio de parsing

Para fazer o parsing de valores do tipo Dynamic a partir de uma coluna String, você pode habilitar a configuração cast_string_to_dynamic_use_inference:

Convertendo uma coluna Dynamic em uma coluna comum

É possível converter uma coluna Dynamic em uma coluna comum. Nesse caso, todos os tipos aninhados serão convertidos para um tipo de destino:

Convertendo uma coluna Variant para uma coluna Dynamic

Convertendo uma coluna Dynamic(max_types=N) em outra Dynamic(max_types=K)

Se K >= N, os dados não mudam durante a conversão:
Se K < N, então os valores com os tipos mais raros serão inseridos em uma única subcoluna especial, mas ainda continuarão acessíveis:
A função isDynamicElementInSharedData retorna true para as linhas armazenadas em uma estrutura de dados compartilhada especial dentro de Dynamic e, como podemos ver, a coluna resultante contém apenas 2 tipos que não são armazenados nessa estrutura de dados compartilhada. Se K=0, todos os tipos serão inseridos em uma única subcoluna especial:

Lendo o tipo Dynamic a partir dos dados

Todos os formatos de texto (TSV, CSV, CustomSeparated, Values, JSONEachRow etc.) permitem ler o tipo Dynamic. Durante o parsing dos dados, o ClickHouse tenta inferir o tipo de cada valor e usá-lo durante a inserção em uma coluna Dynamic. Exemplo:

Usando o tipo Dynamic em funções

A maioria das funções aceita argumentos do tipo Dynamic. Nesse caso, a função é executada separadamente para cada tipo de dado interno armazenado na coluna Dynamic. Quando o tipo de resultado da função depende dos tipos dos argumentos, o resultado de tal função executada com argumentos Dynamic será Dynamic. Quando o tipo de resultado da função não depende dos tipos dos argumentos, o resultado será Nullable(T), onde T é o tipo de resultado usual dessa função. Exemplos:
Se a função não puder ser executada em algum tipo na coluna Dynamic, uma exceção será lançada:
Podemos filtrar os tipos desnecessários:
Ou extraia o tipo necessário como subcoluna:

Comportamento em caso de incompatibilidade de tipo

A configuração dynamic_throw_on_type_mismatch controla o que acontece quando uma função é aplicada a uma coluna Dynamic e o tipo realmente armazenado em uma linha é incompatível com a função:
  • true (padrão) — lança uma exceção (ILLEGAL_TYPE_OF_ARGUMENT) na primeira linha incompatível.
  • false — retorna NULL para as linhas incompatíveis e mantém o resultado para as linhas compatíveis.
Exemplo:

Usando o tipo Dynamic em ORDER BY e GROUP BY

Em ORDER BY e GROUP BY, os valores do tipo Dynamic são comparados de forma semelhante aos valores do tipo Variant: O resultado do operador < para os valores d1, com tipo subjacente T1, e d2, com tipo subjacente T2, de um tipo Dynamic é definido da seguinte forma:
  • Se T1 = T2 = T, o resultado será d1.T < d2.T (os valores subjacentes serão comparados).
  • Se T1 != T2, o resultado será T1 < T2 (os nomes dos tipos serão comparados).
Por padrão, o tipo Dynamic não é permitido em chaves de GROUP BY/ORDER BY. Se quiser usá-lo, leve em consideração sua regra especial de comparação e habilite as configurações allow_suspicious_types_in_group_by/allow_suspicious_types_in_order_by. Exemplos:
Observação: valores de tipos Dynamic com tipos numéricos diferentes são considerados distintos e não são comparados entre si; em vez disso, seus nomes de tipo são comparados. Exemplo:
Observação: a regra de comparação descrita não é aplicada durante a execução de funções de comparação como </>/= e outras, devido ao comportamento especial das funções com o tipo Dynamic

Atingindo o limite do número de diferentes tipos de dados armazenados em Dynamic

O tipo de dado Dynamic pode armazenar apenas um número limitado de diferentes tipos de dados como subcolunas separadas. Por padrão, esse limite é 32, mas você pode alterá-lo na declaração do tipo usando a sintaxe Dynamic(max_types=N), em que N fica entre 0 e 254 (devido a detalhes de implementação, é impossível ter mais de 254 tipos de dados diferentes que possam ser armazenados como subcolunas separadas em Dynamic). Quando esse limite é atingido, todos os novos tipos de dados inseridos na coluna Dynamic passam a ser inseridos em uma única estrutura de dados compartilhada, que armazena valores com diferentes tipos de dados em formato binário. Vamos ver o que acontece quando esse limite é atingido em diferentes cenários.

Atingindo o limite durante o parsing dos dados

Durante o parsing de valores Dynamic a partir dos dados, quando o limite é atingido no bloco de dados atual, todos os novos valores serão inseridos na estrutura de dados compartilhada:
Como podemos ver, após a inserção de 3 tipos de dados diferentes — Int64, Array(Int64) e String —, todos os novos tipos foram inseridos em uma estrutura de dados compartilhada especial.

Durante mesclagens de partes de dados em motores de tabela MergeTree

Durante a mesclagem de várias partes de dados em uma tabela MergeTree, a coluna Dynamic na parte de dados resultante pode atingir o limite de diferentes tipos de dados que podem ser armazenados em subcolunas separadas e não conseguir armazenar todos os tipos como subcolunas das partes de origem. Nesse caso, o ClickHouse escolhe quais tipos permanecerão como subcolunas separadas após a mesclagem e quais tipos serão inseridos na estrutura de dados compartilhada. Na maioria dos casos, o ClickHouse tenta manter os tipos mais frequentes e armazenar os mais raros na estrutura de dados compartilhada, mas isso depende da implementação. Vamos ver um exemplo desse tipo de mesclagem. Primeiro, vamos criar uma tabela com uma coluna Dynamic, definir o limite de diferentes tipos de dados como 3 e inserir valores com 5 tipos diferentes:
Cada inserção criará uma parte de dados separada, com a coluna Dynamic contendo um único tipo:
Agora, vamos unir todas as partes em uma só e ver o que acontece:
Como podemos ver, o ClickHouse manteve os tipos mais frequentes UInt64 e Array(UInt64) como subcolunas e inseriu todos os demais tipos nos dados compartilhados.

Funções JSONExtract com Dynamic

Todas as funções JSONExtract* são compatíveis com o tipo Dynamic:

Formato de saída binária

No formato RowBinary, os valores do tipo Dynamic são serializados no formato a seguir:
Última modificação em 10 de junho de 2026