# Delta Lake vs Apache Iceberg em 2026: Arquitetura Lakehouse e Perguntas de Entrevista > Comparação técnica completa entre Delta Lake e Apache Iceberg para arquiteturas lakehouse modernas. Guia prático com exemplos de código e perguntas de entrevista para data engineering. - Published: 2026-07-21 - Updated: 2026-07-21 - Author: SharpSkill - Reading time: 8 min --- Delta Lake e Apache Iceberg representam os dois formatos de tabela abertos dominantes que impulsionam as arquiteturas data lakehouse modernas em 2026. Ambas as tecnologias resolvem o mesmo problema fundamental—trazer transações ACID, evolução de schema e viagem no tempo para o armazenamento de objetos na nuvem—mas adotam abordagens arquiteturais diferentes que importam para cargas de trabalho em produção. > **Comparação Rápida** > > Delta Lake se destaca em ambientes nativos Spark com integração estreita ao Databricks, enquanto Iceberg oferece compatibilidade mais ampla com engines (Spark, Trino, Flink, Dremio) e particionamento mais flexível através de partições ocultas e evolução de partições. ## Delta Lake vs Iceberg: Diferenças Arquiteturais Fundamentais Ambos os formatos armazenam dados como arquivos Parquet em armazenamento de objetos, mas suas camadas de metadados diferem significativamente. **Delta Lake** utiliza um log de transações (`_delta_log/`) contendo arquivos JSON que registram cada alteração. Cada commit cria um novo arquivo JSON, e checkpoints periódicos consolidam esses arquivos em Parquet para leituras mais rápidas. A especificação do protocolo Delta Lake define recursos de leitura/escrita versionados para compatibilidade futura. **Apache Iceberg** mantém uma hierarquia de arquivos de metadados: um arquivo JSON de metadados apontando para listas de manifestos, que por sua vez apontam para manifestos contendo estatísticas no nível do arquivo. Este design permite predicate pushdown na etapa de planejamento—o engine de consultas ignora arquivos inteiros antes de ler qualquer dado. | Recurso | Delta Lake | Apache Iceberg | |---------|------------|----------------| | Log de Transações | JSON + checkpoints Parquet | JSON metadados + arquivos de manifesto | | Evolução de Partições | Requer reescrita | In-place sem reescrita | | Suporte a Engines | Spark, Trino, Flink | Spark, Trino, Flink, Dremio, Athena | | Viagem no Tempo | Baseado em versões | Baseado em snapshots com branch/tag | | Evolução de Schema | Adicionar/renomear colunas | Adicionar/renomear/reordenar/ampliar colunas | ## Partições Ocultas: A Vantagem Chave do Iceberg O particionamento tradicional estilo Hive expõe as colunas de partição nas consultas (`WHERE year=2026 AND month=7`), acoplando o layout físico à sintaxe SQL. As partições ocultas do Iceberg desacoplam essas preocupações. ```python # iceberg_partition_example.py from pyiceberg.catalog import load_catalog from pyiceberg.schema import Schema from pyiceberg.types import StringType, TimestampType, LongType, NestedField from pyiceberg.partitioning import PartitionSpec, PartitionField from pyiceberg.transforms import MonthTransform # Definição do schema schema = Schema( NestedField(1, "event_id", LongType(), required=True), NestedField(2, "event_time", TimestampType(), required=True), NestedField(3, "user_id", StringType(), required=True), NestedField(4, "event_type", StringType(), required=False), ) # Partição oculta sobre o mês extraído de event_time partition_spec = PartitionSpec( PartitionField( source_id=2, # campo event_time field_id=1000, transform=MonthTransform(), name="event_time_month" ) ) # Criação da tabela com particionamento oculto catalog = load_catalog("production") catalog.create_table( identifier="analytics.events", schema=schema, partition_spec=partition_spec ) ``` Os usuários escrevem `WHERE event_time > '2026-01-01'` e o Iceberg elimina automaticamente as partições irrelevantes. Esta abordagem simplifica as consultas e permite a evolução de partições sem reescrever dados. ## Delta Lake: Gerenciamento do Log de Transações O mecanismo de log de transações do Delta Lake fornece rastreabilidade completa das alterações. Cada operação gera um arquivo JSON atômico no diretório `_delta_log`. ```python # delta_transaction_log.py from delta import DeltaTable from pyspark.sql import SparkSession spark = SparkSession.builder \ .appName("DeltaTransactionDemo") \ .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension") \ .config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog") \ .getOrCreate() # Criação de uma tabela Delta data = [(1, "2026-07-15", "click"), (2, "2026-07-16", "purchase")] df = spark.createDataFrame(data, ["id", "date", "event"]) df.write.format("delta").save("/data/events") # Acesso ao histórico de transações delta_table = DeltaTable.forPath(spark, "/data/events") history = delta_table.history() history.select("version", "timestamp", "operation", "operationMetrics").show() ``` Os checkpoints Parquet são criados a cada 10 commits por padrão, otimizando o desempenho de leitura ao evitar a reconstrução do estado a partir de múltiplos arquivos JSON. ## Evolução de Schema: Comparação Prática A evolução de schema representa um caso de uso crítico para pipelines de dados em produção. Ambos os formatos suportam adição de colunas, mas o Iceberg oferece capacidades mais avançadas. ```sql -- Evolução de schema Iceberg ALTER TABLE analytics.events ADD COLUMN device_type STRING; ALTER TABLE analytics.events ALTER COLUMN event_type SET NOT NULL; ALTER TABLE analytics.events RENAME COLUMN event_type TO action_type; -- Reordenamento de colunas (específico do Iceberg) ALTER TABLE analytics.events ALTER COLUMN device_type FIRST; ALTER TABLE analytics.events ALTER COLUMN user_id AFTER event_id; ``` ```sql -- Evolução de schema Delta Lake ALTER TABLE events ADD COLUMNS (device_type STRING); -- Renomear requer habilitar column mapping ALTER TABLE events SET TBLPROPERTIES ('delta.columnMapping.mode' = 'name'); ALTER TABLE events RENAME COLUMN event_type TO action_type; ``` O Delta Lake requer a habilitação explícita do column mapping para renomeação, enquanto o Iceberg o suporta nativamente através do seu sistema de identificadores de campo. ## Viagem no Tempo e Gerenciamento de Versões Ambos os formatos permitem consultar estados históricos dos dados, funcionalidade essencial para auditoria, debug e reprodutibilidade de análises. ```python # time_travel_comparison.py # Delta Lake - Viagem no tempo df_v1 = spark.read.format("delta").option("versionAsOf", 1).load("/data/events") df_timestamp = spark.read.format("delta").option("timestampAsOf", "2026-07-15").load("/data/events") # Restauração para uma versão anterior delta_table = DeltaTable.forPath(spark, "/data/events") delta_table.restoreToVersion(1) ``` ```python # Iceberg - Viagem no tempo com snapshots from pyiceberg.catalog import load_catalog catalog = load_catalog("production") table = catalog.load_table("analytics.events") # Lista de snapshots disponíveis for snapshot in table.snapshots(): print(f"Snapshot {snapshot.snapshot_id}: {snapshot.timestamp_ms}") # Leitura de um snapshot específico df = spark.read \ .format("iceberg") \ .option("snapshot-id", 3821550127947089987) \ .load("analytics.events") # Branches e tags do Iceberg (funcionalidade avançada) # CREATE TAG production_v1 FOR TABLE analytics.events # CREATE BRANCH feature_test FOR TABLE analytics.events ``` O Iceberg oferece funcionalidades adicionais com branches e tags, permitindo workflows de desenvolvimento isolados sem duplicar dados. ## Otimização e Manutenção de Tabelas As operações de manutenção são cruciais para manter o desempenho das tabelas lakehouse ao longo do tempo. ```python # delta_optimization.py from delta.tables import DeltaTable delta_table = DeltaTable.forPath(spark, "/data/events") # Compactação de arquivos pequenos delta_table.optimize().executeCompaction() # Z-Ordering para melhorar o data skipping delta_table.optimize().executeZOrderBy("user_id", "event_time") # Vacuum para remover arquivos obsoletos delta_table.vacuum(168) # Retenção de 7 dias em horas # Estatísticas de colunas spark.sql("ANALYZE TABLE events COMPUTE STATISTICS FOR ALL COLUMNS") ``` ```python # iceberg_maintenance.py # Compactação Iceberg via Spark spark.sql(""" CALL system.rewrite_data_files( table => 'analytics.events', options => map('target-file-size-bytes', '134217728') ) """) # Expiração de snapshots spark.sql(""" CALL system.expire_snapshots( table => 'analytics.events', older_than => TIMESTAMP '2026-07-01 00:00:00', retain_last => 5 ) """) # Remoção de arquivos órfãos spark.sql(""" CALL system.remove_orphan_files( table => 'analytics.events', older_than => TIMESTAMP '2026-07-01 00:00:00' ) """) ``` ## Perguntas de Entrevista Data Engineering: Arquitetura Lakehouse As entrevistas de data engineering em 2026 frequentemente incluem perguntas sobre arquiteturas lakehouse. Estes são os temas técnicos essenciais para dominar. ### Pergunta 1: Explicar as vantagens das partições ocultas do Iceberg A resposta esperada deve cobrir: o desacoplamento entre o layout físico e a sintaxe SQL, a eliminação automática de partições pelo engine de consultas, e a possibilidade de evoluir o schema de particionamento sem reescrever os dados existentes. ### Pergunta 2: Como o Delta Lake garante transações ACID? O Delta Lake utiliza bloqueio otimista com um log de transações append-only. Cada commit verifica que a versão base não mudou desde a leitura. Em caso de conflito, a operação falha e pode ser reexecutada. Os checkpoints Parquet permitem uma reconstrução rápida do estado. ### Pergunta 3: Quando escolher Iceberg em vez de Delta Lake? O Iceberg é mais adequado quando: múltiplos engines de consulta precisam acessar os mesmos dados (Spark, Trino, Flink), a evolução de partições é uma necessidade recorrente, ou a organização prefere um formato verdadeiramente aberto sem dependência de um fornecedor específico. ```python # interview_code_example.py # Pergunta: Implementar um upsert com Delta Lake from delta.tables import DeltaTable def upsert_events(spark, source_df, target_path): """Merge incremental events into Delta table.""" target_table = DeltaTable.forPath(spark, target_path) target_table.alias("target").merge( source_df.alias("source"), "target.event_id = source.event_id" ).whenMatchedUpdate(set={ "event_time": "source.event_time", "event_type": "source.event_type", "updated_at": "current_timestamp()" }).whenNotMatchedInsert(values={ "event_id": "source.event_id", "event_time": "source.event_time", "event_type": "source.event_type", "created_at": "current_timestamp()", "updated_at": "current_timestamp()" }).execute() ``` ### Pergunta 4: Descrever a estratégia de data skipping Ambos os formatos mantêm estatísticas min/max por arquivo. Ao executar uma consulta com predicados, o engine compara os valores dos predicados com as estatísticas e elimina os arquivos que não podem conter correspondências. O Z-Ordering (Delta) e o sorting (Iceberg) melhoram a eficiência agrupando valores similares. ## Integração com Catálogos de Metadados Os catálogos de metadados centralizam o gerenciamento de tabelas lakehouse e permitem a descoberta de dados em escala organizacional. ```python # catalog_integration.py # Configuração Unity Catalog para Delta Lake spark = SparkSession.builder \ .config("spark.sql.catalog.unity", "com.databricks.sql.managedcatalog.UnityCatalogSpark") \ .config("spark.databricks.unityCatalog.enabled", "true") \ .getOrCreate() # Configuração Iceberg com AWS Glue Catalog spark = SparkSession.builder \ .config("spark.sql.catalog.glue_catalog", "org.apache.iceberg.spark.SparkCatalog") \ .config("spark.sql.catalog.glue_catalog.warehouse", "s3://datalake/warehouse") \ .config("spark.sql.catalog.glue_catalog.catalog-impl", "org.apache.iceberg.aws.glue.GlueCatalog") \ .config("spark.sql.catalog.glue_catalog.io-impl", "org.apache.iceberg.aws.s3.S3FileIO") \ .getOrCreate() # Configuração Iceberg com REST Catalog (Polaris, Tabular) spark = SparkSession.builder \ .config("spark.sql.catalog.rest_catalog", "org.apache.iceberg.spark.SparkCatalog") \ .config("spark.sql.catalog.rest_catalog.type", "rest") \ .config("spark.sql.catalog.rest_catalog.uri", "https://catalog.example.com") \ .getOrCreate() ``` ## Performance: Benchmarks e Considerações O desempenho depende fortemente do caso de uso específico, do tamanho dos dados e do engine de consultas utilizado. Para leituras analíticas intensivas, o Iceberg pode oferecer vantagem graças ao seu planejamento de consultas mais eficiente baseado em manifestos. Para workloads de streaming com micro-batches frequentes, o Delta Lake com seu log de transações otimizado pode ser mais performático. ```python # performance_monitoring.py # Métricas Delta Lake spark.sql("DESCRIBE HISTORY events").show() spark.sql("DESCRIBE DETAIL events").show() # Métricas Iceberg spark.sql("SELECT * FROM analytics.events.metadata_log_entries").show() spark.sql("SELECT * FROM analytics.events.manifests").show() spark.sql("SELECT * FROM analytics.events.files").show() ``` ## Conclusão Delta Lake e Apache Iceberg representam duas abordagens maduras para arquitetura lakehouse em 2026. O Delta Lake oferece integração nativa com o ecossistema Databricks e Spark, enquanto o Iceberg prioriza a interoperabilidade multi-engine e a flexibilidade do particionamento. A escolha entre essas tecnologias depende principalmente do ecossistema existente, dos requisitos de interoperabilidade e dos padrões de acesso aos dados. Ambos os formatos continuam evoluindo com funcionalidades convergentes, como o Delta Lake UniForm que permite a leitura de tabelas Delta através das APIs do Iceberg. Para entrevistas de data engineering, o domínio dos conceitos fundamentais—transações ACID sobre armazenamento de objetos, evolução de schema, viagem no tempo e otimização de performance—permanece mais importante do que o conhecimento profundo de um formato específico. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pt/blog/data-engineering/delta-lake-vs-iceberg-lakehouse-interview-2026