Delta Lake é o table format padrão do Databricks. Toda tabela criada no Databricks é Delta por padrão. Adiciona transações ACID, time travel, schema enforcement e operações de manutenção sobre arquivos Parquet no object storage.
Ver conceitos gerais em formatos-de-arquivo-datalake. Esta nota foca nas operações e otimizações específicas do Databricks.
Estrutura física de uma tabela Delta
s3://lake/silver/pedidos/
├── _delta_log/ ← transaction log (JSON + checkpoint Parquet)
│ ├── 00000000000000000000.json
│ ├── 00000000000000000001.json
│ └── 00000000000000000010.checkpoint.parquet
├── part-00000-abc123.parquet
├── part-00001-def456.parquet
└── part-00002-ghi789.parquet
O _delta_log é o que torna uma pasta de Parquets em uma tabela Delta, contendo o histórico de cada operação.
Operações DML
MERGE (Upsert)
from delta.tables import DeltaTable
delta_tabela = DeltaTable.forName(spark, "silver.pedidos")
delta_tabela.alias("alvo").merge(
novos_dados.alias("origem"),
"alvo.pedido_id = origem.pedido_id"
).whenMatchedUpdateAll() \
.whenNotMatchedInsertAll() \
.execute()-- SQL equivalente
MERGE INTO silver.pedidos AS alvo
USING novos_pedidos AS origem
ON alvo.pedido_id = origem.pedido_id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *MERGE é a base do padrão SCD (Slowly Changing Dimensions) e de pipelines CDC.
DELETE e UPDATE
DELETE FROM silver.pedidos WHERE status = 'cancelado' AND data_pedido < '2024-01-01';
UPDATE silver.pedidos
SET status = 'processado', updated_at = current_timestamp()
WHERE status = 'pendente' AND data_pedido < current_date();Time Travel
-- Por versão
SELECT * FROM silver.pedidos VERSION AS OF 5;
-- Por timestamp
SELECT * FROM silver.pedidos TIMESTAMP AS OF '2026-01-15 08:00:00';
-- Ver histórico
DESCRIBE HISTORY silver.pedidos;# Python
df = spark.read.format("delta").option("versionAsOf", 5).table("silver.pedidos")
df = spark.read.format("delta").option("timestampAsOf", "2026-01-15").table("silver.pedidos")Time travel funciona enquanto os arquivos antigos não forem removidos pelo VACUUM.
OPTIMIZE e Z-ORDER
Com o tempo, tabelas Delta acumulam muitos arquivos pequenos (small files problem). OPTIMIZE os consolida.
-- Compactar arquivos pequenos
OPTIMIZE silver.pedidos;
-- Z-ORDER: co-localiza dados por coluna, acelerando queries com filtro nessa coluna
OPTIMIZE silver.pedidos ZORDER BY (cliente_id, data_pedido);Z-ORDER reordena fisicamente os dados para que rows com os mesmos valores de cliente_id e data_pedido fiquem no mesmo arquivo, permitindo ao Spark pular arquivos inteiros que não contêm o valor filtrado (data skipping).
Liquid Clustering (recomendado para novas tabelas)
Liquid Clustering substitui o particionamento estático + Z-ORDER. Define colunas de clustering sem precisar reescrever a tabela.
-- Criar tabela com Liquid Clustering
CREATE TABLE silver.pedidos (
pedido_id BIGINT,
cliente_id BIGINT,
data_pedido DATE,
valor_total DECIMAL(10,2)
)
CLUSTER BY (cliente_id, data_pedido);
-- Aplicar clustering incremental (não reescreve tudo)
OPTIMIZE silver.pedidos;Vantagens sobre particionamento + Z-ORDER:
- Sem necessidade de escolher cardinalidade de partição no momento da criação
- Rebalanceia incrementalmente, sem reescrever a tabela inteira
- Recomendado para tabelas com > 1 TB ou queries com filtros múltiplos
VACUUM
Remove arquivos Parquet que não fazem mais parte da tabela (referências deletadas, versões antigas).
-- Remover arquivos mais antigos que 7 dias (padrão)
VACUUM silver.pedidos;
-- Remover arquivos mais antigos que 24 horas (atenção: apaga histórico de time travel)
VACUUM silver.pedidos RETAIN 24 HOURS;Cuidado: após VACUUM, time travel para versões antigas desses dados não é mais possível.
Auto Optimize (configuração de tabela)
-- Habilitar compactação automática de arquivos pequenos após cada write
ALTER TABLE silver.pedidos
SET TBLPROPERTIES (
'delta.autoOptimize.optimizeWrite' = 'true',
'delta.autoOptimize.autoCompact' = 'true'
);Ou globalmente no cluster:
spark.conf.set("spark.databricks.delta.optimizeWrite.enabled", "true")
spark.conf.set("spark.databricks.delta.autoCompact.enabled", "true")Change Data Feed (CDF)
Permite consumir apenas as mudanças (inserts, updates, deletes) desde uma versão anterior, servindo de base para pipelines incrementais.
-- Habilitar na tabela
ALTER TABLE silver.pedidos SET TBLPROPERTIES ('delta.enableChangeDataFeed' = 'true');
-- Ler mudanças a partir da versão 5
SELECT * FROM table_changes('silver.pedidos', 5);df_changes = (
spark.read.format("delta")
.option("readChangeFeed", "true")
.option("startingVersion", 5)
.table("silver.pedidos")
)
# _change_type: insert | update_preimage | update_postimage | deleteVer também: databricks | databricks-unity-catalog | databricks-lakeflow-pipelines | formatos-de-arquivo-datalake | arquitetura-medalhao