Decisiones a la hora de afrontar un proyecto

Datos · Microsoft Fabric · Decisiones de diseño

Una plataforma de datos se juzga por el informe que sale al final. Lo que determina si funciona son unas cuantas decisiones tomadas meses antes, que solo se notan cuando faltan.

Tercera entrega sobre el montaje de una plataforma analítica completa. Esta no habla del caso ni de los datos: habla de las decisiones técnicas, una a una, con el motivo por el que se tomaron y lo que costaba la alternativa.

Hay una conversación que se repite cuando alguien hereda una plataforma de datos: ¿y esto por qué está hecho así? Casi siempre la respuesta es «no sé, venía así». Y casi siempre, dos meses después, alguien lo cambia «porque sobraba», y cuatro meses más tarde aparece el problema que esa cosa estaba evitando.

Este post es la respuesta a esa pregunta, escrita antes de que la haga nadie. Son las decisiones de ingeniería de una plataforma analítica montada de punta a punta, cada una con su porqué. No entro en el negocio concreto ni en las cifras: lo que me interesa aquí es la forma del razonamiento, que se repite igual en cualquier proyecto.

Todas tienen la misma forma

Antes de la lista, conviene fijar el molde, porque todas las decisiones que vienen se dejan escribir igual.

Primero hay un principio: lo que se hace. Después un porqué concreto, que no puede ser «es la buena práctica» sino un problema real que aparece si no lo haces. Después la alternativa descartada, porque una decisión sin alternativa no es una decisión, es una costumbre. Y por último, la parte que casi nunca se escribe: una regla verificable, una comprobación que se puede lanzar y que da un número.

PRINCIPIO POR QUÉ ALTERNATIVA REGLA Qué se hace Qué pasa si no Qué se descartó Qué se comprueba Una frase, sinmatices Un problema real,no «buena práctica» Sin alternativa nohay decisión Y devuelve unnúmero Si el cuarto paso no existe, el primero es una opinión. Y una opinión no sobrevive al primer desarrollador que tenga prisa.
El cuarto paso es el que falta casi siempre. Un principio que no se puede comprobar se erosiona solo: nadie lo incumple a propósito, pero cada excepción razonable se queda, y al año el principio ya no describe el sistema.

La capa donde entra el dato

El primer almacén no transforma nada, y eso es el punto

Lo que llega del sistema de origen se guarda tal cual: mismos nombres de columna, mismos tipos, misma divisa, misma basura. Organizado por sistema, por entidad y por fecha de carga, y sin tocar una coma.

La tentación de limpiar al vuelo es enorme, porque el dato llega sucio y tú ya sabes cómo arreglarlo. La razón para no hacerlo cabe en una frase: la última capa tiene que poder reconstruirse entera desde la primera, sin volver a pedirle nada a los sistemas de origen. Si limpias al entrar, lo que guardas ya es una interpretación, y el día que la interpretación resulte estar mal no tienes a dónde volver.

Regla verificableNinguna columna de la capa cruda cambia de nombre, de tipo o de unidad respecto al fichero de origen.

Repetir una carga no duplica nada

Las entidades que son catálogos se sobrescriben enteras. Las que son movimientos reemplazan exclusivamente la porción del día que se está cargando. En los dos casos, lanzar la misma carga dos veces deja el mismo resultado que lanzarla una.

Esto se llama idempotencia y suena a palabro, pero el motivo es muy concreto: a las tres de la mañana algo falla. Si repetir es seguro, el procedimiento de incidencia es «vuelve a lanzarlo». Si no lo es, el procedimiento es una negociación sobre qué borrar primero, hecha por alguien medio dormido, y ahí es donde se pierden datos de verdad.

Lo que no cumple una regla se aparta, no se tira

Cuando una fila incumple una regla de negocio acordada, no se descarta: se mueve a una tabla de cuarentena con el motivo escrito al lado, y la carga sigue.

La diferencia con tirarla es más grande de lo que parece. Lo que se tira desaparece y nadie lo echa de menos. Lo que está apartado es una cifra que se puede enseñar, con el nombre del sistema que la mandó al lado. Y una cifra enseñada en una reunión consigue en diez minutos lo que tres correos no consiguieron en un mes.

En la misma línea va el tratamiento de los datos personales: se pseudonimizan al entrar en la capa intermedia, y la tabla que permite deshacerlo vive aparte, con acceso restringido y auditado. No por ceremonia legal, sino porque el principio operativo es no almacenar datos personales que no hagan falta, y el 95 % de los informes no necesita saber cómo se llama nadie.

