DP-700 · MÓDULO 7 🥇

Organizar un lakehouse de Fabric con arquitectura medallion

El gran patrón arquitectónico del data engineering moderno: Bronze, Silver y Gold, estructura del lakehouse, Materialized Lake Views, star schema, serving, seguridad por capa y CI/CD. 🌸

Intermedio Avanzado
🎯

1. Objetivos y encaje en el DP-700

¿Qué te enseña este módulo?

Este es el módulo del gran patrón arquitectónico del data engineering moderno: la arquitectura medallion. Los objetivos oficiales:

  1. Describir el patrón de arquitectura medallion y por qué se usa en la analítica de lakehouse.
  2. Identificar las decisiones clave al planificar un medallion en Fabric.
  3. Describir cómo se sirve la capa gold para queries y reporting.
  4. Describir las best practices para asegurar y gobernar las capas del medallion.

Peso en el examen DP-700

Aunque no es un dominio en sí, aparece transversalmente en TODOS los dominios:

DominioCómo aparece la medallion
Implement and manage (30-35%)Diseño de workspaces, permisos por capa, Git + deployment pipelines
Ingest and transform (30-35%)Ingesta en bronze, limpieza en silver, modelado en gold, herramientas por capa
Monitor and optimize (30-35%)Optimización específica por capa, Materialized Lake Views, patrones incrementales
🎯 Qué es CRÍTICO dominar:
  • Las 3 capas y qué va en cada una (la base absoluta)
  • Cuándo usar un solo lakehouse, varios lakehouses o varios workspaces
  • Materialized Lake Views (feature nueva muy potente)
  • Star schema en gold (fact + dimensions)
  • OneLake data access roles para la seguridad granular
  • Patrones de serving: SQL endpoint vs semantic model
  • Warehouse como capa gold alternativa
🌸 Buenas noticias: si vienes de la DP-600, ya conoces el concepto de star schema y el modelado dimensional para Power BI. Aquí lo aplicamos al mundo del data engineering.
🥇

2. ¿Qué es la medallion architecture?

Definición oficial

La medallion architecture (también llamada medallion lakehouse architecture) es un patrón de diseño para organizar los datos en un lakehouse. Es el enfoque recomendado por Microsoft para Fabric.

Consiste en tres capas jerárquicas, cada una con una calidad progresivamente mayor:

  • 🥉 Bronze — datos raw, sin procesar.
  • 🥈 Silver — datos validados, limpios y enriquecidos.
  • 🥇 Gold — datos curados, listos para el consumo de negocio.

La idea central

Los sistemas origen (ERPs, CRMs, logs, IoT) organizan los datos para la eficiencia operacional, no para la analítica. Sus schemas son normalizados, complejos y a veces caóticos.

La medallion remodela progresivamente ese caos, capa a capa, preservando el original como fuente de verdad y preparando cada capa para su audiencia:

Sistemas origen
    ↓
🥉 Bronze  (landing zone raw → Data Engineers)
    ↓
🥈 Silver  (limpio e integrado → Analistas + Data Scientists)
    ↓
🥇 Gold    (listo para negocio → Usuarios de negocio)
🌸 Analogía kawaii: piénsalo como cocinar. 🥉 Bronze = los ingredientes tal como vienen del mercado (sin lavar, sin pelar). 🥈 Silver = los ingredientes preparados (lavados, cortados, mezclados según la receta). 🥇 Gold = los platos listos para servir en la mesa 🍽️.
Cada capa tiene su propósito. No puedes servir los ingredientes crudos, ni tirar la comida y volver al mercado si algo sale mal. Se hace paso a paso.

ACID y calidad progresiva

La medallion es coherente con los principios ACID de las tablas Delta: los datos empiezan en su forma raw, se preservan las copias originales como fuente de verdad, los pipelines de validación y transformación los preparan para la analítica y cada capa mejora la calidad respecto a la anterior.

🎨

3. Las 3 capas en detalle: Bronze, Silver, Gold

🥉 Bronze layer

Propósito: landing zone para TODOS los datos, sean estructurados, semiestructurados o no estructurados.

Características:

  • ✅ Datos almacenados en formato original, sin modificar.
  • Fuente de verdad: si algo va mal downstream, puedes reprocesar desde bronze sin volver al origen.
  • Trazabilidad: preservas la historia exacta de qué llegó y cuándo.

Audiencia: data engineers principalmente.

Ejemplos de contenido: CSVs raw de exports diarios, JSON de APIs, logs de aplicaciones, ficheros Parquet ya generados por los sistemas origen, imágenes y PDFs.

🥈 Silver layer

Propósito: validar y refinar los datos para tener un dataset consistente e integrado.

Actividades típicas: estandarizar formatos (fechas, monedas, encoding), eliminar nulls e inconsistencias, deduplicar registros, hacer merge/join de datos de varios orígenes de bronze, aplicar reglas de calidad de datos y correcciones y enriquecimiento básico.

Resultado: un dataset consistente, integrado y fiable que analistas y data scientists pueden usar directamente.

Audiencia: analistas y data scientists.

Ejemplos de contenido: la tabla customers deduplicada con emails normalizados, la tabla sales con los nulls eliminados y los tipos corregidos, o la tabla products con el merge de catálogos de varios orígenes.

🥇 Gold layer

Propósito: modelar los datos para el consumo de negocio.

Modelo típico: star schema con fact tables (eventos y mediciones: sales, transactions, events) y dimension tables (contexto descriptivo: customers, products, dates, locations), agregado a la granularidad necesaria para el reporting.

