Vistas del lago materializadas en Microsoft Fabric: cuando su medallón cabe en una declaración SELECT

Al mismo tiempo, construir una arquitectura medallón en Microsoft Fabric significó unir una pequeña orquesta de partes móviles: cuadernos para las transformaciones, canalizaciones para la orquestación, cronogramas para la actualización, código personalizado para las comprobaciones de calidad de los datos y Monitor Hub para controlar si algo realmente funcionaba. Cada capa funcionó, hasta que algo no funcionó, y entonces había que determinar qué capa se rompió, por qué y qué capas posteriores se vieron afectadas en el camino.

Si alguna vez ha intentado depurar una capa plateada que no se actualizó porque el cuaderno de bronce falló hace tres horas, sabe exactamente de qué estoy hablando.

Luego, en la FabCon Atlanta en marzo de 2026, las vistas materializadas del lago (MLV) estuvieron disponibles de forma generalizada. Y la historia que cuentan es simple: ¿qué pasaría si toda su cartera de medallones pudiera consistir en unas pocas declaraciones SELECT?

Permítanme explicarles todo: qué son, cómo funcionan, qué cambió entre la vista previa y GA, y dónde encajan (y dónde no) en su arquitectura.

Vista materializada del lago – ¿QUÉ?

Una vista de lago materializada es una vista persistente y actualizada automáticamente definida en Spark SQL o PySpark. Usted escribe una consulta SELECT que describe la transformación que desea y Fabric se encarga de la ejecución, el almacenamiento, la actualización, el seguimiento de dependencias y el cumplimiento de la calidad de los datos.

El resultado se almacena como una tabla Delta en su casa del lago. Por lo tanto, los consumidores intermedios, como Power BI Direct Lake, los cuadernos Spark y los puntos finales de SQL, pueden consultarla como cualquier otra tabla Delta. Sin manejo especial, sin sintaxis diferente.

Para decirlo en términos sencillos: un MLV no es más que una declaración SELECT que aprendió a materializarse, administrar sus propias dependencias, programar su propia actualización y verificar la calidad de sus propios datos.

Imagen del autor

Vale, eso es bueno. Pero, ¿a qué reemplaza eso realmente?

Esa es una pregunta justa. Antes de los MLV, crear un único flujo de bronce a plata a oro era más o menos así: se escribía un cuaderno para cada transformación, se configuraba una canalización de Data Factory para llamarlas en el orden correcto, se configuraban cronogramas, se creaba una lógica de validación personalizada y luego se conectaba Monitor Hub para detectar fallas. Cinco superficies diferentes, cinco cosas diferentes para depurar cuando algo se rompe.

Con los MLV, todo eso se colapsa en SQL declarativo. Describes lo que quieres. La tela se encarga del resto.

Las cuatro etapas de la vida de un MLV

Cada MLV pasa por cuatro etapas. Según la documentación de Microsoft, comprenderlos es la base para todo lo demás:

Crear: escribe el Spark SQL (o PySpark) que define la transformación. Fabric almacena la definición y materializa el resultado inicial como una tabla Delta. Actualizar: cuando los datos de origen cambian, Fabric elige la estrategia óptima: incremental (solo cambios en el proceso), completa (reconstrucción) u omisión (no se detectan cambios). Consulta: cualquier aplicación o herramienta lee el resultado materializado. No saben (y no necesitan saber) que es un MLV. Monitor: el historial de actualización, el estado de ejecución, las métricas de calidad de los datos y el linaje se rastrean y visualizan de forma nativa en Fabric.

Ahora profundicemos en cada pieza.

Crear: la sintaxis

Aquí está la sintaxis completa del pseudocódigo Spark SQL para crear un MLV, directamente de la referencia de Microsoft Learn:

CREAR [O REEMPLAZAR] VISTA DEL LAGO MATERIALIZADA [SI NO EXISTE] [workspace.lakehouse.schema].MLV_Identifier [(CONSTRAINT constraint_name CHECK (condición) [ON DISCATCH DROP | FAIL], …)] [PARTICIONADO POR (col1, col2, …)] [COMENTARIO “descripción”] [TBLPROPERTIES (“key1”=”val1”, …)] COMO declaración_select

Un ejemplo real: limpieza de datos de pedidos unidos desde productos y pedidos, con una restricción de calidad de datos y partición:

CREAR O REEMPLAZAR VISTA DEL LAGO MATERIALIZADO silver.cleaned_order_data (CONSTRAINT valid_quantity CHECK (cantidad > 0) ON MISMATCH DROP) PARTICIONADO POR (categoría) COMENTARIO “Datos de pedidos limpios unidos de productos y pedidos” COMO SELECCIONAR p.productID, p.productName, p.category, o.orderDate, o.quantity, o.totalAmount FROM bronce.products p INNER ÚNETE a bronce.pedidos o ON p.productID = o.productID