Las decisiones del modelo

Aquí es donde se concentra casi todo. El modelo es lo que ve la herramienta de informes, y cada decisión de esta sección se paga o se cobra todos los días.

Estrella, no copo de nieve

Cada tabla descriptiva se entrega aplanada: una sola tabla, con todos sus atributos dentro. Ninguna tabla descriptiva se relaciona con otra tabla descriptiva.

Una jerarquía geográfica normalizada produciría cuatro tablas encadenadas y tres saltos de relación para resolver un filtro. Aplanada, es una tabla y un salto. Hay tres beneficios y conviene separarlos, porque el que suele citarse es el menos importante:

  • Usabilidad. La jerarquía de navegación se define dentro de una sola tabla. Con el modelo normalizado, el usuario ve cuatro tablas en el panel de campos y tiene que saber en cuál buscar. Este es el beneficio grande.
  • Rendimiento. Un salto en vez de tres. Con tablas pequeñas la diferencia en tiempo absoluto es despreciable, pero el patrón se replica en todas y elimina los planes de consulta con cadenas de relaciones.
  • Compresión. Desnormalizar parece caro y no lo es: el motor codifica cada valor distinto una sola vez en su diccionario. Repetir un nombre de país en mil filas cuesta mil referencias a una entrada, no mil cadenas de texto.

Regla verificableNúmero de relaciones cuyas dos puntas son tablas descriptivas: cero, con la única excepción documentada de la tabla de seguridad.

Claves propias, enteras, que no son las del origen

Cada tabla descriptiva genera su propio identificador interno. El identificador del sistema de origen se conserva como atributo, pero nunca se usa como extremo de una relación.

Da trabajo y alguien siempre pregunta para qué. Cuatro motivos, y el primero es el que no admite discusión:

  • Historificación. Si una entidad guarda versiones a lo largo del tiempo, el identificador de origen es el mismo en todas ellas. No puede ser la clave de la relación, porque no distingue versiones. Solo la clave propia lo hace.
  • Orígenes heterogéneos. Cuando una parte del parque corre una versión anterior del sistema, con otro esquema y otros identificadores, la clave propia absorbe esa diferencia abajo y el modelo no se entera.
  • Rendimiento. Un entero de baja cardinalidad se une y se comprime mucho mejor que una cadena de texto. En una tabla de hechos de millones de filas, la diferencia es material.
  • Miembros especiales. Los dos de la decisión siguiente solo son posibles con una clave entera propia.

Dos miembros especiales, no uno

Cada tabla descriptiva lleva dos filas que no vienen de ningún sitio: una significa «no aplica» y la otra «desconocido».

Parece una distinción cosmética y es justo lo contrario. Que una venta no tenga comercial asignado porque es venta directa —no debe tenerlo— no es lo mismo que una venta cuyo comercial no sabemos cuál es. La primera es diseño de negocio. La segunda es un fallo del origen, y va a un cuadro de calidad del dato. Si las colapsas en una sola fila, el fallo queda escondido entre los casos normales y nadie lo ve nunca.

Ninguna clave puede quedarse en blanco

Toda clave apunta a algún sitio, aunque sea a uno de esos dos miembros especiales. Ninguna admite nulo y ninguna queda huérfana.

Esta tiene el porqué más visual de todas. Una clave nula o rota genera en la herramienta de informes una fila en blanco: el total del hecho la suma, pero cualquier filtro por atributos de la tabla descriptiva la excluye. El resultado es que la suma de las partes no da el total, delante de alguien que lleva veinte años cuadrando cuentas.

SIN MIEMBRO ESPECIAL CON MIEMBRO ESPECIAL Norte420 Centro330 Sur190 Suma visible940 Total del informe 1.000 Norte420 Centro330 Sur190 Desconocido60 Suma = total1.000 Los 60 de la izquierda existen: están en el total y no están en ninguna fila. A la derecha siguen siendo un problema, pero es un problema con nombre y con responsable.
El miembro especial no arregla el dato. Lo hace visible, que es lo único que se puede pedir a un modelo. Un hueco atribuido a «Desconocido» acaba en una conversación con quien envía los datos; un hueco invisible acaba en una reunión perdida discutiendo si el informe funciona.

Una sola tabla de fechas, no cuatro

Un mismo hecho tiene varias fechas con significado distinto: la de creación, la de ejecución, la de cancelación, la de la foto. Todas apuntan a la misma tabla de calendario. Una de las relaciones está activa y el resto existen pero están desactivadas, y se encienden desde dentro de la medida que las necesita.

La alternativa es tener una copia del calendario por cada eje. Se descartó por tres razones que se acumulan:

  • Un selector de fecha en la página debería filtrar todos los visuales. Con copias, cada visual obedece a un selector distinto y el usuario ve septiembre en un sitio y otro septiembre en el de al lado.
  • La inteligencia de tiempo —comparar con el año anterior, acumulados— se define una vez sobre una tabla. Con copias hay que definirla tantas veces como copias.
  • El mantenimiento se multiplica: cualquier columna nueva del calendario hay que añadirla en todas.

Y lo que más me gusta de esta decisión es que tiene escrito cuándo deja de valer: si alguien pide ver dos ejes temporales a la vez en el mismo visual —una matriz con fecha de creación en filas y fecha de ejecución en columnas— entonces sí hace falta una segunda tabla de fechas. Nadie lo ha pedido. El día que se pida, la decisión se revisa, y está escrito que se revise.

UNA TABLA, CUATRO CAMINOS CUATRO COPIAS Calendario El hecho 1 activa · 3 inactivas que enciende la medida Calendario 1 Calendario 2 Calendario 3 Calendario 4 su propio selector su propio selector su propio selector su propio selector Cuatro selectores es cuatro septiembres distintos.
La línea de puntos no es una relación rota. Es una relación que existe, está declarada y permanece apagada hasta que una medida concreta la enciende, con el nombre de la medida diciendo qué eje está usando.

El grano más fino que el origen pueda dar

Los hechos se cargan al detalle, no agregados. El resumen mensual se calcula; el detalle, si no lo guardaste, no se recupera.

La excepción es cuando el agregado es el hecho: unos costes que el sistema contable cierra por mes no tienen detalle diario que guardar, y fingir que lo tienen repartiendo entre los días es inventarse un dato. Ahí el grano del hecho es el mes, y se dice.

La seguridad, que es un modelo aparte

Quién ve qué es dato, no código

Los ámbitos de acceso —global, por región, por país, por centro— se resuelven al construir una tabla puente que los expande a filas: una fila por persona y por centro que puede ver. Un responsable regional acaba con tantas filas como centros tiene su región.

Parece redundante y es lo que hace que todo lo demás sea simple. Como el ámbito ya está expandido, los cuatro perfiles de seguridad comparten una única expresión de filtro, idéntica para todos. Y dar de alta a alguien es añadirlo a un grupo del directorio corporativo, no tocar el modelo ni volver a publicarlo. La gestión de accesos sale del equipo de datos y vuelve a donde tiene que estar.

Una sola relación bidireccional en todo el modelo

El filtrado cruzado en los dos sentidos está desactivado en todas partes menos en una: la de esa tabla puente, que lo necesita para que el filtro de seguridad llegue hasta donde tiene que llegar.

La bidireccionalidad es cómoda y por eso es peligrosa: resuelve el problema de hoy y mete caminos de filtro ambiguos que se manifiestan meses después como una cifra que cambia según por dónde la mires. La regla aquí no es «no usarla nunca», es usarla donde es imprescindible y dejar escrito por qué, de forma que la cuenta se pueda hacer.

Regla verificableNúmero de relaciones con filtrado en ambos sentidos: exactamente una, y es la de seguridad.

Lo que no se puede construir, se declara

En todo proyecto llega el momento en que la especificación pide una columna que el origen no entrega. Hay dos formas de resolverlo.

La primera es rellenarla con un valor plausible. Es rápida, nadie protesta, y crea un problema que no tiene arreglo: tres meses después, un valor plausible es indistinguible de un valor real, y alguien lo va a usar para decidir algo.

La segunda es declararla. Con cada despliegue se publica un registro de cobertura que dice, columna a columna, qué se implementó, qué no, y por qué no. Tiene tres apartados, y el tercero es el que importa: columnas implementadas, columnas declaradas sin origen con su motivo escrito, y columnas no implementadas sin explicación, que tiene que valer cero.

Algunos de esos huecos rompen indicadores del catálogo. Eso se dice en el acta de despliegue, con nombre y apellidos, en vez de entregar el indicador calculado con la mitad de los ingredientes.

Un hueco declarado es una tarea pendiente. Un hueco rellenado es una mentira con fecha de caducidad larga.

La parte que hizo la IA, y la que no

El proyecto se construyó con asistencia de un modelo de lenguaje, y como esto suele contarse fatal —o como magia, o como fraude— prefiero ser preciso sobre qué se delegó.

No se delegó ninguna decisión de negocio. Las definiciones, las reglas, los criterios de aceptación y las ambigüedades resueltas las decidió una persona y quedaron escritas en un acta y en un pliego, antes de que se escribiera una línea de código. Lo que se delegó es la derivación: a partir de esos documentos, producir el modelo, las transformaciones, las medidas y los controles.

DECIDE UNA PERSONA SE DERIVA DEL DOCUMENTO Qué significa cada término Qué regla se aplica y cuál no Qué cifra tiene que salir Si se acepta o no se acepta La estructura del modelo El código de transformación Las medidas de cálculo Los controles de validación La columna de la derecha solo es fiable si la de la izquierda está escrita y cerrada.
La frontera no está donde la gente supone. No separa lo difícil de lo fácil: separa lo que alguien tiene que decidir y firmar de lo que, una vez decidido, es traducción.

Las reglas que hubo que escribir

Para que esa derivación sea fiable hizo falta escribir unas cuantas reglas del encargo. Las cuatro que más trabajo dieron:

  • No inventes una necesidad y después olvides implementarla en los datos.
  • No definas un indicador que después no pueda calcularse. Esta es la más exigente de todas, porque obliga a cerrar el círculo: cada fórmula del catálogo tiene que poder trazarse hasta una columna que existe de verdad. Es la que produce el registro de cobertura de la sección anterior.
  • No generes columnas que no tengan utilidad.
  • Cuando exista ambigüedad, debe aparecer discutida, no resuelta en silencio.

La cuarta merece un párrafo propio, porque corrige la idea equivocada sobre dónde está el riesgo. El modo de fallo de un modelo de lenguaje no es inventarse algo disparatado: eso se ve y se corrige. El modo de fallo es resolver una ambigüedad de forma razonable y seguir adelante sin decirlo. Esa decisión queda tomada, no queda escrita, y aparece seis semanas más tarde como una cifra que nadie sabe explicar. Pedir explícitamente que las dudas se levanten en vez de resolverse convierte el silencio en una pregunta, que es algo con lo que sí se puede trabajar.

Una nota de implementación que resultó importar más de lo que parecía: esas reglas no van pegadas en el mensaje, van en la configuración del proyecto. Así se aplican a todas las conversaciones y no solo a la que recordaste. Y hay una diferencia de fondo entre las dos cosas: una regla en el mensaje es un truco; una regla en la configuración es una política.

Por qué los criterios de aceptación dejaron de ser opcionales

Un despliegue es determinista: ejecutas lo mismo y pasa lo mismo. Una generación no lo es. El mismo encargo, lanzado dos veces, da dos redacciones, dos órdenes y a veces una función de más.

Eso obliga a cambiar la pregunta de control. «¿Ha terminado?» deja de significar nada, y la única pregunta que sirve es «¿han salido las cifras que tenían que salir?». Por eso cada fase del proyecto cerró con un acta que fija números concretos —cuántas tablas, cuántas filas, cuántos controles en verde— y la fase siguiente no empieza hasta que esos números coinciden.

Es exactamente la misma disciplina que exige un proyecto hecho a mano por un equipo de seis personas. La diferencia es que aquí no es opcional: sin criterios numéricos, «ha terminado» y «ha terminado bien» son la misma frase.

Lo que tienen en común

Releyendo la lista, todas las decisiones encajan en el mismo molde, y no creo que sea casualidad.

Ninguna se eligió por ser la más elegante, ni la más moderna, ni la que mejor queda en una presentación. Todas se eligieron porque la alternativa falla en un momento concreto que llega siempre: el día que hay que reprocesar, el día que el sistema de origen cambia sus códigos, el día que alguien pregunta por qué la suma de las partes no da el total, el día que alguien hereda esto y tiene que entenderlo sin que estés tú delante.

Y por eso no se ven. Una plataforma con estas decisiones tomadas no parece especialmente bien hecha: parece normal, que es exactamente el objetivo. Lo que se nota son las que faltan.

Esto sale de un proyecto de laboratorio que construí para recorrer el método completo sin depender de los tiempos ni de los permisos de un cliente real. Las decisiones son las que tomaría en un proyecto de verdad, y si tú tomas alguna de otra manera, me interesa mucho saber por qué.

Comentarios

Deja un comentario