Audiencia: usuarios de negocio, analistas, data scientists y directivos.

Ejemplos de contenido: fact_sales con las métricas de ventas por día/producto/región, dim_customer, dim_product, dim_date, vistas agregadas para dashboards ("sales_by_region_monthly") y tablas planas para feature engineering de ML.

Tabla resumen

Bronze 🥉Silver 🥈Gold 🥇
PropósitoLanding rawLimpieza + integraciónModelado de negocio
ModificaciónNingunaSí (validación)Sí (agregación + star schema)
AudienciaData EngineersAnalistas + Data ScientistsUsuarios de negocio
FormatosCualquieraDelta (típicamente)Delta (star schema)
Uso principalReprocesamientoAnálisis directoReporting y dashboards
RetenciónLargaMediaCorta (agregados)
💡

4. Por qué separar en capas

Beneficios

A) Cada equipo tiene lo que necesita: los data engineers no interfieren con lo que consumen los analistas, los analistas no ven la complejidad del raw y los usuarios de negocio tienen métricas listas para consumir.

B) Resiliencia: si algo falla, no lo pierdes todo: un pipeline de silver roto → sigues teniendo bronze intacto. Puedes reprocesar desde bronze sin volver a extraer del sistema origen (que puede ser caro, lento o incluso inaccesible).

C) Trazabilidad y auditoría: puedes rastrear cualquier dato de gold hasta su origen en bronze. Compliance: guardas el raw para las auditorías.

D) Iteración independiente: puedes cambiar la lógica de silver sin tocar bronze, y rediseñar gold sin tocar silver. Acoplamiento débil entre capas.

E) Reutilización: varios silvers pueden derivar del mismo bronze, y varios golds del mismo silver (uno para BI, otro para ML).

Análisis de tradeoffs

No es gratis: más storage (guardas los datos varias veces), más cómputo (varios pipelines) y más complejidad operativa. Pero los beneficios de resiliencia, auditoría y separación de responsabilidades compensan de sobra en cualquier proyecto serio.

🔧

5. Adaptar la arquitectura (más capas, menos capas)

No es una regla estricta

El patrón de 3 capas es un punto de partida, no un dogma. Puedes adaptarlo:

Añadir una landing zone antes de bronze: para datos que llegan en un formato específico (ej: XML raw, EDIFACT). Se llama a veces capa "raw" o "landing".

Añadir capas específicas de dominio después de gold: Gold-Finance, Gold-Marketing, Gold-Operations para equipos concretos, cada uno modelado para las preguntas de ese equipo.

Simplificar a 2 capas: para casos sencillos, raw + curated (sin capa intermedia). Válido cuando la complejidad de la transformación es baja.

Nombres flexibles

Los nombres bronze/silver/gold son una convención. Puedes usar raw / cleansed / curated, staging / integration / semantic o L0 / L1 / L2. Lo importante es que cada capa tenga un propósito y una audiencia claros.

Ejemplos de arquitecturas variantes

Caso 1: añadir capa landing

Landing → Bronze → Silver → Gold

Landing es donde caen los ficheros originales; bronze es el mismo dato pero ya cargado como tabla Delta.

Caso 2: varios golds

                        → Gold-BI (star schema)
Bronze → Silver → Gold →
                        → Gold-ML (tabla plana y ancha)

Caso 3: preparado para Fabric IQ

Bronze → Silver → Gold → Ontology (Fabric IQ)

Con Fabric IQ, después de gold puedes tener una capa semántica "ontológica" para los AI agents.

🎯

6. Decisiones de diseño en Fabric

Hay 3 decisiones críticas cuando planeas una medallion en Fabric:

  1. Cómo estructurar el lakehouse (uno solo vs varios).
  2. Qué herramientas usar para mover datos entre capas (dataflows, notebooks, pipelines).
  3. Cómo servir la capa gold a los consumidores.

Cada decisión tiene sus tradeoffs. Vamos una por una.

🏢

7. Estructura del lakehouse: single vs multiple

Las 3 opciones oficiales

Opción A: un solo lakehouse con schemas — todo (bronze, silver, gold) en un único lakehouse, con cada capa como un schema (bronze, silver, gold).

Opción B: lakehouses separados — un lakehouse por capa: lh_bronze, lh_silver, lh_gold. Pueden estar en el mismo workspace o en distintos.

Opción C: workspaces separados — un workspace por capa: ws_bronze, ws_silver, ws_gold. Máximo aislamiento.

Comparativa oficial

OpciónMejor para
Un lakehouse con schemasMás simple de gestionar; equipos pequeños o proyectos en fase temprana
Lakehouses separadosSeparación más clara; permisos distintos por capa
Workspaces separadosAislamiento más fuerte; obligatorio en escenarios de compliance o regulatorios

Cuándo elegir cada uno

Un lakehouse con schemas ✅ en proyectos pequeños o medianos, con un solo equipo trabajando en todas las capas, sin requisitos estrictos de aislamiento y cuando quieres simplicidad operativa.

Lakehouses separados (mismo workspace): equipos distintos con permisos ligeramente diferentes, o cuando quieres control granular de permisos por capa sin tanto overhead.

Lakehouses separados en workspaces separados ⭐: compliance/regulatorio (SOX, GDPR, HIPAA), cada capa gestionada por un equipo distinto, cada capa necesita su propia capacidad (para aislar el cómputo), deployment pipelines por capa y empresas grandes.