Dos cosas que vale la pena señalar de inmediato. En primer lugar, los nombres MLV no distinguen entre mayúsculas y minúsculas (MyView se convierte en myview). En segundo lugar, no se admiten nombres de esquema que estén completamente en mayúsculas (como MYSCHEMA), por lo tanto, utilice letras mixtas o minúsculas.

También necesita una casa del lago habilitada para esquemas y Fabric Runtime 1.3 o superior. Si su casa del lago no tiene esquemas activados, los MLV no están disponibles, ese es el primer requisito previo.

Actualizar: el cerebro de los MLV

Aquí es donde los MLV dejan de ser inteligentes y empiezan a serlo.

Cuando los datos de origen cambian, el motor de actualización óptimo de Fabric analiza cada MLV del linaje y plantea una serie de preguntas: ¿Cambió algo realmente? ¿Puedo procesar solo los cambios? ¿O necesito reconstruir desde cero?

Tres posibles resultados:

Omitir actualización: los datos de origen no han cambiado. No desperdicies cómputo. Siga adelante. Actualización incremental: procesa solo las filas nuevas o modificadas. Rápido, barato, ideal. Actualización completa: reconstruya todo. Ruta más lenta, utilizada cuando el incremental no es seguro o posible.

Imagen del autor

Pero, y esto es importante, la actualización incremental no es gratuita. Tiene requisitos previos:

La fuente de datos de cambios (CDF) delta debe estar habilitada en cada tabla de origen a la que hace referencia el MLV (delta.enableChangeDataFeed=true). La fuente debe ser una tabla Delta. Las fuentes que no son de Delta siempre obtienen una actualización completa. Los datos deben ser sólo para anexar. Si su fuente tiene actualizaciones o eliminaciones, Fabric recurre a una actualización completa. La consulta debe utilizar sólo construcciones SQL compatibles (más sobre esto en un momento).

Sin CDF habilitado, la actualización óptima solo puede elegir entre omitir y completar. Con CDF activado, se abre la ruta incremental completa. Habilitar CDF en sus tablas de origen no tiene ningún impacto medible en el almacenamiento o el rendimiento para cargas de trabajo de solo agregar, por lo que hay muy pocas razones para no activarlo:

ALTER TABLE bronce.pedidos SET TBLPROPERTIES (delta.enableChangeDataFeed = true); ALTER TABLE bronce.productos SET TBLPROPERTIES (delta.enableChangeDataFeed = true);

¿Puede haber algo mejor que esto? ¡En realidad, sí! Y aquí es donde realmente comienza la historia de GA.

¿Qué hay de nuevo en la fase de Disponibilidad General?

Los MLV se introdujeron en una vista previa en la compilación 2025. Entre entonces y GA en marzo de 2026, Microsoft cerró las brechas más importantes. Cinco cambios importantes hicieron que los MLV pasaran de ser "interesantes" a estar "listos para producción":

Compatibilidad con múltiples programaciones Cobertura de actualización incremental más amplia Creación de PySpark (vista previa) Actualizaciones in situ con Reemplazo Controles de calidad de datos más sólidos

Déjame tomarlos uno a la vez.

1. Soporte de múltiples horarios

En la versión preliminar, solo podía actualizar todos los MLV en una casa del lago en una única programación. ¿Necesita que las finanzas se actualicen cada hora, pero que los análisis se actualicen cada seis horas? Había que solucionarlo con cuadernos, lo que rompía la conciencia de dependencia, el informe de errores y la lógica de reintento. Las actualizaciones activadas por el portátil no muestran detalles del error MLV. Los fallos aparecen sólo en la salida de la celda y las vistas dependientes no tienen conocimiento de ellos. Los errores pueden persistir semana tras semana sin que nadie sepa que la tubería está rota.

Ahora puede definir programas con nombre dentro de una única casa del lago, cada uno de los cuales apunta a un subconjunto específico de vistas. Tubería financiera por hora. Análisis cada seis horas. Comercialización cada 15 minutos. Todo en la misma casa del lago, sin código personalizado.

Imagen del autor

Cuando se ejecuta una programación con nombre, Fabric aún actualiza todas las dependencias ascendentes en el orden correcto, ejecuta vistas independientes en paralelo y muestra los errores de manera centralizada. Si una ejecución ya está en progreso cuando se activa una programación, la nueva ejecución se omite y la siguiente ventana continúa como se esperaba, por lo que no tiene que preocuparse de que las ejecuciones superpuestas se pisoteen entre sí.

2. Actualización incremental más amplia

La actualización incremental solía volver al máximo con bastante frecuencia, porque la lista de construcciones SQL "admitidas" era estrecha. En GA, esa lista se amplió significativamente. Los MLV ahora se actualizan de forma incremental cuando la definición incluye:

Agregaciones como COUNT y SUM con GROUP BY Uniones externas izquierdas y semiuniones izquierdas Expresiones de tabla comunes (CTE)

Ese es un cambio significativo. La mayoría de los canales de medallón del mundo real en los que he trabajado utilizan exactamente estos patrones y ahora califican para el procesamiento incremental sin ser reescritos. Con una actualización óptima, un motor de decisión integrado examina cada actualización, evalúa el volumen de datos modificados frente al costo de un nuevo cálculo completo y elige automáticamente la ruta más rápida.

Te escucho, te escucho: Nikola, ¿qué sucede si mi consulta utiliza algo que el motor no puede manejar de forma incremental? No te preocupes, es mucho más fácil de lo que parece 🙂 El uso de construcciones no compatibles no te impide crear el MLV. Solo significa que Fabric utiliza una actualización completa en lugar de una incremental. La actualización óptima vuelve automáticamente al máximo cuando es necesario, por lo que normalmente no es necesario forzarla. Si desea forzar uno (por ejemplo, reprocesar datos después de una corrección), hay una frase para eso:

ACTUALIZAR VISTA AL LAGO MATERIALIZADO silver.cleaned_order_data COMPLETO;

3. Autoría de PySpark (vista previa)

¡Este es enorme! SQL es excelente hasta que su lógica de transformación involucre una biblioteca Python personalizada, una llamada de inferencia ML o una UDF que incluya reglas comerciales complejas. Entonces chocarías contra una pared ya que los MLV eran solo para SQL.

Con la creación de PySpark, ahora puede crear, actualizar y reemplazar MLV desde cuadernos Fabric utilizando PySpark y la conocida API DataFrameWriter. El módulo fmlv expone un patrón basado en decorador, documentado en la referencia oficial de PySpark MLV:

importar fmlv desde pyspark.sql importar funciones como F @fmlv.materialized_lake_view( nombre=”LH1.silver.customer_silver”, comentario=”MLV de plata de cliente limpio y enriquecido”, partición_cols=[”año”, “ciudad”], table_properties={”delta.enableChangeDataFeed”: “true”}, reemplazar=True) @fmlv.check(nombre=”non_null_sales”, condición=”las ventas NO ES NULA”, acción=”DROP”) def customer_silver(): df = spark.read.table(”bronze.customer_bronze”) clean_df = df.filter(F.col(”sales”).isNotNull()) enriched_df = clean_df.withColumn(”sales_in_usd”, F.col(”ventas”) * 1.0) devuelve enriched_df

Algunas trampas de PySpark que vale la pena conocer:

Los MLV de PySpark todavía están en versión preliminar al momento de escribir este artículo. Hoy en día, los MLV creados por PySpark siempre realizan una actualización completa. La actualización óptima para PySpark está en la hoja de ruta, pero aún no ha llegado. El decorador @fmlv no admite parámetros o variables dinámicas. Todos los parámetros deben estar codificados. No puede crear un MLV desde una vista temporal de PySpark (createOrReplaceTempView): el motor no puede ver vistas con ámbito de sesión. Utilice tablas Delta físicas u otros MLV como fuentes. No elimine el cuaderno donde está definido el MLV. La actualización programada falla sin ella.

Entonces, si su transformación se puede expresar claramente en SQL, SQL sigue siendo la mejor opción para el rendimiento. Los MLV de PySpark desbloquean los casos en los que SQL por sí solo no es suficiente.

4. Actualizaciones locales (Reemplazar)

La lógica empresarial cambia. Un filtro cambia. Una combinación gana una columna. Una agregación agrega una métrica. En la versión preliminar, actualizar una definición de MLV requería eliminarla y recrearla, lo que perdía el historial de actualización y obligaba a los consumidores intermedios a volver a conectarse.

Ahora, con la capacidad Reemplazar, actualiza la definición de un MLV en su lugar. Fabric valida la nueva lógica, la intercambia y preserva la identidad, los metadatos y el linaje de la vista. Las dependencias posteriores permanecen intactas. Funciona tanto para SQL (CREAR O REEMPLAZAR) como para PySpark (reemplazar = Verdadero).

Esta es una de esas características de GA "que pasan desapercibidas" que no aparece en los titulares pero que tiene una enorme importancia en el día a día. Si alguna vez ha tenido que coordinar la eliminación y recreación de una tabla muy consumida mientras se ejecuta la producción, conoce el dolor. Eso se va con esto.

5. Mayor calidad de los datos

Las limitaciones de calidad de los datos no son nada nuevo en los MLV, pero en GA obtuvieron una importante actualización. Ahora puedes:

Utilice lógica basada en expresiones que combine varias columnas. Aplique funciones aritméticas e integradas dentro de una sola regla. Invoque funciones definidas por el usuario con ámbito de sesión para una lógica de validación que reside en Python en lugar de SQL.

Combine eso con los informes de calidad de datos generados automáticamente y obtendrá algo parecido a una capa de observabilidad de datos incorporada. Puede detectar rápidamente qué reglas fallan con más frecuencia, qué vistas afectan y cómo cambian las tendencias con el tiempo, sin necesidad de crear un canal de monitoreo separado.

La vista del linaje – Dependencias gratis

Cuando un MLV hace referencia a otro (o a una tabla), Fabric infiere la relación automáticamente. Sin configuración manual, sin herramienta de orquestación externa. Las dependencias se descubren desde su SQL.

Ese gráfico de dependencia se convierte en un linaje visual en su casa del lago. Cada nodo representa una transformación. Las flechas muestran el orden de ejecución. Fabric se asegura de que cuando lleguen los datos de bronce, el MLV de bronce a plata se ejecute primero, luego el MLV de plata a oro se ejecute contra el plata recién actualizado.

Imagen del autor

Aquí es donde el enfoque declarativo realmente vale la pena. No estás escribiendo tuberías. No estás definiendo la orquestación. Estás escribiendo cómo debería verse cada capa y Fabric determina el orden. Ésta es la belleza de un enfoque declarativo 🙂

Algunos comportamientos útiles que debe conocer:

Las vistas independientes se ejecutan en paralelo Los errores aparecen centralmente en lugar de perderse en la salida de la celda del cuaderno La vista de linaje se actualiza automáticamente cada dos minutos cuando hay una ejecución en progreso Todos los accesos directos se tratan como entidades de origen en la vista de linaje Puede adjuntar un entorno Spark personalizado al linaje de vistas de lago materializadas para optimizar el rendimiento y el uso de recursos durante la actualización

Calidad de los datos – ¡Declarada!

Mencioné esto anteriormente, pero merece su propia sección porque es una de las cosas que hace que los MLV se sientan diferentes de una tubería construida a mano.

Cada MLV puede tener una o más restricciones de calidad de datos adjuntas:

CREAR O REEMPLAZAR LA VISTA DEL LAGO MATERIALIZADA silver.valid_orders ( RESTRICCIÓN cantidad_positiva VERIFICAR (cantidad > 0) EN LA CAÍDA DE DISCORRECTO, RESTRICCIÓN fecha_válida VERIFICAR (fecha_pedido >= '2020-01-01') EN EL FALLO DE COINCIDENCIA ) COMO SELECCIONAR * DE bronce.pedidos

Dos tipos de acciones:

DROP: se eliminan las filas infractoras, el recuento se registra en la vista de linaje y la canalización continúa. FAIL: la actualización se detiene en la primera infracción. Este también es el valor predeterminado si no especifica

Si hay varias restricciones presentes y ambos comportamientos están configurados, FAIL tiene prioridad.

Las infracciones aparecen en la vista de linaje y en los detalles de ejecución. Bien, pero ¿cómo se ve eso en la práctica? Bueno, en el informe de calidad de los datos verá recuentos por restricción, por vista, a lo largo del tiempo. Entonces, si una restricción que normalmente reduce el 0,1 % de las filas de repente cae un 15 %, verá el pico y sabrá exactamente qué regla falló y a qué vista pertenece. Esa es una señal de calidad que de otro modo tendrías que construir a mano.

Los documentos de Microsoft también señalan que las nuevas restricciones basadas en expresiones admiten funciones integradas de Spark/SQL como UPPER(), LOWER(), TRIM(), COALESCE(), INITCAP() y DATE_FORMAT(), por lo que sus condiciones CHECK pueden ser más ricas que simples comparaciones.

Cuando los MLV brillan y cuando no

Los MLV no son un martillo para cada clavo. La documentación de Microsoft es inusualmente directa sobre dónde encajan y dónde no.

Imagen del autor

Utilice MLV cuando tenga:

Agregaciones a las que se accede con frecuencia (totales diarios, métricas mensuales) donde los resultados calculados previamente superan la repetición de consultas costosas. Uniones complejas en múltiples tablas grandes que deben ser consistentes para todos los consumidores. Reglas de calidad de datos que desea aplicar de manera uniforme y declarativa. Conjuntos de datos de informes que combinan datos de múltiples fuentes y se benefician de la actualización automática. Patrón de diseño Medallion: de bronce a plata y oro definido como transformaciones SQL.

No utilice MLV cuando:

La consulta se ejecuta una vez o rara vez: la computación previa no ayudará Las transformaciones ya son simples y rápidas. Necesita lógica que no sea SQL, como inferencia de ML, llamadas API o procesamiento complejo de Python; las computadoras portátiles son aún mejores (aunque los MLV de PySpark están comenzando a cerrar esta brecha) Necesita una latencia inferior a un segundo para la transmisión: ese es territorio de inteligencia en tiempo real

Agregaré una nota personal aquí. Actualmente estoy inmerso en un compromiso con Microsoft Fabric donde la opción de diseño de capa plateada (Warehouse versus Lakehouse con MLV) está activamente sobre la mesa. Y a lo que sigo volviendo es a esto: los MLV no compiten con el Warehouse como algunas personas lo plantean. Están compitiendo con los espaguetis de cuadernos y tuberías que de otro modo se construirían dentro de Lakehouse. Si su equipo ya domina SQL y sus transformaciones se desarrollan de forma natural en declaraciones SELECT, el argumento a favor de los MLV como capa plateada en una arquitectura basada en Lakehouse es realmente sólido.

La letra pequeña: lo que debe saber antes de lanzarse

No te haría ningún favor si pintara los MLV como una solución milagrosa. Tienen limitaciones significativas, algunas de las cuales serán importantes para su arquitectura:

Sin linaje ni ejecución entre casas del lago: todas las fuentes, MLV y dependencias deben vivir en la misma casa del lago. Si está utilizando una tabla de Fabric Data Warehouse como fuente, primero debe crear un acceso directo a ella en su casa del lago. Sin declaraciones DML: no puede INSERTAR, ACTUALIZAR ni ELIMINAR en un MLV. Los datos son lo que produce SELECT. No hay consultas de viaje en el tiempo en la definición: no se permiten VERSIÓN A PARTIR y MARCA DE TIEMPO A PARTIR. No hay UDF en la definición de SQL, aunque la creación de PySpark llena este vacío con UDF con ámbito de sesión. No hay vistas temporales como fuentes: SELECT puede hacer referencia a tablas físicas y otros MLV, pero no a vistas temporales. Esto también se aplica a PySpark: las salidas de createOrReplaceTempView() no son visibles para el motor MLV. Las propiedades de Spark a nivel de sesión no se aplican durante la actualización programada; en su lugar, configúrelas en el nivel de la casa del lago o del espacio de trabajo. Las mayúsculas y minúsculas de los nombres de esquema son importantes: no se admiten nombres de esquemas completamente en mayúsculas. Utilice mayúsculas o minúsculas mixtas. Disponibilidad regional: al momento de escribir este artículo, los MLV no están disponibles en la región centro-sur de EE. UU.

Ninguno de estos es un obstáculo para la mayoría de los oleoductos. Pero vale la pena conocerlos antes de comprometer una arquitectura con MLV y descubrir la limitación a mitad de camino.

Concluyendo

Si ha estado creando patrones de diseño de medallones en Fabric utilizando cuadernos y canalizaciones, vale la pena examinar seriamente los MLV. Colapsan cinco superficies en una capa declarativa. La gestión de dependencias es automática. La calidad de los datos está integrada. El linaje es visible. Y a partir de la FabCon Atlanta, están listos para la producción.

La hoja de ruta de Microsoft es clara: se acerca la actualización óptima para los MLV creados por PySpark, más operadores SQL serán elegibles para la actualización incremental y está en camino una integración más profunda con otras cargas de trabajo de Fabric. Este es un hito, no la línea de meta, y tengo curiosidad por ver cómo evolucionan los MLV en los próximos trimestres, especialmente en torno a la actualización incremental de PySpark y cualquier historia entre lagos que Microsoft pueda contar.

Dos conclusiones a las que me aferraría:

La "T" en su ELT ahora es mucho más fácil de escribir, programar y confiar, si esa "T" es SQL. Los MLV no reemplazan todos los portátiles, todos los canales ni todos los almacenes. Pero para las transformaciones declarativas que necesitan linaje, actualización y calidad de datos incorporada, ahora son un valor predeterminado legítimo en Microsoft Fabric.

¡Gracias por leer!