O que Construção de Tabelas Iceberg faz?
Quando usar
- Criar ou manter tabelas Apache Iceberg em um lakehouse.
- Escolher particionamento, ou evoluir particionamento/esquema sem reescritas.
- Gerenciar snapshots, viagem no tempo, compactação e arquivos pequenos.
- NÃO usar para trabalhos específicos do Delta (use
engineering-databricks-pipelines).
Fluxo de trabalho
- [ ] Particionar por colunas de filtro de consulta; usar transformações de partição ocultas
- [ ] Usar MERGE para upserts idempotentes
- [ ] Agendar compactação (rewrite_data_files) para corrigir arquivos pequenos
- [ ] Expirar snapshots antigos + remover arquivos órfãos para controlar metadados/armazenamento
- [ ] Evoluir particionamento/esquema por ID de campo (sem reescrita de dados)
- Particionar por colunas de filtro usando transformações de partição ocultas
(
days(ts),bucket(N, id)), para que consultas podem podar sem que usuários adicionem colunas derivadas de partição. - Escritas idempotentes via
MERGE INTOchaveado pela chave de negócio. - Compactar regularmente — escritas em lote/streaming criam muitos arquivos pequenos;
rewrite_data_filesrestaura o desempenho de leitura. - Manter metadados — expirar snapshots antigos e remover arquivos órfãos, caso contrário o histórico de snapshots e o armazenamento crescem sem limites.
- Evoluir livremente — Iceberg rastreia colunas/partições por ID, então adicionar/remover/renomear e até mesmo alterações na especificação de partição não necessitam de reescrita de dados.
Padrões
Criar com particionamento oculto + upsert MERGE:
CREATE TABLE lake.db.orders (order_id BIGINT, customer_id BIGINT, amount DECIMAL, ordered_at TIMESTAMP)
USING iceberg PARTITIONED BY (days(ordered_at));
MERGE INTO lake.db.orders t USING staging s ON t.order_id = s.order_id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *;
Manutenção (procedimentos Spark):
CALL lake.system.rewrite_data_files('db.orders'); -- compactar arquivos pequenos
CALL lake.system.expire_snapshots('db.orders', TIMESTAMP '2026-08-01 00:00:00');
CALL lake.system.remove_orphan_files(table => 'db.orders');
Viagem no tempo — ler um snapshot anterior para auditoria ou recuperação:
SELECT * FROM lake.db.orders VERSION AS OF <snapshot_id>.
Evolução de partição — ALTER TABLE ... ADD PARTITION FIELD bucket(16, customer_id)
aplica-se apenas a novos dados; dados antigos permanecem válidos.
Armadilhas comuns
- Sem compactação em tabelas de streaming — explosão de arquivos pequenos prejudica velocidade de leitura.
- Nunca expirar snapshots — metadados e armazenamento crescem indefinidamente; agende expiração dentro de sua retenção de viagem no tempo.
- Particionamento excessivo (ex.: por hora em baixo volume) — muitas partições minúsculas; ajuste a granularidade ao tamanho dos dados.
- Adicionar colunas de partição derivadas explícitas — anula o propósito do particionamento oculto; use transformações.
- Sobrescrita cega em vez de MERGE — perde idempotência; use MERGE por chave.
- Remover arquivos órfãos com janela muito curta — pode deletar arquivos que escritores ainda precisam; use um limite seguro.