🎯 Consideración de capacidad: con workspaces separados, cada uno puede tener su propia capacity: el workspace bronze con capacidad dedicada a la ingesta pesada, el de silver para la transformación y el de gold optimizado para el consumo (Direct Lake). Esto aísla el cómputo entre capas y evita que una ingesta pesada tumbe los reports de gold.
📁

8. Uso de schemas para organizar layers

Schemas: por defecto en Fabric

Cuando creas un lakehouse en Fabric, los schemas están habilitados por defecto. Ya lo vimos en el Módulo 2, pero ahora lo aplicamos a la medallion.

Nombrar los schemas por capa

Crea schemas llamados bronze, silver y gold en tu lakehouse:

CREATE SCHEMA bronze
CREATE SCHEMA silver
CREATE SCHEMA gold

Ahora las tablas se organizan por capa:

Lakehouse
├── bronze
│   ├── customers_raw
│   ├── orders_raw
│   └── products_raw
├── silver
│   ├── customers
│   ├── orders
│   └── products
└── gold
    ├── fact_sales
    ├── dim_customer
    ├── dim_product
    └── dim_date

Beneficios de usar schemas

  • 🎯 Descubribilidad: es fácil encontrar las tablas por capa.
  • 🔐 Permisos por schema: distintos roles para bronze/silver/gold.
  • 🧩 Sin el overhead de tener varios lakehouses.
  • 📊 Queries más limpias: SELECT * FROM gold.fact_sales.

Queries cross-schema

-- Query cross-schema en el mismo lakehouse
SELECT
    f.order_id,
    d.customer_name,
    f.total_amount
FROM gold.fact_sales f
JOIN gold.dim_customer d
    ON f.customer_key = d.customer_key

O comparando con silver:

SELECT COUNT(*) AS bronze_count FROM bronze.orders_raw
UNION ALL
SELECT COUNT(*) AS silver_count FROM silver.orders

Útil para las comprobaciones de calidad de datos entre capas.

🥉

9. Bronze layer a fondo

Filosofía

Bronze es tu landing zone de datos raw. Los datos llegan exactamente como los envió el origen: sin cambios, sin limpieza.

Es intencional: si una transformación se rompe downstream, puedes reprocesar desde bronze sin volver al sistema origen (que puede ser caro, lento o incluso ya no tener los datos).

Cómo cargar datos en bronze

Depende de dónde viva el origen:

Origen en cloud storage (OneLake, ADLS Gen2, S3, GCS) ✅ — usar un shortcut de OneLake para referenciarlo in-place. No hay copia ni pipeline, y bronze se mantiene sincronizado con el origen automáticamente. 🎯 Es el enfoque recomendado cuando aplica.

Origen en otros sitios (BBDD, APIs, on-prem) — usar Pipelines con la actividad Copy Data, Dataflows Gen2 para lo low-code, o notebooks para transformaciones complejas o formatos raros.

Estructura típica de una tabla bronze

Suele replicar la estructura del origen:

bronze.orders_raw
├── order_id (INT)
├── customer_id (INT)
├── order_date (STRING — ¡sin castear!)
├── quantity (STRING — ¡sin castear!)
├── total (STRING — ¡sin castear!)
├── raw_json (STRING — payload original opcional)
├── ingestion_timestamp (TIMESTAMP)   ← metadata añadida
├── source_file (STRING)              ← metadata añadida
└── _ingest_batch_id (STRING)         ← metadata añadida

Cositas comunes: mantener los tipos originales (a veces strings) para preservar la exactitud, añadir columnas de metadata (timestamp de ingesta, fichero origen, batch id) y no borrar duplicados (de eso se encarga silver).

Retención en bronze

Bronze suele tener retención larga (años, incluso indefinida) por requisitos de compliance, reprocesamiento futuro con lógica nueva y auditoría. Conviene considerar el particionado por fecha para ser eficiente:

df.write.format("delta") \
    .partitionBy("ingestion_year", "ingestion_month") \
    .saveAsTable("bronze.orders_raw")

Automatización

La capa bronze se automatiza mucho: schedule diario u horario para los pipelines de ingesta, triggers por evento para la llegada de ficheros e idempotencia (reingerir el mismo fichero no debe duplicar).

🥈

10. Silver layer a fondo

Filosofía

Silver es donde los datos se limpian y se integran. Las transformaciones se centran en la calidad y la consistencia: estandarizar formatos (fechas, divisas, encodings), eliminar nulls, deduplicar registros, hacer join de datos de varios orígenes de bronze, castear a los tipos correctos y aplicar reglas de negocio básicas.

Resultado: un dataset fiable e integrado que analistas y data scientists pueden usar directamente. También alimenta a la capa gold.

Las 3 opciones de Fabric para silver

A) Dataflows Gen2 (low-code) — perfectos para transformaciones directas: filtrar, renombrar, cambiar tipos, sin escribir código. Ideal para analistas que vienen de Power BI.

B) Notebooks (código completo) — control total con PySpark o Spark SQL. Ideal para datasets grandes, lógica compleja, cálculos custom, llamadas a APIs y joins complejos.

C) Materialized Lake Views 🎯 (SQL declarativo) — defines la transformación en SQL y Fabric crea y mantiene la tabla por ti, con actualizaciones incrementales automáticas.

Cuándo usar cada uno

SituaciónHerramienta
Analista con background de Power BIDataflow Gen2
Transformación con lógica Python complejaNotebook
Merge de varias fuentes de big dataNotebook
Feature engineering para MLNotebook
Transformación expresable en SQLMaterialized Lake View

Ejemplo de notebook de silver

from pyspark.sql.functions import col, upper, trim, to_date, when

# Leer de bronze
bronze_df = spark.table("bronze.orders_raw")

# Aplicar la limpieza
silver_df = (bronze_df
    # Castear tipos
    .withColumn("order_date", to_date(col("order_date"), "yyyy-MM-dd"))
    .withColumn("quantity", col("quantity").cast("int"))
    .withColumn("total", col("total").cast("decimal(10,2)"))
    # Estandarizar strings
    .withColumn("region", upper(trim(col("region"))))
    # Eliminar nulls críticos
    .filter(col("order_id").isNotNull())
    .filter(col("customer_id").isNotNull())
    # Regla de negocio: solo cantidades positivas
    .filter(col("quantity") > 0)
    # Deduplicar por order_id (quedarse con el último)
    .dropDuplicates(["order_id"])
)

# Escribir a silver
silver_df.write \
    .format("delta") \
    .mode("overwrite") \
    .saveAsTable("silver.orders")

print(f"Silver orders: {silver_df.count()} rows")
🌟

11. Materialized Lake Views (feature clave)

Esta es una feature nueva y súper importante. Muy examinable en el DP-700 actualizado 💎

¿Qué es una Materialized Lake View?

Una materialized lake view es una tabla que se define en SQL y que Fabric mantiene actualizada automáticamente a partir de las tablas origen. Es como una vista SQL, pero con los resultados persistidos como tabla Delta.

Sintaxis

CREATE MATERIALIZED LAKE VIEW silver.sales
AS
SELECT
    order_id,
    customer_id,
    UPPER(TRIM(region))        AS region,
    CAST(order_date AS DATE)   AS order_date,
    unit_price * quantity      AS total_amount
FROM bronze.sales
WHERE order_id IS NOT NULL

Esto crea una tabla real llamada silver.sales. Puedes hacer SELECT * FROM silver.sales como con cualquier tabla.

🎯 La magia: el refresh incremental automático. Diferencia crítica frente a una view SQL normal:
  • 🆚 View SQL normal: reejecuta la query cada vez que alguien la consulta. Coste alto en queries.
  • Materialized Lake View: los resultados se guardan como tabla real. Cuando llegan datos nuevos a bronze, Fabric actualiza solo las filas que cambiaron.

¿Cómo lo consigue Fabric?

Aprovecha el transaction log de Delta:

  1. Todas las tablas de Fabric son Delta.
  2. Delta registra cada cambio en un log JSON.
  3. Fabric monitoriza el log del origen (bronze).
  4. Cuando llegan filas nuevas → Fabric procesa solo esas filas y actualiza la materialized view.

No hay que programar ni disparar nada. La tabla se mantiene actualizada automáticamente. 🌸

Ventajas

  • 🚀 Rendimiento: las lecturas son como las de una tabla normal (rápidas).
  • 🤖 Automatización: sin schedules ni triggers.
  • 💰 Eficiencia de coste: solo procesa lo que cambió (incremental).
  • 📝 Declarativa: defines el "qué" en SQL, no el "cómo".
⚠️ Limitación clave: la transformación tiene que ser expresable como SQL. Si necesitas lógica en Python, llamadas a APIs, predicciones de ML inline o UDFs custom complejas → usa un notebook, no una materialized view.

Casos de uso ideales

  • Silver: limpieza en SQL puro (UPPER, TRIM, CAST, WHERE, joins simples).
  • Gold: agregaciones simples (SUM, COUNT, GROUP BY).
  • Poblar facts/dims: si la lógica es SQL, la materialized view queda más limpia que un notebook.

Cuándo NO usar materialized views

  • ❌ La lógica requiere Python o Scala.
  • ❌ Necesitas control fino del incremental (schedule custom, batching específico).
  • ❌ Necesitas SCD Type 2 con lógica de historial.
  • ❌ Queries que dependen de fuentes externas (APIs, BBDD).
🥇

12. Gold layer a fondo

Filosofía

Gold es donde los datos se moldean para el consumo de negocio. El modelo típico es un star schema, pero no es la única opción. La forma del gold depende de quién lo consume:

  • BI / dashboards → star schema clásico.
  • Feature engineering para ML → tabla plana y ancha.
  • Reports financieros → agregados precalculados.
  • Dashboards ejecutivos → agregados de más alto nivel.

Varios golds desde el mismo silver

Un patrón muy común:

                              → gold.bi_sales_star
silver.sales, customers  →   → gold.ml_features_flat
                              → gold.finance_pnl_aggregated

El mismo silver por debajo, distintos golds para distintas audiencias, cada uno modelado como necesite ese equipo.

Herramientas para construir gold

Las mismas que para silver: Dataflows Gen2 (low-code), notebooks (código), Materialized Lake Views (SQL declarativo) y pipelines para orquestar.

Ejemplo: fact table en gold

CREATE MATERIALIZED LAKE VIEW gold.fact_sales
AS
SELECT
    s.order_id           AS sales_order_id,
    dc.customer_key      AS customer_key,
    dp.product_key       AS product_key,
    dd.date_key          AS order_date_key,
    dr.region_key        AS region_key,
    s.quantity           AS quantity,
    s.unit_price         AS unit_price,
    s.quantity * s.unit_price AS total_amount
FROM silver.sales s
JOIN gold.dim_customer dc ON s.customer_id = dc.customer_id
JOIN gold.dim_product dp ON s.product_id = dp.product_id
JOIN gold.dim_date dd ON s.order_date = dd.date
JOIN gold.dim_region dr ON s.region = dr.region

La fact table conectada a las dimensions por surrogate keys.

13. Star schema: fact y dimension tables

¿Qué es un star schema?

Star schema = técnica de modelado dimensional que consiste en una fact table en el centro y dimension tables rodeándola (formando una estrella ⭐). Es el estándar de facto para los data warehouses relacionales y los modelos semánticos de Power BI.

Dimension tables

Describen las entidades relevantes para tu organización: products, customers, locations, dates, employees, etc. Representan "las cosas" que modelas.

Características: baja cardinalidad (respecto al fact), descriptivas (muchas columnas de texto), actualizaciones poco frecuentes y cada fila es una entidad única.

Fact tables

Almacenan las mediciones asociadas a observaciones o eventos: sales orders, stock balances, exchange rates, temperature readings.

Características: alta cardinalidad (muchas filas) y contienen las dimension keys más los valores granulares que se pueden agregar. Ejemplo: fact_sales con customer_key, product_key, date_key, quantity y total_amount.

🎯 Por qué usar star schema

  • Rendimiento: menos joins que un modelo normalizado → queries más rápidas.
  • 📚 Comprensible: fácil de entender para los analistas.
  • 🔧 Mantenible: añadir columnas a una dimension es sencillo.
  • 🎨 Adaptable: puede evolucionar con el negocio.
  • Requerido para Power BI: los semantic models enterprise funcionan mejor con star.

Ejemplo visual

                    dim_customer
                          |
                          |
     dim_date --- fact_sales --- dim_product
                          |
                          |
                    dim_region

fact_sales es la estrella central y las dimensions son las puntas. Suele haber varios facts en el mismo modelo (varias estrellas) compartiendo dimensions (conformed dimensions).

ETL / ELT del star schema

Periódicamente (típicamente a diario), un proceso ETL actualiza las dimensions (filas nuevas, cambios), añade filas nuevas al fact y puede reprocesar datos si hay correcciones. En Fabric esto se orquesta con pipelines que ejecutan notebooks o materialized views.

📐

14. Dimensiones especiales (SCD, junk, degenerate, role-playing)

En el modelado dimensional avanzado hay varios patrones que aparecen en el examen:

Slowly Changing Dimensions (SCD)

Ya vimos las SCD en el Módulo 4. Recordatorio rápido:

SCD Type 1: sobrescribir el historial. Un cliente cambia de región → sobrescribes region en su fila. Simple, pero pierdes la historia.

SCD Type 2: mantener el historial con versionado. Un cliente cambia de región → creas una fila nueva con Valid_From, Valid_To e Is_Current. Preservas la historia completa y cada versión tiene un surrogate key único.

Ejemplo de SCD Type 2:

CustomerKeyCustomerIDNameRegionValid_FromValid_ToIs_Current
1001C-123AcmeCA2023-01-152026-02-20No
1002C-123AcmeNY2026-02-20NULLYes

Role-playing dimensions

Cuando una misma dimension se usa varias veces en una fact table con distintos roles. Ejemplo: el fact Flight tiene Departure Airport y Arrival Airport. Ambos apuntan a la misma tabla dim_airport pero con roles distintos.

fact_flight
├── departure_airport_key → dim_airport (rol: Departure)
├── arrival_airport_key   → dim_airport (rol: Arrival)

En Power BI se implementan con varias relaciones activas/inactivas o con dimensions "virtualizadas" vía USERELATIONSHIP.

Junk dimensions

Una junk dimension consiste en consolidar varias dimensiones pequeñas en una sola. Útil cuando tienes muchas dimensions con pocos atributos (a veces solo 1) y baja cardinalidad (pocos valores).

Ejemplo: en vez de tener dim_order_status, dim_delivery_status y dim_payment_status, los unificas en dim_sales_status con el producto cartesiano de todas las combinaciones.

Beneficios: menos dimensions, menos keys en la fact table, fact table más pequeña y menos ruido en el panel de datos de Power BI.

Degenerate dimensions

Una degenerate dimension ocurre cuando la dimension está al mismo grano que el fact, es decir, cada fila del fact tiene un valor único.

Ejemplo clásico: sales_order_number. Cada venta tiene un número de pedido único, así que no tiene sentido crear una dim_order_number con solo 1 fila por pedido: se deja en la fact table directamente.

Opcionalmente se puede exponer como una view que hace SELECT DISTINCT sales_order_number FROM fact_sales para las queries que lo necesiten como dimension.

🎯

15. Serving del gold: SQL endpoint + semantic model

Una vez tienes tu capa gold, hay que servirla a los consumidores. Dos opciones principales en Fabric:

Opción A: SQL analytics endpoint

Para: analistas y data scientists con conocimiento de SQL que quieren acceso directo.

Características: interfaz T-SQL sobre las tablas Delta de gold, read-only, puedes crear views y funciones que exponen queries curadas, aplica la seguridad SQL (RLS, CLS, OLS) y no requiere mover datos.

SQL endpoint del Lakehouse
├── bronze (schema visible pero con acceso restringido)
├── silver (lo mismo)
└── gold  ← los analistas consultan aquí
    ├── fact_sales
    ├── dim_customer
    └── ...

Queries típicas:

SELECT
    d.date_key,
    dc.customer_name,
    SUM(f.total_amount) AS total_sales
FROM gold.fact_sales f
JOIN gold.dim_customer dc ON f.customer_key = dc.customer_key
JOIN gold.dim_date d ON f.order_date_key = d.date_key
WHERE d.year = 2026
GROUP BY d.date_key, dc.customer_name
ORDER BY total_sales DESC

