Snowflake MigrationClickHouse Workshops
Planilhas de planejamento

Planilha 3: tradução do esquema

Mapeie cada coluna de TRIPS_RAW e FACT_TRIPS para seu tipo ClickHouse e traduza sete expressões do Snowflake, com feedback imediato para cada resposta.

Tempo estimado: 20–25 minutos Referência: Snowflake versus ClickHouse — seção 2 (diferenças entre os dialetos SQL)

Conceito

O mapeamento de tipos e a tradução de funções são a parte mais mecânica da migração, mas também a mais propensa a erros quando feita sem cuidado. Snowflake e ClickHouse têm sistemas de tipos e semânticas diferentes; usar o tipo incorreto pode causar perda silenciosa de precisão, armazenamento excessivo ou falhas na lógica das consultas.

Princípios fundamentais:

  1. Seja explícito sobre a precisão. TIMESTAMP_NTZ(9) do Snowflake tem precisão de nanossegundos. DateTime do ClickHouse tem precisão de apenas um segundo; não o use em colunas de versão. Use DateTime64(3, 'UTC') para precisão de milissegundos (que atende à maioria dos requisitos reais) ou DateTime64(9, 'UTC') para nanossegundos. Isso afeta a correção: se a coluna de versão de um ReplacingMergeTree tiver precisão de apenas um segundo, duas atualizações recebidas no mesmo segundo terão resultado não determinístico; o ClickHouse não conseguirá saber qual é a mais recente.

  2. Use o menor tipo inteiro correto. INTEGER do Snowflake é NUMBER(38, 0): precisão fixa de 38 dígitos, armazenada como um valor de 128 bits. O ClickHouse tem inteiros de largura fixa: Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64. Escolher UInt8 para vendor_id (valores de 1 a 3) economiza 7 bytes por linha em relação a Int64. Em 50 milhões de linhas, são 350 MB.

  3. VARIANT → String. O ClickHouse tem um tipo JSON nativo (estável para produção a partir da v25.3), mas ele foi projetado para esquemas realmente dinâmicos, cujos nomes e estruturas de campos são desconhecidos na criação da tabela. Para trip_metadata neste laboratório, a estrutura é conhecida (driver.rating, app.surge_multiplier, etc.). É melhor pré-achatar os dados em colunas tipadas durante a migração ou armazená-los como String e usar JSONExtract* nas consultas. Use o tipo JSON quando for realmente impossível prever o esquema, como na ingestão de cargas arbitrárias de eventos de clientes em que cada evento tem campos diferentes. (“Pré-achatar em colunas tipadas” significa extrair os campos em colunas distintas de primeiro nível durante o ETL — como FACT_TRIPS.driver_rating é gerado a partir de trip_metadata — e não envolver o próprio bloco JSON em um Tuple. Uma coluna Tuple ainda se compromete com um conjunto fixo de campos e falha assim que os metadados de uma corrida não correspondem a esse formato.)

  4. Precisão de ponto flutuante. FLOAT do Snowflake corresponde a Float64 no ClickHouse. Para valores monetários que exigem aritmética decimal exata, use Decimal(18, 2), mas neste laboratório Float64 basta para corresponder à origem. (Esse é um padrão, não uma regra de que toda coluna FLOAT deve usar Float64 independentemente da faixa: uma coluna como driver_rating, com valores de 1,0 a 5,0 e uma casa decimal, cabe com folga nos cerca de 7 dígitos significativos de Float32; nesse caso, a decisão depende da nulabilidade, não da precisão que a regra 4 protege para dinheiro.)

  5. LowCardinality() — otimização exclusiva do ClickHouse. Envolver um tipo em LowCardinality(String) (ou LowCardinality(UInt8), etc.) orienta o ClickHouse a usar codificação por dicionário nessa coluna: os valores são armazenados como referências inteiras a um dicionário, e não como strings repetidas. Normalmente, isso melhora a compressão de 2 a 5 vezes e acelera GROUP BY em colunas de string com menos de aproximadamente 10 mil valores distintos. O Snowflake não tem equivalente; ele cuida disso automaticamente. Bons candidatos neste laboratório: pickup_borough (6 valores), payment_type (6 valores), vehicle_type, vendor_name.

Exercício: mapeamento de tipos para TRIPS_RAW

Mapeie cada coluna de NYC_TAXI_DB.RAW.TRIPS_RAW para seu tipo ClickHouse. TRIP_ID está preenchido como exemplo: String é idiomático na migração a partir de VARCHAR(36), pois dispensa conversão, aceita todas as funções de string e evita o custo de análise de UUID durante a inserção, embora o ClickHouse também tenha um tipo UUID nativo.

Exercício: mapeamento de tipos para FACT_TRIPS

FACT_TRIPS acrescenta colunas calculadas ou derivadas pelo pipeline dbt. A maioria repete uma decisão de TRIPS_RAW; DRIVER_RATING e UPDATED_AT são novas.

DRIVER_RATING costuma ser NULL (nenhuma avaliação fornecida). No ClickHouse, Nullable(Float64) tem uma pequena sobrecarga de desempenho em relação a uma coluna não anulável: uma máscara de bits separada é armazenada junto aos dados para indicar as linhas nulas. A escolha para esta coluna fica entre Nullable(Float32) (semântica de nulo explícita) e um Float32 simples com um valor sentinela como -1.0 (mais rápido, menos convencional). Este laboratório usa Nullable(Float32) para manter a correção.

Exercício: tradução de funções

Traduza cada expressão do Snowflake para seu equivalente no ClickHouse. Elas vêm diretamente de Q1 a Q7 em 01-setup-snowflake/queries/. Três das oito — QUALIFY, MERGE INTO e a leitura do stream CDC — não têm como resposta uma expressão de uma única linha; elas são trabalhadas nas perguntas abaixo da tabela.

Questões de reflexão

Depois de preencher as tabelas, responda às perguntas. Três vêm das traduções do exercício 3 que precisaram de mais de uma linha; as outras três são as “decisões de tradução menos óbvias” da planilha de origem — o raciocínio por trás das escolhas de tipo para TRIP_METADATA, FARE_AMOUNT e PICKUP_LOCATION_ID acima.

Loading worksheet...

Transferência para migration-plan.md

Copie suas decisões de tipo e todas as observações de tradução menos óbvias para a seção 5 de migration-plan.md e marque:

- [ ] Schema translation: completed

Nesta página

Acompanhar seu progresso?

Opcional. Enviaremos um link por e-mail para confirmar seu endereço; o progresso será registrado depois que você o abrir.

Use seu e-mail corporativo, não um endereço pessoal.

O acompanhamento do progresso também exige a aceitação dos Termos de Serviço atuais nas Configurações de privacidade.

PT