Fundamentos de Datos
Los pilares conceptuales que todo Data Engineer debe dominar: desde los distintos tipos de bases de datos hasta los modelos de procesamiento, storage patterns y principios de governance.
Bases de Datos Relacionales (RDBMS)
Las bases de datos relacionales son el fundamento histórico del almacenamiento de datos estructurados. Organizan información en tablas con filas y columnas, donde las relaciones entre tablas se definen mediante llaves foráneas y se aseguran mediante constraints.
Principios ACID
Las bases de datos relacionales garantizan las propiedades ACID, fundamentales para sistemas transaccionales:
Atomicity
Una transacción es todo o nada. Si falla una parte, toda la transacción se revierte (ROLLBACK).
Consistency
La base de datos siempre pasa de un estado válido a otro válido. Las constraints nunca se violan.
Isolation
Las transacciones concurrentes se comportan como si fueran secuenciales. No hay interferencia entre ellas.
Durability
Una vez confirmada (COMMIT), la transacción persiste incluso ante fallos del sistema.
Bases de Datos Relacionales Populares
| Base de Datos | Tipo | Casos de Uso | Fortalezas |
|---|---|---|---|
| PostgreSQL | Open Source | Aplicaciones web, analytics | Extensible, JSON support, performance |
| MySQL / MariaDB | Open Source | Aplicaciones web (LAMP) | Simple, amplio soporte, rápido en reads |
| Oracle Database | Comercial | Enterprise, Banking | Features avanzados, alta disponibilidad |
| SQL Server (MSSQL) | Comercial | Enterprise Windows | Integración Microsoft, SSIS, SSRS |
| SQLite | Open Source | Embedded, desarrollo local | Zero config, serverless, portable |
| Amazon Aurora | Cloud Managed | Cloud apps | MySQL/PG compatible, auto-scaling |
| Cloud Spanner | Cloud Managed | Global distributed apps | ACID a escala global, 99.999% SLA |
SQL básico: Fundamentos
-- Crear tabla con constraints
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_id INTEGER NOT NULL REFERENCES customers(customer_id),
order_date TIMESTAMP DEFAULT NOW(),
total_amount DECIMAL(10,2) CHECK (total_amount >= 0),
status VARCHAR(20) DEFAULT 'pending'
CHECK (status IN ('pending','processing','shipped','delivered','cancelled'))
);
-- INSERT con valores
INSERT INTO orders (customer_id, total_amount)
VALUES (1, 150.00), (2, 89.99);
-- SELECT con JOIN básico
SELECT
o.order_id,
c.name AS customer_name,
o.total_amount,
o.status
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
WHERE o.status != 'cancelled'
ORDER BY o.order_date DESC
LIMIT 100;
-- TRANSACTION ejemplo
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT; -- o ROLLBACK si hay error
Bases de Datos NoSQL
Las bases de datos NoSQL ("Not Only SQL") surgieron para resolver limitaciones de las RDBMS en escenarios de alta escala, datos no estructurados y flexibilidad de esquema. No son "mejores" que las relacionales — son herramientas diferentes para problemas diferentes.
Document Stores — MongoDB, Firestore, CouchDB
Almacenan documentos en formato JSON/BSON. Ideal cuando los datos tienen estructura variable o jerárquica.
// MongoDB - Insertar documento
db.users.insertOne({
_id: ObjectId(),
name: "Ana García",
email: "ana@example.com",
preferences: {
theme: "dark",
language: "es",
notifications: ["email", "push"]
},
orders: [
{ order_id: "ORD-001", amount: 150.00, date: new Date() }
],
tags: ["premium", "verified"],
created_at: new Date()
});
// Query con filtros anidados
db.users.find({
"preferences.language": "es",
"orders.amount": { $gt: 100 }
}).limit(10);
Casos de uso: Catálogos de productos, perfiles de usuario, CMS, aplicaciones con esquemas variables.
Fortalezas: Esquema flexible, fácil de escalar horizontalmente, consultas en documentos anidados.
Key-Value Stores — Redis, DynamoDB, Memcached
La forma más simple de NoSQL. Cada dato se identifica por una clave única y su valor puede ser cualquier estructura.
# Redis - Operaciones básicas
# String
SET user:1:session "abc123" EX 3600 # TTL de 1 hora
# Hash (objeto)
HSET user:1 name "Ana" email "ana@example.com"
HGET user:1 name
# List (cola FIFO)
LPUSH notifications:1 "New order received"
RPOP notifications:1
# Sorted Set (leaderboard)
ZADD leaderboard 1500 "player:1"
ZADD leaderboard 2300 "player:2"
ZREVRANGE leaderboard 0 9 WITHSCORES # Top 10
# Pub/Sub
PUBLISH channel:orders "new_order:ORD-005"
Casos de uso: Caché, sesiones, leaderboards, colas de mensajes, rate limiting.
Fortalezas: Latencia sub-milisegundo, extremadamente simple, muy alta throughput.
Column-Family Stores — Cassandra, HBase, Bigtable
Organizan datos en familias de columnas. Optimizados para escrituras masivas y consultas por rango de tiempo.
-- Cassandra CQL (Cassandra Query Language)
-- Diseñado para escrituras/lecturas masivas
CREATE TABLE sensor_readings (
device_id UUID,
timestamp TIMESTAMP,
temperature DOUBLE,
humidity DOUBLE,
pressure DOUBLE,
PRIMARY KEY (device_id, timestamp)
-- Partition key: device_id
-- Clustering key: timestamp (orden cronológico)
) WITH CLUSTERING ORDER BY (timestamp DESC)
AND compaction = {'class': 'TimeWindowCompactionStrategy'};
-- Insert masivo (diseñado para esto)
INSERT INTO sensor_readings
(device_id, timestamp, temperature, humidity)
VALUES (uuid(), toTimestamp(now()), 22.5, 65.0);
-- Query eficiente (usa partition key)
SELECT * FROM sensor_readings
WHERE device_id = 550e8400-e29b-41d4-a716-446655440000
AND timestamp > '2026-01-01'
LIMIT 1000;
Casos de uso: IoT data, series de tiempo, logs a escala masiva, datos de sensores.
Fortalezas: Escalabilidad lineal, alta disponibilidad, writes de alta throughput, distribución geográfica.
Graph Databases — Neo4j, Amazon Neptune, TigerGraph
Modelan datos como nodos y relaciones (aristas). Excelentes para datos altamente relacionados donde los JOINs serían prohibitivos.
// Neo4j - Cypher Query Language
// Crear nodos y relaciones
CREATE (ana:Person {name: 'Ana', age: 28})
CREATE (carlos:Person {name: 'Carlos', age: 32})
CREATE (python:Skill {name: 'Python', level: 'Advanced'})
CREATE (spark:Skill {name: 'Apache Spark', level: 'Intermediate'})
CREATE (ana)-[:KNOWS]->(carlos)
CREATE (ana)-[:HAS_SKILL]->(python)
CREATE (ana)-[:HAS_SKILL]->(spark)
CREATE (carlos)-[:HAS_SKILL]->(spark)
// Consultar: amigos con skill en Spark
MATCH (p:Person)-[:KNOWS]-(friend)-[:HAS_SKILL]->(s:Skill)
WHERE p.name = 'Ana' AND s.name = 'Apache Spark'
RETURN friend.name, s.level
Casos de uso: Redes sociales, detección de fraude, sistemas de recomendación, conocimiento empresarial, grafos de conocimiento.
Fortalezas: Traversal de relaciones complejo en tiempo constante, consultas de grafos naturales.
Time Series Databases — InfluxDB, TimescaleDB, Prometheus
Optimizadas específicamente para datos secuenciales en el tiempo. Comprensión nativa del concepto de "timestamp".
-- TimescaleDB (extensión de PostgreSQL)
-- Crear hypertable (tabla optimizada para time series)
CREATE TABLE cpu_metrics (
time TIMESTAMPTZ NOT NULL,
host TEXT NOT NULL,
cpu_usage DOUBLE PRECISION,
memory_usage DOUBLE PRECISION
);
SELECT create_hypertable('cpu_metrics', 'time');
-- Insert data
INSERT INTO cpu_metrics VALUES
(NOW(), 'server-01', 45.2, 72.1),
(NOW(), 'server-02', 23.1, 55.3);
-- Time-series query con bucketing
SELECT
time_bucket('5 minutes', time) AS bucket,
host,
AVG(cpu_usage) as avg_cpu,
MAX(cpu_usage) as max_cpu
FROM cpu_metrics
WHERE time > NOW() - INTERVAL '1 hour'
GROUP BY bucket, host
ORDER BY bucket DESC;
Casos de uso: Monitoring de infraestructura, métricas de aplicaciones, datos financieros (OHLCV), IoT, observabilidad.
CAP Theorem: El Triángulo Imposible
(Todos los nodos ven los mismos datos)"] A["✅ Availability
(Siempre hay respuesta)"] P["🌐 Partition Tolerance
(Soporta fallos de red)"] C --- A A --- P P --- C CA["RDBMS tradicional
MySQL, PostgreSQL
(sin sharding)"] CP["MongoDB, HBase,
Zookeeper"] AP["Cassandra, DynamoDB,
CouchDB"] C -.-> CA A -.-> CA C -.-> CP P -.-> CP A -.-> AP P -.-> AP style C fill:#1e40af,stroke:#3b82f6,color:#fff style A fill:#065f46,stroke:#10b981,color:#fff style P fill:#7c3aed,stroke:#8b5cf6,color:#fff
El teorema CAP afirma que un sistema distribuido solo puede garantizar 2 de las 3 propiedades simultáneamente. La tolerancia a particiones (P) es inevitable en sistemas distribuidos, por lo que el trade-off real es entre Consistency y Availability.
ETL vs ELT: Paradigmas de Integración
ETL (Extract, Transform, Load) y ELT (Extract, Load, Transform) son los dos grandes paradigmas para mover datos entre sistemas. La elección impacta directamente el rendimiento, costo y flexibilidad de tus pipelines.
🔄 ETL — Extract, Transform, Load
- Transformaciones ocurren antes de cargar al destino
- Requiere un servidor/motor de transformación intermedio
- El destino recibe datos ya limpios y listos
- Ideal cuando el destino tiene recursos limitados
- Herramientas: Informatica, Talend, SSIS, Pentaho
- Común en DWH tradicionales on-premise
📥 ELT — Extract, Load, Transform
- Datos se cargan crudos primero, transformaciones después
- Usa el poder computacional del destino (DWH cloud)
- Más flexible: puedes re-transformar sin re-extraer
- Ideal para cloud DWH (BigQuery, Snowflake, Redshift)
- Herramientas: dbt, Fivetran + dbt, Airbyte + dbt
- Estándar moderno (2020+)
Spark / Python] B1 --> C1[Data Warehouse
Cleaned Data] end subgraph ELT A2[Source DB] --> B2[Raw Storage
S3 / GCS / ADLS] B2 --> C2[Cloud DWH
BigQuery / Snowflake] C2 --> D2[dbt Models
Transform in DWH] end style B1 fill:#1e40af,stroke:#3b82f6,color:#fff style D2 fill:#5b21b6,stroke:#8b5cf6,color:#fff
Pipeline ETL completo en Python
import pandas as pd
import sqlalchemy as sa
from datetime import datetime
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class ETLPipeline:
def __init__(self, source_conn: str, dest_conn: str):
self.source_engine = sa.create_engine(source_conn)
self.dest_engine = sa.create_engine(dest_conn)
# EXTRACT
def extract(self, query: str) -> pd.DataFrame:
logger.info(f"Extracting data...")
df = pd.read_sql(query, self.source_engine)
logger.info(f"Extracted {len(df):,} rows")
return df
# TRANSFORM
def transform(self, df: pd.DataFrame) -> pd.DataFrame:
logger.info("Transforming data...")
# Limpiar nulos
df = df.dropna(subset=['customer_id', 'amount'])
# Normalizar tipos
df['amount'] = df['amount'].astype(float)
df['order_date'] = pd.to_datetime(df['order_date'])
# Calcular métricas derivadas
df['year_month'] = df['order_date'].dt.to_period('M').astype(str)
df['is_large_order'] = df['amount'] > 500
# Eliminar duplicados
df = df.drop_duplicates(subset=['order_id'])
logger.info(f"After transform: {len(df):,} rows")
return df
# LOAD
def load(self, df: pd.DataFrame, table_name: str) -> None:
logger.info(f"Loading {len(df):,} rows into {table_name}...")
df.to_sql(
table_name,
self.dest_engine,
if_exists='append', # 'replace', 'append', 'fail'
index=False,
method='multi', # Batch insert
chunksize=1000
)
logger.info("Load complete ✓")
# ORCHESTRATE
def run(self) -> dict:
start = datetime.now()
query = """
SELECT order_id, customer_id, amount, order_date
FROM orders
WHERE updated_at > NOW() - INTERVAL '1 day'
"""
raw_df = self.extract(query)
clean_df = self.transform(raw_df)
self.load(clean_df, 'fact_orders')
elapsed = (datetime.now() - start).seconds
return {"rows_processed": len(clean_df), "elapsed_seconds": elapsed}
# Ejecución
pipeline = ETLPipeline(
source_conn="postgresql://user:pass@source-db:5432/prod",
dest_conn="postgresql://user:pass@dw:5432/warehouse"
)
result = pipeline.run()
print(f"Pipeline completed: {result}")
Data Warehouse, Data Lake y Lakehouse
Estos tres paradigmas de almacenamiento han dominado diferentes eras del Data Engineering. En 2026, el Lakehouse es el estándar emergente que intenta combinar lo mejor de ambos mundos.
Data Warehouse (DWH)
Un Data Warehouse es un repositorio centralizado de datos estructurados, limpios y optimizados para análisis. Los datos llegan transformados y listos para consulta.
- Estructura: Esquema definido (schema-on-write). Datos altamente estructurados.
- Formato: Tabular. Datos almacenados en formato columnar interno.
- Datos: Solo datos estructurados. No acepta video, audio, texto libre sin procesar.
- Costo: Más caro por GB (almacenamiento + cómputo acoplados en soluciones legacy).
- Ejemplos modernos: Snowflake, BigQuery, Redshift, Azure Synapse.
- Velocidad de query: Muy rápida. Optimizado para SQL analytics.
- Casos de uso: BI, reporting, dashboards, análisis histórico estructurado.
Bronze/Raw → Silver/Cleaned → Gold/Aggregated. Cada capa tiene un propósito y nivel de calidad definido.
Data Lake
Un Data Lake es un repositorio que almacena datos en su formato nativo (crudo) hasta que sean necesarios. El principio es: "Store everything, figure out schema later".
- Estructura: Schema-on-read. El esquema se aplica al leer, no al escribir.
- Formato: Todo: JSON, CSV, Parquet, Avro, imágenes, videos, logs, audio.
- Costo: Muy barato por GB (object storage: S3, GCS, ADLS).
- Escalabilidad: Prácticamente ilimitada. Exabytes posibles.
- Problema histórico: Fácil que se convierta en un "Data Swamp" (sin governance).
- Ejemplos: S3 + Hadoop, GCS + Dataproc, ADLS + Azure HDInsight.
- Casos de uso: ML training data, raw event storage, archivado, datos no estructurados.
Sin governance, catalogación y calidad de datos, un Data Lake se convierte rápidamente en un Data Swamp donde nadie sabe qué hay, dónde está o si los datos son confiables. Esto fue el gran fracaso de muchos proyectos de Big Data 2010-2018.
Lakehouse (El Estándar 2026)
El Lakehouse combina la flexibilidad y el bajo costo del Data Lake con las capacidades analíticas y ACID del Data Warehouse. Permite SQL directo sobre object storage.
- Tecnologías clave: Delta Lake (Databricks), Apache Iceberg, Apache Hudi
- ACID sobre object storage: Transacciones confiables sobre S3/GCS/ADLS
- Time Travel: Consultar versiones históricas de los datos
- Schema Evolution: Cambiar esquemas sin reescribir todos los datos
- Unified batch + streaming: El mismo sistema para ambos paradigmas
- Open formats: Parquet + metadata layer, sin vendor lock-in
- Casos de uso: El estándar para arquitecturas modernas que necesitan tanto ML como BI
# Delta Lake con PySpark
from pyspark.sql import SparkSession
from delta import configure_spark_with_delta_pip
spark = (configure_spark_with_delta_pip(
SparkSession.builder
.appName("lakehouse_demo")
.config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension")
).getOrCreate())
# Escribir como Delta Table
df.write.format("delta").mode("overwrite").save("gs://my-lake/silver/orders/")
# ACID MERGE (upsert)
from delta.tables import DeltaTable
delta_table = DeltaTable.forPath(spark, "gs://my-lake/silver/orders/")
delta_table.alias("target").merge(
updates_df.alias("source"),
"target.order_id = source.order_id"
).whenMatchedUpdateAll() \
.whenNotMatchedInsertAll() \
.execute()
# Time Travel - consultar versión anterior
df_yesterday = spark.read.format("delta") \
.option("versionAsOf", 5) \
.load("gs://my-lake/silver/orders/")
Comparativa Definitiva
| Característica | Data Warehouse | Data Lake | Lakehouse |
|---|---|---|---|
| Schema | Schema-on-write | Schema-on-read | Ambos (flexible) |
| Tipo de datos | Solo estructurados | Todo tipo | Todo tipo |
| Costo storage | 💰💰💰 Alto | 💰 Bajo | 💰 Bajo |
| Performance SQL | ⚡⚡⚡ Excelente | ⚡ Variable | ⚡⚡ Muy buena |
| ACID | ✅ Sí | ❌ No nativo | ✅ Sí (Delta/Iceberg) |
| ML workloads | ❌ Limitado | ✅ Nativo | ✅ Nativo |
| Ejemplos | Snowflake, BigQuery | S3+Hadoop, GCS | Databricks, Delta Lake |
| Mejor para | BI, reporting | ML, raw storage | Todo en uno |
Batch Processing vs Stream Processing
La elección entre procesamiento batch y streaming es una de las decisiones de arquitectura más importantes. Depende del caso de uso, la latencia requerida y el costo aceptable.
📦 Batch Processing
- Procesa datos en lotes grandes con periodicidad definida
- Alta latencia (minutos, horas, días)
- Alta throughput y eficiencia computacional
- Más fácil de implementar, debuggear y mantener
- Ideal para reportes nocturnos, ETL histórico
- Herramientas: Spark, Hadoop MapReduce, dbt
- Tolerante a fallos con retry fácil
⚡ Stream Processing
- Procesa eventos uno a uno o en micro-batches continuamente
- Baja latencia (milisegundos a segundos)
- Mayor complejidad: estado, exactly-once, watermarks
- Ideal para detección de fraude, recomendaciones en tiempo real
- Herramientas: Kafka Streams, Flink, Spark Structured Streaming
- Requiere gestión de estado (stateful processing)
- Mayor costo operacional
No uses streaming si batch es suficiente. Streaming añade complejidad significativa. La pregunta clave es: ¿cuánto tiempo puedes esperar para actuar sobre este dato? Si la respuesta es "horas" → batch. Si es "segundos" → streaming. Si es "milisegundos" → streaming avanzado + consideraciones especiales.
Casos de Uso por Paradigma
| Caso de Uso | Paradigma | Latencia Requerida | Herramienta |
|---|---|---|---|
| Reporte de ventas mensual | Batch | Días | dbt + Airflow |
| ETL nightly de OLTP a DWH | Batch | Horas | Spark + Airflow |
| Detección de fraude bancario | Stream | <100ms | Kafka + Flink |
| Recomendaciones en tiempo real | Stream | <200ms | Kafka Streams |
| Dashboard en tiempo real | Stream | Segundos | Spark Streaming |
| ML training data prep | Batch | Horas | Spark |
| Analytics de logs | Hybrid | Minutos | Kafka + Spark |
OLTP vs OLAP
La distinción entre sistemas OLTP y OLAP es fundamental para entender por qué necesitamos Data Warehouses separados de bases de datos operacionales.
| Aspecto | OLTP (Online Transaction Processing) | OLAP (Online Analytical Processing) |
|---|---|---|
| Propósito | Operaciones diarias del negocio | Análisis histórico y reporting |
| Operaciones típicas | INSERT, UPDATE, DELETE frecuentes | SELECT complejos con agregaciones |
| Volumen de datos | MB a GB (datos actuales) | GB a PB (histórico completo) |
| Usuarios | Miles de usuarios concurrentes | Pocos analistas/ingenieros |
| Queries | Simples, rápidas (<10ms) | Complejas, largas (segundos-minutos) |
| Schema | Normalizado (3NF) | Desnormalizado (Star/Snowflake) |
| Índices | Muchos índices en PKs y FKs | Pocos, orientados a columnas |
| Ejemplos | PostgreSQL, MySQL, Oracle | BigQuery, Snowflake, Redshift |
| Backup/Recovery | Crítico, RPO bajo | Menos crítico |
Una query analítica pesada (ej: "ventas totales por mes de los últimos 5 años") puede bloquear la base de datos operacional durante minutos, haciendo que las transacciones de usuarios fallen. Este es exactamente el problema que los Data Warehouses resuelven: aislar el workload analítico del transaccional.
Data Governance
El Data Governance es el conjunto de políticas, procesos, roles y tecnologías que garantizan que los datos sean usados de forma segura, ética, consistente y conforme a regulaciones. Es el "sistema legal" del ecosistema de datos.
- Data Ownership: Cada dataset tiene un dueño responsable de su calidad y definición.
- Data Stewardship: Roles dedicados a mantener la calidad y documentación de los datos.
- Data Catalog: Inventario centralizado de todos los datos disponibles con metadatos, linaje y documentación.
- Data Classification: Clasificar datos por sensibilidad: públicos, internos, confidenciales, PII.
- Access Control: Políticas de quién puede acceder a qué datos y con qué permisos.
- Data Retention: Políticas de cuánto tiempo se guardan los datos y cómo se eliminan.
- Compliance: Asegurar cumplimiento de GDPR, CCPA, HIPAA, SOC2, etc.
GDPR (Europa): Regula el tratamiento de datos personales de ciudadanos europeos. Aplica a cualquier empresa global que procese datos de europeos. Multas de hasta €20M o 4% del revenue global anual.
CCPA (California): Regulación de privacidad de datos de residentes en California. Similar a GDPR pero con diferencias en derechos de consumidores.
LGPD (Brasil): Lei Geral de Proteção de Dados. Inspirada en GDPR, aplica a datos de ciudadanos brasileños.
Impacto para DE: Como Data Engineer, debes implementar:
- Right to be forgotten: capacidad de eliminar todos los datos de un usuario
- Data portability: exportar datos de usuario en formato estándar
- Data minimization: recolectar solo datos necesarios
- Pseudonymization/Anonymization de datos PII en pipelines
Un Data Catalog es el "Google de los datos internos". Permite a cualquier persona en la organización descubrir, entender y acceder a los datos correctos.
Funcionalidades clave:
- Search & Discovery: Buscar datasets por nombre, tags, descripción
- Business Glossary: Definiciones estandarizadas de términos de negocio
- Data Lineage: Rastrear el origen y transformaciones de cada campo
- Metadata Management: Estadísticas, esquemas, dueños, SLAs
- Collaboration: Comentarios, ratings, Q&A sobre datasets
Herramientas populares en 2026: LinkedIn DataHub (open source), Apache Atlas, Google Dataplex, Collibra, Alation, Atlan.
Data Quality y Data Lineage
La calidad de los datos es la diferencia entre insights útiles y decisiones erróneas. "Garbage in, garbage out" es la ley fundamental del Data Engineering.
Las 6 Dimensiones de Data Quality
Completeness
¿Todos los campos requeridos tienen valor? ¿Existen todos los registros esperados?
Accuracy
¿Los datos representan la realidad correctamente? ¿Son precisos?
Consistency
¿Los mismos datos tienen el mismo valor en distintos sistemas?
Timeliness
¿Los datos están disponibles cuando se necesitan? ¿Son frescos?
Uniqueness
¿No hay duplicados? ¿Cada entidad tiene un identificador único?
Validity
¿Los datos siguen el formato y reglas de negocio definidas?
Data Lineage: Rastreando el Origen
El Data Lineage es la capacidad de rastrear el viaje de un dato desde su origen hasta su uso final. Es esencial para debugging, compliance y confianza en los datos.
orders table)] -->|ETL diario| B[S3 Raw Layer
orders/2026/01/01] B -->|Spark job| C[Silver Layer
orders_cleaned/] C -->|dbt model| D[Gold Layer
fact_orders] D -->|dbt model| E[mart_sales_monthly] E -->|BI connector| F[📊 Power BI
Sales Dashboard] F -->|Report| G[👔 CFO Report
Q1 Revenue] style A fill:#065f46,stroke:#10b981,color:#fff style D fill:#1e40af,stroke:#3b82f6,color:#fff style G fill:#7c3aed,stroke:#8b5cf6,color:#fff
Cuando el CFO pregunta "¿por qué el revenue del Q1 en el dashboard es diferente al reporte contable?", el Data Lineage te permite rastrear exactamente qué transformación o fuente causó la discrepancia. Sin lineage, el debugging puede tomar días. Con lineage, minutos.