Opción B: semantic model de Power BI

Para: usuarios de Power BI, usuarios de negocio y dashboards.

Cómo crearlo:

  1. Desde el lakehouse → New semantic model.
  2. Seleccionar las tablas de la capa gold.
  3. Definir relationships, measures, jerarquías y nombres de negocio.
  4. Los reports de Power BI conectan al semantic model, no directamente a las tablas.

Beneficios: capa de negocio con nombres amigables y measures predefinidas, gobernanza centralizada (measures y lógica definidas una vez), reutilización (varios reports usan el mismo modelo) y modo Direct Lake.

Direct Lake mode

Los semantic models se conectan a la capa gold usando Direct Lake: leen directamente los ficheros Delta de OneLake, NO importan una copia a Power BI, y los reports siempre muestran datos actuales sin un paso de refresh separado.

Direct Lake da lo mejor de dos mundos: ⚡ el rendimiento de Import (in-memory), 🔄 datos siempre frescos (como DirectQuery) y 💾 sin duplicación de storage. Requiere Fabric capacity o Power BI Premium.

Comparativa SQL endpoint vs semantic model

SQL endpointSemantic model
AudienciaUsuarios SQL, data scientistsUsuarios de Power BI y de negocio
InterfazT-SQLDAX, reports de Power BI
DatosDirecto desde DeltaDirect Lake (o import)
Lógica de negocioViews y funcionesMeasures y columnas calculadas
GobernanzaSeguridad SQLEndorsement, sensitivity labels
RLS/CLS/OLSSí (a nivel del SQL endpoint)Sí (en el modelo)

Muchas organizaciones ofrecen ambos para distintas audiencias.

🏛️

16. Data Warehouse como gold layer alternativo

Cuándo usar Warehouse en vez de Lakehouse

Aunque el patrón medallion se define típicamente sobre lakehouses, para gold puedes usar un Fabric Data Warehouse cuando tu equipo trabaja principalmente en SQL, necesitas un modelado relacional más fuerte, requieres features específicas del Warehouse (T-SQL completo, ACID, queries transaccionales) o estás implementando BI empresarial tradicional.

Arquitectura mixta típica

Bronze (Lakehouse) → Silver (Lakehouse) → Gold (Warehouse)

Bronze y silver aprovechan la flexibilidad del lakehouse (Spark, cualquier formato) y gold usa la potencia relacional del Warehouse (T-SQL puro, índices, estadísticas).

Cómo cargar del Silver Lakehouse al Gold Warehouse

Opción A: usar CREATE TABLE AS SELECT cross-database:

-- En el Warehouse
CREATE TABLE gold.fact_sales AS
SELECT * FROM [lakehouse_silver].[dbo].silver.sales

Opción B: un notebook que lee del Silver Lakehouse y escribe en el Warehouse.

Opción C: un pipeline con la actividad Copy Data.

El serving cambia según el gold

  • Gold en Lakehouse → SQL endpoint + semantic model en Direct Lake.
  • Gold en Warehouse → T-SQL nativo + semantic model (Import o Direct Lake).

En el Warehouse el T-SQL es completo (INSERT, UPDATE, DELETE, MERGE, transacciones). En el SQL endpoint del Lakehouse es read-only.

🔐

17. Seguridad y gobierno por capa

La medallion crea una frontera natural de control de acceso. Distintos equipos necesitan distintas capas: los data engineers → bronze + silver; los analytics engineers → silver + gold; y los analistas y usuarios de negocio → solo gold. Aplicar esas fronteras requiere un enfoque deliberado.

Dos niveles de control de acceso

A) Workspace e item permissions: los workspace roles (Admin, Member, Contributor, Viewer) aplican a todo el workspace; los item permissions son más específicos y permiten compartir un lakehouse concreto sin dar acceso al workspace completo.

B) OneLake data access roles: control granular dentro de un solo lakehouse, acotado a tablas o carpetas concretas. Ideal para restringir por capa dentro del mismo lakehouse.

Estrategia según la arquitectura

Con un solo lakehouse + schemas: usa OneLake data access roles para dar acceso por schema — role_gold_readers con acceso solo a gold.*, role_silver_engineers con acceso a silver.* y gold.* (lectura), y role_bronze_engineers con acceso a todo.

Con varios lakehouses: usa item permissions por lakehouse — lh_bronze solo para data engineers, lh_silver para data engineers + analistas y lh_gold para todos.

Con varios workspaces: usa workspace roles distintos por capa. Aislamiento máximo y cada capa gestionada de forma independiente.

Tabla comparativa

EnfoqueCuándo usarlo
OneLake data access rolesEquipos que comparten workspace y necesitan distinto acceso por tabla/capa
Workspaces separados por capaAislamiento fuerte, fronteras de compliance o capacidad separada
🎯

18. OneLake data access roles (granular)

¿Qué son?

Los OneLake data access roles son roles personalizados dentro de un lakehouse que permiten definir acceso granular a tablas o carpetas concretas, sin necesidad de crear workspaces separados.

DefaultReader role

Cada lakehouse tiene un role integrado llamado DefaultReader que concede acceso a todos los datos del lakehouse para todos los usuarios con ReadAll. Puedes modificarlo o borrarlo para restringir el acceso por defecto.

Configurar la seguridad de OneLake

  1. Abrir el lakehouse.
  2. Seleccionar Manage OneLake security.
  3. Crear un role.
  4. Definir su scope (tablas o carpetas concretas).
  5. Asignar miembros (usuarios o grupos).

Ejemplo práctico

Escenario: un lakehouse con schemas bronze/silver/gold, donde quieres que los data engineers tengan acceso a bronze + silver + gold y los analistas solo a gold.

Rol 1: role_gold_only — scope: gold.* (todas las tablas del schema gold), miembros: el security group Analysts. Puedes borrar el DefaultReader para forzar que solo aplique este rol.

Rol 2: role_full_access — scope: bronze.*, silver.*, gold.*, miembros: el security group Data Engineers.

Ahora un analista NO puede ver las tablas de bronze o silver aunque tenga el rol Contributor del workspace.

🎯 Detalle importante: los OneLake data access roles trabajan con el modelo de permisos ReadAll (acceso a ficheros vía la API de OneLake y Spark). Complementan a los workspace roles, pero no los reemplazan del todo. Lo profundizamos en la Fase 4.
🔀

19. Git y deployment pipelines para medallion

Una arquitectura medallion implica muchas piezas de código: pipelines, notebooks, definiciones de schema. Todas necesitan mantenerse sincronizadas. Sin control de versiones, un mal deployment puede corromper datos a mitad de capa sin una recuperación fácil.

Git integration

La Git integration de Fabric conecta tu workspace a un repositorio Git: notebooks, pipelines y definiciones del lakehouse versionados juntos. Si un cambio rompe la capa silver, puedes revertir al commit anterior. Los equipos pueden trabajar en branches y hacer merge vía pull requests (el mismo workflow que el código de aplicación).

Deployment pipelines

Los deployment pipelines lo extienden: promocionan tu workspace medallion de dev → test → prod en una secuencia controlada, y permiten comparar entornos y detectar diferencias antes de que lleguen a producción.

Arquitectura CI/CD típica de una medallion

Repositorio Git (Azure DevOps o GitHub)
    ↓
Workspace de desarrollo (medallion completo)
    ↓ (deployment pipeline)
Workspace de test
    ↓ (deployment pipeline)
Workspace de producción

Cada workspace tiene sus propias fuentes de datos (configuración específica): dev con datos de muestra o sintéticos, test con un subconjunto de producción y prod con los datos reales.

📌 Best practices de CI/CD para medallion:
  1. Un solo repositorio Git para toda la medallion.
  2. Branches por developer o feature.
  3. Pull requests con code review.
  4. Tests automatizados en los pipelines (comprobaciones de calidad de datos).
  5. Deployment pipelines con puertas de validación.
  6. Configuración específica por entorno (parámetros, variables, connection strings).
  7. Plan de rollback claro.
Vemos el CI/CD en profundidad en la Fase 4. Aquí solo lo introducimos como parte del patrón medallion.
🎨

20. Patrones comunes de orquestación

Patrón 1: todo con notebooks + pipeline maestro

Pipeline "medallion_daily":
  ├── Notebook: bronze_ingest.ipynb
  ├── Notebook: silver_transform.ipynb (depende del anterior)
  ├── Notebook: gold_star_schema.ipynb (depende del anterior)
  └── Actividad de refresh del SQL Endpoint

Cuándo: casi todo con Spark, control total, casos complejos.

Patrón 2: mezcla de dataflows y notebooks

Pipeline "medallion_daily":
  ├── Copy Data: origen → bronze (SQL DB)
  ├── Dataflow Gen2: bronze → silver (limpieza simple)
  ├── Notebook: silver → gold (agregaciones complejas)
  └── Refresh del semantic model

Cuándo: equipos mixtos (Power BI + Spark), aprovechando lo mejor de cada herramienta.

Patrón 3: todo con materialized views (nuevo)

Bronze (shortcut a S3)
  ↓ (sync automático)
Silver (Materialized Lake View sobre Bronze)
  ↓ (incremental automático)
Gold (Materialized Lake View sobre Silver)
  ↓ (incremental automático)
Semantic Model (Direct Lake sobre Gold)

Cuándo: si todas las transformaciones son expresables en SQL, este patrón minimiza el overhead operativo. Fabric mantiene todo actualizado automáticamente, sin schedules ni triggers. 🌸

Patrón 4: medallion orientada a eventos

Llega un fichero a la carpeta origen de OneLake
  ↓ (trigger por evento)
El pipeline se dispara automáticamente
  ↓
Notebook: procesar y cargar a bronze
  ↓
Notebook: silver (delta desde bronze)
  ↓
Materialized views: gold (automático)

Cuándo: requisitos near-real-time, para minimizar la latencia entre la llegada de los datos y su disponibilidad en gold.

Consideraciones de orquestación

  • El orden importa: siempre bronze → silver → gold.
  • Gestión de fallos: si falla silver, ¿reintentar? ¿saltar y avisar?
  • Idempotencia: reingerir el mismo bronze debe producir el mismo silver.
  • Watermarks: para las cargas incrementales, saber qué se procesó ya.
  • Puertas de calidad de datos: validar antes de pasar a la siguiente capa.
⚠️

