Dynamic, use a seguinte sintaxe:
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
Dynamic na definição de uma coluna da tabela:
Variant:
Lendo tipos aninhados de Dynamic como subcolunas
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:
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
Dynamic.
Convertendo uma coluna comum em uma coluna Dynamic
Convertendo uma coluna String em uma coluna Dynamic por meio de parsing
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
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)
K >= N, os dados não mudam durante a conversão:
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:
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
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
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:
Dynamic, uma exceção será lançada:
Comportamento em caso de incompatibilidade de tipo
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— retornaNULLpara as linhas incompatíveis e mantém o resultado para as linhas compatíveis.
Usando o tipo Dynamic em ORDER BY e GROUP BY
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).
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:
</>/= 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
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
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:
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
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:
Dynamic contendo um único tipo:
UInt64 e Array(UInt64) como subcolunas e inseriu todos os demais tipos nos dados compartilhados.
Funções JSONExtract com Dynamic
JSONExtract* são compatíveis com o tipo Dynamic:
Formato de saída binária
Dynamic são serializados no formato a seguir: