ON CLUSTER, que é descrita separadamente.
Variações de sintaxe
Com esquema explícito
table_name no banco de dados db ou no banco de dados atual, se db não estiver definido, com a estrutura especificada entre colchetes e o engine especificado.
A estrutura da tabela é uma lista de descrições de colunas, índices secundários, projeções e restrições. Se a chave primária for compatível com o engine, ela será indicada como parâmetro do motor de tabela.
Uma descrição de coluna é name type no caso mais simples. Exemplo: RegionID UInt32.
Expressões também podem ser definidas para valores padrão (veja abaixo).
Se necessário, a chave primária pode ser especificada com uma ou mais expressões-chave.
Comentários podem ser adicionados às colunas e à tabela.
Com o esquema de uma tabela existente
Com o esquema e os dados de uma tabela existente
db.table são anexadas a ela. Em outras palavras, os dados de db.table são clonados para db2.table_clone no momento da criação. Esta consulta é equivalente à seguinte:
db.table).
De uma função de tabela
A partir da consulta SELECT
SELECT, com o motor engine, e a preenche com os dados de SELECT. Você também pode especificar explicitamente a definição das colunas.
Se a tabela já existir e IF NOT EXISTS for especificado, a consulta não fará nada.
Pode haver outras cláusulas após a cláusula ENGINE na consulta. Veja a documentação detalhada sobre como criar tabelas nas descrições de motores de tabela.
Exemplo
Query
Response
Modificadores NULL ou NOT NULL
NULL e NOT NULL, quando usados após o tipo de dado na definição da coluna, indicam se ela pode ou não ser Nullable.
Se o tipo não for Nullable e NULL for especificado, ele será tratado como Nullable; se NOT NULL for especificado, não será. Por exemplo, INT NULL é o mesmo que Nullable(INT). Se o tipo for Nullable e os modificadores NULL ou NOT NULL forem especificados, uma exceção será gerada.
Veja também a configuração data_type_default_nullable.
Valores padrão
DEFAULT expr, MATERIALIZED expr ou ALIAS expr. Exemplo: URLDomain String DEFAULT domain(URL).
A expressão expr é opcional. Se for omitida, o tipo da coluna deve ser especificado explicitamente, e o valor padrão será 0 para colunas numéricas, '' (a string vazia) para colunas de string, [] (o array vazio) para colunas de array, 1970-01-01 para colunas de data ou NULL para colunas Nullable.
O tipo da coluna com valor padrão pode ser omitido; nesse caso, ele é inferido a partir do tipo de expr. Por exemplo, o tipo da coluna EventDate DEFAULT toDate(EventTime) será date.
Se um tipo de dado e uma expressão de valor padrão forem especificados, será inserida uma função implícita de conversão de tipo que converte a expressão para o tipo especificado. Exemplo: Hits UInt32 DEFAULT 0 é representado internamente como Hits UInt32 DEFAULT toUInt32(0).
Uma expressão de valor padrão expr pode referenciar colunas arbitrárias da tabela e constantes. O ClickHouse verifica se alterações na estrutura da tabela não introduzem loops no cálculo da expressão. Para INSERT, ele verifica se as expressões podem ser resolvidas — isto é, se todas as colunas a partir das quais elas podem ser calculadas foram fornecidas.
DEFAULT
DEFAULT expr
Valor padrão comum. Se o valor dessa coluna não for especificado em uma consulta INSERT, ele será calculado com base em expr.
Exemplo:
MATERIALIZED
MATERIALIZED expr
Expressão materializada. Os valores dessas colunas são calculados automaticamente de acordo com a expressão materializada especificada quando as linhas são inseridas. Não é possível especificar explicitamente esses valores durante INSERTs.
Além disso, colunas com valor padrão desse tipo não são incluídas no resultado de SELECT *. Isso preserva a invariante de que o resultado de um SELECT * sempre pode ser inserido de volta na tabela usando INSERT. Esse comportamento pode ser desativado com a configuração asterisk_include_materialized_columns.
Exemplo:
EPHEMERAL
EPHEMERAL [expr]
Coluna efêmera. Colunas desse tipo não são armazenadas na tabela e não é possível consultá-las com SELECT. O único propósito das colunas efêmeras é servir de base para expressões de valor padrão de outras colunas.
Um insert sem colunas explicitamente especificadas ignorará colunas desse tipo. Isso preserva a invariante de que o resultado de um SELECT * sempre pode ser inserido de volta na tabela usando INSERT.
Exemplo:
ALIAS
ALIAS expr
Colunas calculadas (sinônimo). Colunas desse tipo não são armazenadas na tabela, e não é possível fazer INSERT de valores nelas.
Quando consultas SELECT fazem referência explícita a colunas desse tipo, o valor é calculado no momento da consulta a partir de expr. Por padrão, SELECT * exclui colunas ALIAS. Esse comportamento pode ser desativado com a configuração asterisk_include_alias_columns.
Ao usar a consulta ALTER para adicionar novas colunas, os dados antigos dessas colunas não são gravados. Em vez disso, ao ler dados antigos que não têm valores para as novas colunas, as expressões são calculadas dinamicamente por padrão. No entanto, se a execução dessas expressões exigir colunas diferentes que não estejam indicadas na consulta, essas colunas também serão lidas, mas apenas para os blocos de dados que precisarem disso.
Se você adicionar uma nova coluna a uma tabela, mas depois alterar sua expressão padrão, os valores usados para os dados antigos mudarão (para dados cujos valores não foram armazenados em disco). Observe que, ao executar mesclagens em segundo plano, os dados das colunas que estiverem ausentes em uma das partes que estão sendo mescladas serão gravados na parte mesclada.
Não é possível definir valores padrão para elementos em estruturas de dados aninhadas.
Você pode definir uma chave primária ao criar uma tabela. A chave primária pode ser especificada de duas formas:
- Na lista de colunas
- Fora da lista de colunas
Restrições
CONSTRAINT
boolean_expr_1 pode ser qualquer expressão booleana. Se forem definidas restrições para a tabela, cada uma delas será verificada para cada linha na consulta INSERT. Se alguma restrição não for atendida — o servidor gerará uma exceção com o nome da restrição e a expressão de verificação.
Adicionar um grande número de restrições pode afetar negativamente o desempenho de consultas INSERT grandes.
ASSUME
ASSUME é usada para definir uma CONSTRAINT em uma tabela que se presume ser true. Essa restrição pode então ser usada pelo otimizador para melhorar o desempenho das consultas SQL.
Veja este exemplo em que ASSUME CONSTRAINT é usado na criação da tabela users_a:
ASSUME CONSTRAINT é usado para declarar que a função length(name) é sempre igual ao valor da coluna name_len. Isso significa que, sempre que length(name) for chamada em uma consulta, o ClickHouse poderá substituí-la por name_len, o que tende a ser mais rápido, pois evita chamar a função length().
Assim, ao executar a consulta SELECT name FROM users_a WHERE length(name) < 5;, o ClickHouse pode otimizá-la para SELECT name FROM users_a WHERE name_len < 5; por causa de ASSUME CONSTRAINT. Isso pode fazer com que a consulta seja executada mais rapidamente, pois evita calcular o comprimento de name para cada linha.
ASSUME CONSTRAINT não impõe a restrição; ele apenas informa ao otimizador que a restrição é válida. Se a restrição não for realmente válida, os resultados das consultas poderão estar incorretos. Portanto, você só deve usar ASSUME CONSTRAINT se tiver certeza de que a restrição é válida.
Expressão TTL
Codecs de compressão de colunas
lz4 na versão autogerenciada e zstd no ClickHouse Cloud.
Para a família de engines MergeTree, você pode alterar o método de compressão padrão na seção compressão da configuração do servidor.
Você também pode definir o método de compressão para cada coluna na consulta CREATE TABLE.
Default pode ser especificado para fazer referência à compressão padrão, que pode depender de diferentes configurações (e das propriedades dos dados) em tempo de execução.
Exemplo: value UInt64 CODEC(Default) — o mesmo que não especificar um codec.
Você também pode remover o CODEC atual da coluna e usar a compressão padrão de config.xml:
CODEC(Delta, Default).
A compressão é compatível com os seguintes motores de tabela:
- Família MergeTree. Oferece suporte a codecs de compressão de colunas e à seleção do método de compressão padrão por meio das configurações de compression.
- Família Log. Usa o método de compressão
lz4por padrão e oferece suporte a codecs de compressão de colunas. - Set. Oferece suporte apenas à compressão padrão.
- Join. Oferece suporte apenas à compressão padrão.
Codecs de uso geral
NONE
NONE — Sem compressão.
LZ4
LZ4 — Algoritmo de compressão de dados sem perda usado por padrão. Aplica a compactação rápida LZ4.
LZ4HC
LZ4HC[(level)] — algoritmo LZ4 HC (alta compressão) com nível configurável. Nível padrão: 9. Se level <= 0, o nível padrão é aplicado. Níveis possíveis: [1, 12]. Faixa de níveis recomendada: [4, 9].
ZSTD
ZSTD[(level)] — algoritmo de compressão ZSTD com level configurável. Níveis possíveis: [1, 22]. Nível padrão: 1.
Níveis altos de compressão são úteis em cenários assimétricos, como comprimir uma vez e descomprimir repetidamente. Níveis mais altos significam melhor compressão e maior uso de CPU.
Obsoleto: ZSTD_QAT
Obsoleto: DEFLATE_QPL
Codecs especializados
Delta
Delta(delta_bytes) — Método de compressão em que os valores brutos são substituídos pela diferença entre dois valores vizinhos, exceto o primeiro valor, que permanece inalterado. delta_bytes é o tamanho máximo dos valores brutos; o valor padrão é sizeof(type). Especificar delta_bytes como argumento está obsoleto, e o suporte será removido em um lançamento futuro. Delta é um codec de preparação de dados, ou seja, não pode ser usado isoladamente.
DoubleDelta
DoubleDelta(bytes_size) — Calcula a delta das deltas e a grava em formato binário compacto. bytes_size tem significado semelhante a delta_bytes no codec Delta. Especificar bytes_size como argumento está obsoleto, e o suporte será removido em um lançamento futuro. As taxas de compressão ideais são obtidas para sequências monotônicas com passo constante, como séries temporais. Pode ser usado com qualquer tipo numérico. Implementa o algoritmo usado no Gorilla TSDB, estendendo-o para oferecer suporte a tipos de 64 bits. Usa 1 bit extra para deltas de 32 bits: prefixos de 5 bits em vez de prefixos de 4 bits. Para mais informações, consulte Compressing Time Stamps em Gorilla: A Fast, Scalable, In-Memory Time Series Database. DoubleDelta é um codec de preparação de dados, ou seja, não pode ser usado isoladamente.
GCD
GCD() - - Calcula o máximo divisor comum (GCD) dos valores da coluna e, em seguida, divide cada valor pelo GCD. Pode ser usado com colunas de inteiros, decimais e data/hora. O codec é particularmente adequado para colunas com valores que variam (aumentam ou diminuem) em múltiplos do GCD, por exemplo, 24, 28, 16, 24, 8, 24 (GCD = 4). GCD é um codec de preparação de dados, ou seja, não pode ser usado isoladamente.
Gorilla
Gorilla(bytes_size) — Calcula o XOR entre o valor atual de ponto flutuante e o anterior e o grava em formato binário compacto. Quanto menor a diferença entre valores consecutivos, ou seja, quanto mais lentamente os valores da série mudam, melhor a taxa de compressão. Implementa o algoritmo usado no Gorilla TSDB, estendendo-o para oferecer suporte a tipos de 64 bits. Os valores possíveis de bytes_size são: 1, 2, 4, 8; o valor padrão é sizeof(type) se ele for igual a 1, 2, 4 ou 8. Em todos os outros casos, é 1. Para mais informações, consulte a seção 4.1 de Gorilla: A Fast, Scalable, In-Memory Time Series Database.
ALP
ALP() — Compressão adaptativa sem perdas para dados de ponto flutuante baseada em escala decimal. O ALP tenta representar cada valor como um inteiro exato escalonado usando potências de 10 e, em seguida, comprime os inteiros resultantes com Frame-of-Reference e bit-packing. Valores que não podem ser representados com exatidão são armazenados como exceções brutas. Funciona melhor para números oriundos de valores decimais (por exemplo, medições e moeda). Compatível com Float32 e Float64. Para detalhes, consulte ALP: Adaptive lossless floating-point compression.
Este codec é experimental e requer
SET allow_experimental_codecs = 1 para ser usado.FPC
FPC(level, float_size) - Prediz repetidamente o próximo valor de ponto flutuante na sequência usando o melhor de dois preditores, depois aplica XOR entre o valor real e o valor previsto e comprime o resultado com zeros à esquerda. Assim como o Gorilla, é eficiente para armazenar uma série de valores de ponto flutuante que mudam lentamente. Para valores de 64 bits (double), o FPC é mais rápido que o Gorilla; para valores de 32 bits, o desempenho pode variar. Valores possíveis de level: 1-28; o valor padrão é 12. Valores possíveis de float_size: 4, 8; o valor padrão é sizeof(type) se o tipo for Float. Em todos os outros casos, é 4. Para uma descrição detalhada do algoritmo, consulte High Throughput Compression of Double-Precision Floating-Point Data.
T64
T64 — Abordagem de compressão que recorta os bits altos não utilizados dos valores em tipos de dados inteiros (incluindo Enum, Date e DateTime). Em cada passo do algoritmo, o codec pega um bloco de 64 valores, coloca-os em uma matriz de 64x64 bits, transpõe essa matriz, recorta os bits não utilizados dos valores e retorna o restante como uma sequência. Bits não utilizados são os bits que não diferem entre os valores máximo e mínimo em toda a data part para a qual a compressão é usada.
Os codecs DoubleDelta e Gorilla são usados no Gorilla TSDB como componentes do algoritmo de compressão. A abordagem Gorilla é eficaz em cenários em que há uma sequência de valores que mudam lentamente com seus timestamps. Os timestamps são comprimidos com eficiência pelo codec DoubleDelta, e os valores são comprimidos com eficiência pelo codec Gorilla. Por exemplo, para obter uma tabela armazenada com eficiência, você pode criá-la com a seguinte configuração:
Codecs de criptografia
AES_128_GCM_SIV
CODEC('AES-128-GCM-SIV') — Criptografa os dados usando AES-128 no modo GCM-SIV da RFC 8452.
AES-256-GCM-SIV
CODEC('AES-256-GCM-SIV') — Criptografa os dados com AES-256 no modo GCM-SIV.
Esses codecs usam um nonce fixo e, portanto, a criptografia é determinística. Isso os torna compatíveis com motores que fazem deduplicação, como ReplicatedMergeTree, mas há uma fraqueza: quando o mesmo bloco de dados é criptografado duas vezes, o texto cifrado resultante será exatamente o mesmo, de modo que um invasor que consiga ler o disco poderá perceber essa equivalência (embora apenas a equivalência, sem acessar o conteúdo).
A maioria dos motores, incluindo a família “*MergeTree”, cria arquivos de índice em disco sem aplicar codecs. Isso significa que texto simples aparecerá no disco se uma coluna criptografada for indexada.
Se você executar uma consulta SELECT mencionando um valor específico em uma coluna criptografada (como em sua cláusula WHERE), o valor poderá aparecer em system.query_log. Talvez você queira desativar o logging.
Se for necessário aplicar compressão, ela deverá ser especificada explicitamente. Caso contrário, apenas a criptografia será aplicada aos dados.
Tabelas temporárias
Observe que as tabelas temporárias não são replicadas. Como resultado, não há garantia de que os dados inseridos em uma tabela temporária estarão disponíveis em outras réplicas. O principal caso de uso em que tabelas temporárias podem ser úteis é consultar ou fazer join com pequenos conjuntos de dados externos durante uma única sessão.
- As tabelas temporárias desaparecem quando a sessão termina, inclusive se a conexão for perdida.
- Uma tabela temporária usa o motor de tabela Memory quando nenhum motor é especificado e pode usar qualquer motor de tabela, exceto os motores Replicated e
KeeperMap. - Não é possível especificar o DB para uma tabela temporária. Ela é criada fora dos bancos de dados.
- Não é possível criar uma tabela temporária com uma consulta DDL distribuída em todos os servidores do cluster (usando
ON CLUSTER): essa tabela existe apenas na sessão atual. - Se uma tabela temporária tiver o mesmo nome que outra tabela e uma consulta especificar o nome da tabela sem especificar o DB, a tabela temporária será usada.
- No processamento distribuído de consultas, tabelas temporárias com o motor Memory usadas em uma consulta são enviadas aos servidores remotos.
(GLOBAL) IN distribuído. Para mais informações, consulte as seções apropriadas
É possível usar tabelas com ENGINE = Memory em vez de tabelas temporárias.
REPLACE TABLE
REPLACE permite atualizar uma tabela atomicamente.
Esta instrução é compatível com os motores de banco de dados
Atomic e Replicated,
que são os motores de banco de dados padrão do ClickHouse e do ClickHouse Cloud, respectivamente.SELECT que não recupere os dados indesejados,
depois remover a tabela antiga e renomear a nova.
Essa abordagem é demonstrada no exemplo abaixo:
REPLACE (desde que você esteja usando os motores de banco de dados padrão) para obter o mesmo resultado:
Sintaxe
Todas as sintaxes da instrução
CREATE também funcionam para esta instrução. Executar REPLACE em uma tabela que não existe resultará em erro.Exemplos:
- Local
- Cloud
Considere a tabela a seguir:Podemos usar a instrução Ou podemos usar a instrução
REPLACE para apagar todos os dados:REPLACE para alterar a estrutura da tabela:Cláusula COMMENT
A cláusula
COMMENT deve ser especificada depois de quaisquer cláusulas específicas de armazenamento, como PARTITION BY, ORDER BY e SETTINGS específicos de armazenamento.Após a cláusula COMMENT, apenas SETTINGS específicos da consulta (como max_threads etc.) serão interpretados, e não as configurações relacionadas ao armazenamento.Isso significa que a ordem correta das cláusulas é:ENGINE- cláusulas de armazenamento
COMMENT- configurações da consulta (se houver)
Query
Response