Pular para o conteúdo principal
Arquivos Tab Separated Value, ou TSV, são comuns e podem incluir nomes de campos na primeira linha do arquivo. O ClickHouse pode fazer a ingestão de arquivos TSV e também consultar arquivos TSV sem ingestão. Este guia aborda esses dois casos. Se você precisar consultar ou fazer a ingestão de arquivos CSV, as mesmas técnicas funcionam: basta substituir TSV por CSV nos argumentos de formato. Ao seguir este guia, você vai:
  • Investigar: consultar a estrutura e o conteúdo do arquivo TSV.
  • Determinar o esquema de destino no ClickHouse: escolher os tipos de dados adequados e mapear os dados existentes para esses tipos.
  • Criar uma tabela no ClickHouse.
  • Pré-processar e enviar em stream os dados para o ClickHouse.
  • Executar algumas consultas no ClickHouse.
O conjunto de dados usado neste guia vem da equipe do NYC Open Data e contém dados sobre “todos os crimes válidos de felony, misdemeanor e violation reportados ao New York City Police Department (NYPD)”. No momento da redação, o arquivo de dados tem 166 MB, mas é atualizado regularmente. Origem: data.cityofnewyork.us Termos de uso: https://www1.nyc.gov/home/terms-of-use.page

Pré-requisitos

Uma observação sobre os comandos descritos neste guia

Há dois tipos de comandos neste guia:
  • Alguns comandos consultam os arquivos TSV; eles são executados no prompt de comando.
  • Os demais comandos consultam o ClickHouse e são executados no clickhouse-client ou na UI Play.