21. Trampas típicas y confusiones frecuentes

  • Trampa 1: "Los nombres bronze/silver/gold son obligatorios" ❌ Son una convención. Puedes usar raw/cleansed/curated, L0/L1/L2, etc. Lo importante es el propósito claro de cada capa.
  • Trampa 2: "Una medallion siempre tiene 3 capas" ❌ Es un punto de partida. Puedes tener 2, 4 o incluso más capas según las necesidades.
  • Trampa 3: "Bronze tiene que estar obligatoriamente en Fabric" ❌ Bronze puede ser un shortcut a un ADLS/S3/GCS existente. No hace falta copiar. Recomendación oficial: usa un shortcut cuando el origen ya está en cloud storage.
  • Trampa 4: "Silver siempre es Delta"Sí, en Fabric silver debe ser Delta para tener las capabilities (SQL endpoint, ACID, Power BI). Pero conceptualmente la medallion no lo exige.
  • Trampa 5: "Gold siempre es star schema" ❌ Es lo más común pero no obligatorio. Puedes tener tablas planas y anchas para ML, preagregados para dashboards ejecutivos, etc.
  • Trampa 6: "Necesito 3 workspaces separados para hacer medallion" ❌ Es una opción para el máximo aislamiento, pero puedes hacer medallion en un solo lakehouse con schemas.
  • Trampa 7: "Las Materialized Lake Views son solo para gold" ❌ Se pueden usar también en silver (o en cualquier capa donde la transformación sea expresable en SQL).
  • Trampa 8: "Las Materialized Lake Views funcionan con Python"Solo SQL. Si necesitas Python, usa un notebook.
  • Trampa 9: "La capa bronze se puede borrar después de un tiempo" ⚠️ Depende del compliance. Suele tener retención larga (años) porque es tu fuente de verdad, por compliance/auditoría y para el reprocesamiento futuro.
  • Trampa 10: "La capa gold siempre va en un Lakehouse" ❌ Puede ir en un Warehouse también, especialmente para equipos SQL-first o BI empresarial tradicional.
  • Trampa 11: "Direct Lake requiere refresh como Import" ❌ Direct Lake NO requiere refresh: lee directamente de Delta y los datos siempre están actualizados.
  • Trampa 12: "El default semantic model es lo mismo que un semantic model custom" ❌ Desde septiembre de 2025, los default semantic models ya no se crean automáticamente. Tienes que crear uno custom explícitamente.
  • Trampa 13: "Los OneLake data access roles reemplazan a los workspace roles" ❌ Los complementan. Ambos operan a distinto nivel.
  • Trampa 14: "El DefaultReader role no se puede tocar"Sí se puede modificar o borrar para restringir el acceso por defecto.
  • Trampa 15: "La medallion es solo para Fabric" ❌ Es un patrón genérico (viene de Databricks). Fabric es una implementación. Es aplicable a cualquier plataforma de lakehouse.
🆚

22. Comparativas clave (chuleta)

Bronze vs Silver vs Gold

Bronze 🥉Silver 🥈Gold 🥇
PropósitoLanding rawLimpieza + integraciónModelado de negocio
AudienciaData EngineersAnalistas + Data ScientistsUsuarios de negocio
ModificaciónNingunaSí + agregaciones
RetenciónLargaMediaCorta
FormatoOriginalDeltaDelta (star schema)
Herramientas típicasShortcut, PipelineDataflow, Notebook, MLVNotebook, MLV

Un lakehouse vs varios lakehouses vs varios workspaces

OpciónAislamientoComplejidadMejor para
Un lakehouse + schemasBajoBajaEquipos pequeños, fase temprana
Varios lakehousesMedioMediaPermisos por capa
Varios workspacesAltoAltaCompliance, capacidad aislada

Herramientas para transformar en silver/gold

HerramientaMejor para
Dataflow Gen2Low-code, analistas, transformaciones simples
NotebookCódigo Spark/Python, lógica compleja, ML
Materialized Lake ViewSQL declarativo, auto-refresh incremental
Pipeline (Copy Data)Movimiento sin transformar

Serving del gold

MétodoPara
SQL analytics endpointAnalistas SQL-first, data scientists
Semantic model (Direct Lake)Usuarios de Power BI y de negocio
Semantic model (Import)Casos legacy o críticos en rendimiento
API REST/GraphQLAplicaciones externas

Seguridad por capa

EnfoqueGranularidadCuándo
Workspace rolesWorkspace enteroSimplicidad
Item permissionsItem concretoCompartir sin dar acceso al workspace
OneLake data access rolesTabla/carpetaGranular por schema dentro del lakehouse
Varios workspacesUn workspace por capaCompliance, capacidad aislada

Materialized Lake View vs SQL View vs Delta Table

SQL ViewMaterialized Lake ViewDelta Table
Almacena datos✅ (como tabla real)
Reejecuta la query en cada lectura
Auto-refresh incrementalManual
LenguajeSQLSQLCualquiera
Requiere scheduleManual
📚

23. Fuentes oficiales consultadas

🎉 ¡Fase 1 completada!

Módulos cubiertos en la Fase 1: Lakehouse y Delta (foundation) 🥇

  1. Introducción a la analítica end-to-end con Microsoft Fabric
  2. Lakehouses en Microsoft Fabric
  3. Apache Spark en Microsoft Fabric
  4. Tablas Delta Lake en Microsoft Fabric
  5. Ingestar datos con Dataflows Gen2
  6. Orquestar procesos y movimiento de datos
  7. Organizar un lakehouse con arquitectura medallion (este módulo)

Con estos 7 módulos tienes los fundamentos completos del data engineering en Fabric. Ya estás preparada para meterte de lleno en las siguientes fases: Real-Time Intelligence, Warehouses, CI/CD, gobernanza y monitorización. 🌸✨

🚀 ¡Módulo 7 completado! Cierras la Fase 1 con el gran patrón arquitectónico. Sigue con el Módulo 8: Real-Time Intelligence y arranca la Fase 2. 🌸