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:
-
Seja explícito sobre a precisão.
TIMESTAMP_NTZ(9)do Snowflake tem precisão de nanossegundos.DateTimedo ClickHouse tem precisão de apenas um segundo; não o use em colunas de versão. UseDateTime64(3, 'UTC')para precisão de milissegundos (que atende à maioria dos requisitos reais) ouDateTime64(9, 'UTC')para nanossegundos. Isso afeta a correção: se a coluna de versão de umReplacingMergeTreetiver 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. -
Use o menor tipo inteiro correto.
INTEGERdo 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. EscolherUInt8paravendor_id(valores de 1 a 3) economiza 7 bytes por linha em relação aInt64. Em 50 milhões de linhas, são 350 MB. -
VARIANT → String. O ClickHouse tem um tipo
JSONnativo (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. Paratrip_metadataneste 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 comoStringe usarJSONExtract*nas consultas. Use o tipoJSONquando 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 — comoFACT_TRIPS.driver_ratingé gerado a partir detrip_metadata— e não envolver o próprio bloco JSON em umTuple. Uma colunaTupleainda se compromete com um conjunto fixo de campos e falha assim que os metadados de uma corrida não correspondem a esse formato.) -
Precisão de ponto flutuante.
FLOATdo Snowflake corresponde aFloat64no ClickHouse. Para valores monetários que exigem aritmética decimal exata, useDecimal(18, 2), mas neste laboratórioFloat64basta para corresponder à origem. (Esse é um padrão, não uma regra de que toda colunaFLOATdeve usarFloat64independentemente da faixa: uma coluna comodriver_rating, com valores de 1,0 a 5,0 e uma casa decimal, cabe com folga nos cerca de 7 dígitos significativos deFloat32; nesse caso, a decisão depende da nulabilidade, não da precisão que a regra 4 protege para dinheiro.) -
LowCardinality()— otimização exclusiva do ClickHouse. Envolver um tipo emLowCardinality(String)(ouLowCardinality(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 aceleraGROUP BYem 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: completedPlanilha 2: projeto da chave de ordenação (ORDER BY)
Derive um ORDER BY para cada tabela de táxis de NYC a partir de sua carga de consultas, com feedback imediato para cada resposta.
Planilha 4: plano de ondas da migração
Distribua dez objetos de táxis de NYC em ondas de migração e classifique a complexidade de cada um, com feedback imediato para cada resposta.