Os exemplos neste guia pressupõem que você salvou o arquivo TSV em ${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv; ajuste os comandos, se necessário.

Conheça o arquivo TSV

Antes de começar a trabalhar com o banco de dados ClickHouse, conheça os dados.

Veja os campos do arquivo TSV de origem

Este é um exemplo de comando para consultar um arquivo TSV, mas não o execute ainda.
Query
Resposta de exemplo
Na maioria das vezes, o comando acima informará quais campos nos dados de entrada são numéricos, quais são strings e quais são tuplas. Isso nem sempre acontece. Como o ClickHouse é usado rotineiramente com conjuntos de dados que contêm bilhões de registros, há um número padrão (100) de linhas examinadas para inferir o esquema, a fim de evitar a análise de bilhões de linhas para inferir o esquema. A resposta abaixo pode não corresponder ao que você vê, pois o conjunto de dados é atualizado várias vezes ao ano. Ao consultar o Dicionário de Dados, você verá que CMPLNT_NUM está especificado como texto, e não como valor numérico. Ao substituir o padrão de 100 linhas para inferência pela configuração SETTINGS input_format_max_rows_to_read_for_schema_inference=2000 você pode ter uma ideia melhor do conteúdo.Observação: a partir da versão 22.5, o padrão passou a ser 25.000 linhas para inferir o esquema, portanto altere essa configuração apenas se você estiver usando uma versão mais antiga ou se precisar que mais de 25.000 linhas sejam amostradas.
Execute este comando no prompt de comando. Você usará clickhouse-local para consultar os dados no arquivo TSV que baixou.
Query
Response
Neste ponto, você deve verificar se as colunas do arquivo TSV correspondem aos nomes e tipos especificados na seção Columns in this Dataset da página do conjunto de dados. Os tipos de dados não são muito específicos: todos os campos numéricos estão definidos como Nullable(Float64), e todos os demais campos como Nullable(String). Ao criar uma tabela no ClickHouse para armazenar os dados, você pode especificar tipos mais adequados e com melhor desempenho.

Determine o esquema adequado

Para determinar quais tipos devem ser usados nos campos, é necessário saber como os dados se apresentam. Por exemplo, o campo JURISDICTION_CODE é numérico: ele deve ser UInt8 ou Enum, ou Float64 seria apropriado?
Query
Response
A resposta da consulta mostra que JURISDICTION_CODE se ajusta bem a um UInt8. Da mesma forma, examine alguns dos campos String e veja se eles se encaixam bem como campos DateTime ou LowCardinality(String). Por exemplo, o campo PARKS_NM é descrito como “Nome do parque, playground ou área verde em Nova York onde ocorreu o registro, se aplicável (parques estaduais não estão incluídos)”. Os nomes dos parques da cidade de Nova York podem ser um bom candidato para LowCardinality(String):
Query
Response
Confira alguns dos nomes dos parques:
Query
Response
O conjunto de dados em uso no momento da redação tem apenas algumas centenas de parques e playgrounds distintos na coluna PARK_NM. Esse é um número baixo, com base na recomendação de LowCardinality de manter menos de 10.000 strings distintas em um campo LowCardinality(String).

Campos DateTime

Com base na seção Columns in this Dataset da página do conjunto de dados, há campos de data e hora para o início e o fim do evento relatado. Observar os valores mínimo e máximo de CMPLNT_FR_DT e CMPLT_TO_DT ajuda a entender se esses campos são sempre preenchidos ou não:
Query
Response
Query
Response
Query
Response
Query
Response

Elabore um plano

Com base na investigação acima:
  • JURISDICTION_CODE deve ser convertido para UInt8.
  • PARKS_NM deve ser convertido para LowCardinality(String)
  • CMPLNT_FR_DT e CMPLNT_FR_TM estão sempre preenchidos (possivelmente com o horário padrão 00:00:00)
  • CMPLNT_TO_DT e CMPLNT_TO_TM podem estar vazios
  • As datas e os horários são armazenados em campos separados na origem
  • As datas estão no formato mm/dd/yyyy
  • Os horários estão no formato hh:mm:ss
  • Datas e horários podem ser concatenados em tipos DateTime
  • Há algumas datas anteriores a 1º de janeiro de 1970, o que significa que precisamos de um DateTime de 64 bits
Há muitas outras alterações a serem feitas nos tipos, e todas elas podem ser determinadas seguindo as mesmas etapas de investigação. Observe o número de strings distintas em um campo, os valores mínimo e máximo dos números e tome suas decisões. O esquema da tabela apresentado mais adiante no guia tem muitas strings de baixa cardinalidade e campos inteiros sem sinal, além de pouquíssimos números de ponto flutuante.

Concatene os campos de data e hora

Para concatenar os campos de data e hora CMPLNT_FR_DT e CMPLNT_FR_TM em uma única String que possa ser convertida para DateTime, selecione os dois campos unidos pelo operador de concatenação: CMPLNT_FR_DT || ' ' || CMPLNT_FR_TM. Os campos CMPLNT_TO_DT e CMPLNT_TO_TM são tratados da mesma forma.
Query
Response

Converta a String de data e hora em um tipo DateTime64

Anteriormente, neste guia, vimos que há datas no arquivo TSV anteriores a 1º de janeiro de 1970, o que significa que precisamos de um tipo DateTime de 64 bits para essas datas. As datas também precisam ser convertidas do formato MM/DD/YYYY para YYYY/MM/DD. Ambas as tarefas podem ser feitas com parseDateTime64BestEffort().
Query
As linhas 2 e 3 acima contêm a concatenação da etapa anterior, e as linhas 4 e 5 acima fazem o parse das strings para DateTime64. Como não há garantia de que o horário de término da reclamação exista, usa-se parseDateTime64BestEffortOrNull.
Response
As datas exibidas acima como 1925 se devem a erros nos dados. Há vários registros nos dados originais com datas nos anos 1019 - 1022 que deveriam ser 2019 - 2022. Essas datas estão sendo armazenadas como 1º de janeiro de 1925, pois essa é a data mais antiga compatível com um DateTime de 64 bits.

Criar uma tabela

As decisões tomadas acima sobre os tipos de dados usados nas colunas estão refletidas no esquema da tabela abaixo. Também precisamos definir o ORDER BY e a PRIMARY KEY da tabela. Pelo menos um entre ORDER BY e PRIMARY KEY deve ser especificado. Aqui estão algumas diretrizes para decidir quais colunas incluir em ORDER BY; mais informações estão na seção Próximos passos no final deste documento.

Cláusulas ORDER BY e PRIMARY KEY

  • A tupla ORDER BY deve incluir campos usados nos filtros da consulta
  • Para maximizar a compressão em disco, a tupla ORDER BY deve ser ordenada por cardinalidade crescente
  • Se existir, a tupla PRIMARY KEY deve ser um subconjunto da tupla ORDER BY
  • Se apenas ORDER BY for especificada, a mesma tupla será usada como PRIMARY KEY
  • O índice da chave primária é criado usando a tupla PRIMARY KEY, se especificada; caso contrário, a tupla ORDER BY
  • O índice PRIMARY KEY é mantido na memória principal
Ao analisar o conjunto de dados e as perguntas que poderiam ser respondidas ao consultá-lo, podemos decidir que gostaríamos de observar os tipos de crimes reportados ao longo do tempo nos cinco distritos da cidade de Nova York. Esses campos poderiam então ser incluídos no ORDER BY: Consultando o arquivo TSV para a cardinalidade das três colunas candidatas:
Query
Response
Ao ordenar por cardinalidade, o ORDER BY fica:
A tabela abaixo usará nomes de colunas mais fáceis de ler; os nomes acima serão mapeados para
Ao combinar as alterações nos tipos de dados e a tupla ORDER BY, chega-se a esta estrutura de tabela:

Encontrando a chave primária de uma tabela

O banco de dados system do ClickHouse, mais especificamente system.table, contém todas as informações sobre a tabela que você acabou de criar. Esta consulta mostra o ORDER BY (chave de ordenação) e a PRIMARY KEY:
Resposta

Pré-processar e importar dados

Usaremos a ferramenta clickhouse-local para pré-processar os dados e o clickhouse-client para enviá-los.

Argumentos usados no clickhouse-local

table='input' aparece nos argumentos do clickhouse-local abaixo. O clickhouse-local recebe a entrada fornecida (cat ${HOME}/NYPD_Complaint_Data_Current__Year_To_Date_.tsv) e insere esses dados em uma tabela. Por padrão, a tabela se chama table. Neste guia, o nome da tabela é definido como input para deixar o fluxo de dados mais claro. O argumento final do clickhouse-local é uma consulta que seleciona dados da tabela (FROM input), que então é enviada por pipe para o clickhouse-client para preencher a tabela NYPD_Complaint.

Valide os dados

O conjunto de dados muda uma ou mais vezes por ano, então suas contagens podem não corresponder às deste documento.
Query
Response
O tamanho do conjunto de dados no ClickHouse corresponde a apenas 12% do arquivo TSV original; compare o tamanho do arquivo TSV original com o da tabela:
Query
Response

Execute algumas consultas

Consulta 1. Compare o número de reclamações por mês

Query
Response

Consulta 2. Compare o número total de reclamações por distrito

Query
Response

Próximos passos

Uma introdução prática aos índices primários esparsos no ClickHouse discute as diferenças de indexação no ClickHouse em comparação com bancos de dados relacionais tradicionais, como o ClickHouse cria e usa um índice primário esparso e as práticas recomendadas de indexação.
Última modificação em 3 de julho de 2026