20  Inteligencia de negocio

La inteligencia de negocio o Business Intelligence (BI) es sin duda uno de los recursos clave a la hora de conocer la actividad de nuestra empresa. Toda esa información que los datos ocultan, si la manipulamos de forma correcta y la presentamos de un modo lógico puede ayudarnos a determinar si estamos comprando de más, vendiendo de menos, si nuestras líneas de fabricación están siendo bien empleadas o si nuestros almacenes requieren una renovación del stock.

Lo que hace una herramienta de BI, por debajo, es más sencillo de lo que su precio suele sugerir: traduce clics en SQL, ejecuta ese SQL contra el almacén y dibuja el resultado. Todo el valor está en las tres decisiones que rodean ese ciclo: quién define las métricas, dónde se ejecuta el cálculo y cómo se versiona lo que se construye.

20.1 BI de clics y BI de código

La división que más determina el día a día de un equipo de datos no es entre proveedores, sino entre dos filosofías.

En el BI de clics los cuadros de mando se construyen arrastrando campos en una interfaz. La ventaja es evidente: cualquiera puede empezar sin ayuda. El coste aparece a los dos años, cuando hay trescientos informes, nadie sabe cuáles se usan, la misma métrica está definida de once formas distintas dentro de otros tantos ficheros binarios, y no hay forma de revisar un cambio antes de publicarlo.

En el BI de código el cuadro de mando es un fichero de texto en el repositorio. Se revisa en un pull request, se despliega con el resto del proyecto y se puede diferenciar entre versiones. Cuesta más arrancar y escala infinitamente mejor. Es, además, coherente con todo lo que llevamos hecho: dlt es código, dbt es código, y no tendría mucho sentido que la última capa dejara de serlo.

20.2 Evidence

Evidence lleva el BI de código hasta su conclusión lógica: un informe es un fichero Markdown con consultas SQL dentro. No hay lienzo, no hay arrastrar y soltar, no hay fichero binario. Se escribe el texto que explica lo que se está mirando, se intercala la consulta que lo sostiene y se colocan los componentes que dibujan el resultado.

Encaja con este stack por cuatro motivos:

  • Habla DuckDB de forma nativa, que es exactamente el motor sobre el que hemos construido todo lo demás.
  • La salida es un sitio estático. El resultado de compilar un proyecto de Evidence es HTML, que se publica en cualquier sitio y no necesita servidor ni base de datos detrás. Es, literalmente, la misma mecánica con la que se publica este libro.
  • El informe es narrativo. Un cuadro de mando cuenta un número; un informe de Evidence cuenta por qué ese número es el que es, con el texto y el dato en el mismo fichero y sin posibilidad de que uno se desactualice respecto al otro.
  • Todo es texto plano y por tanto versionable, revisable y diferenciable.

20.2.1 Ponerlo en marcha

npx degit evidence-dev/template academia-informes
cd academia-informes
npm install
npm run sources   # ejecuta las consultas contra el origen
npm run dev       # levanta el sitio en http://localhost:3000

El origen se declara en un fichero por conexión:

# sources/lago/connection.yaml
name: lago
type: duckdb
options:
  filename: consumo.duckdb
AdvertenciaEl punto flojo de esta combinación

Conviene decirlo con claridad. Evidence habla DuckDB, pero no habla DuckLake directamente: su conector espera un fichero de base de datos, no una sentencia ATTACH con la extensión cargada.

Hay dos salidas razonables y ninguna es dramática. La primera es dejar que dbt materialice también la capa de consumo en un fichero DuckDB local, que es un modelo más en el proyecto y pesa lo que pesen unas cuantas dimensiones. La segunda es generar ese fichero como paso previo a npm run sources, con un script de tres líneas que adjunta el lago y copia las tablas de marts.

Es el precio de usar la herramienta más joven del cuadro. Si esto molesta, Rill tiene conector nativo de DuckLake y consulta el lago sin copia intermedia; le hemos dedicado un apéndice.

20.2.2 Una página

Así se escribe un informe completo. Nótese que el bloque SQL tiene nombre (matriculas_por_asignatura) y que los componentes lo consumen por ese nombre:

---
title: Alumnado del curso
---

Los datos salen de la capa de consumo del almacén y se actualizan con cada
ejecución de la ingesta.

```sql alumnos
select count(*) as alumnos from marts.dim_alumno
```

Ahora mismo hay <Value data={alumnos} column=alumnos /> alumnos dados de alta.

```sql matriculas_por_asignatura
select
    s.asignatura,
    count(*) as matriculas
from marts.fct_matriculas f
join marts.dim_asignatura s on s.asignatura_id = f.asignatura_id
group by 1
order by 2 desc
```

<BarChart
    data={matriculas_por_asignatura}
    x=asignatura
    y=matriculas
    title="Matrículas por asignatura"
/>

Ese <Value> incrustado en mitad de una frase es la idea entera de Evidence. El texto no dice “hay cinco alumnos” y se queda desfasado la semana que viene: dice el número que devuelve la consulta, siempre.

20.2.3 El resultado

Compilar lo anterior produce un panel como este. Lo que sigue está calculado con las mismas consultas contra el mismo lakehouse, pero dibujado con las herramientas del propio libro, porque Evidence necesita Node para compilar y no queremos esa dependencia solo para una figura.

Alumnado del curso
5Alumnos
4Matrículas
3Asignaturas
1Sin matricular

Matrículas por asignatura

Biología3
Historia1
Matemáticas0

Matrículas por día de carga

2026-01-103
2026-01-121
Fuente: marts.dim_alumno, marts.fct_matriculas, marts.dim_asignatura del lakehouse. Sin copias intermedias.

Dos detalles de ese panel no están ahí por decoración.

La tarjeta ámbar es exactamente la ambigüedad que discutíamos en el capítulo anterior: según se cuenten los alumnos por la dimensión o por los hechos, el panel dice cinco o cuatro. Que ambas cifras aparezcan juntas y con nombres distintos es lo que evita la reunión de las dos horas.

Y Matemáticas aparece con cero. Es el error más repetido de un cuadro de mando: la consulta natural cruza los hechos con la dimensión y, al hacerlo, la asignatura sin matrículas desaparece del gráfico. Nadie la echa de menos, porque no se ve lo que no está. Basta con partir de la dimensión y cruzar hacia los hechos (left join en lugar de join) para que el vacío sea visible, que es justo la información que alguien necesitaba.

20.3 Lightdash

Hay un segundo enfoque que merece la pena conocer, sobre todo si el problema no es publicar informes sino dar autoservicio a gente que no va a escribir SQL.

Lightdash se conecta directamente al proyecto de dbt y toma de ahí su modelo: las tablas son los modelos, y las métricas son las que estén declaradas en el YAML de dbt. No hay que redefinir nada, porque la capa semántica ya vive donde vive el código.

# models/marts/_marts.yml
models:
  - name: fct_matriculas
    meta:
      metrics:
        matriculas:
          type: count
          label: "Matrículas"
          description: "Matrículas registradas, una por alumno y asignatura."

Esa métrica aparece sola en la interfaz, y quien explore no puede inventarse otra forma de contar. Es la propiedad que lo distingue del BI de clics clásico: la interfaz es de clics, pero las definiciones son de código.

A cambio, es un servicio que hay que desplegar y operar, con su base de datos propia. Para un equipo pequeño es una pieza más de infraestructura; para uno con cincuenta consumidores de datos, es justo lo que hace falta.

20.4 El panorama

Herramientas de explotación habituales
Herramienta Naturaleza Cuándo encaja
Evidence Abierta, informes en Markdown y SQL Informes narrativos, publicación estática, equipos que versionan
Rill Abierta, exploración, DuckDB nativo Stack DuckDB/DuckLake, análisis interactivo, capa semántica incluida
Lightdash Abierta, sobre métricas de dbt Autoservicio cuando la semántica ya vive en dbt
Metabase Abierta, orientada a clics Autoservicio para gente no técnica, arranque rápido
Superset Abierta, muy completa Muchos usuarios y muchas fuentes, si hay quien la opere
Power BI, Tableau, Looker Comerciales Cuando ya están implantadas, que suele ser el caso

Las tres primeras se reparten el trabajo bastante bien y no compiten tanto como parece: Evidence publica lo que hay que contar, Rill sirve para averiguar qué está pasando y Lightdash para que otros se lo pregunten solos.

La observación honesta sobre la última fila: en la mayoría de organizaciones la herramienta de BI ya está elegida y no la elige el equipo de datos. Lo que sí se puede elegir, y es donde está el margen de maniobra real, es que las métricas vivan fuera de ella. Un almacén bien modelado con una capa semántica versionada sirve a Power BI igual de bien que a Evidence, y sobrevive al día que la organización cambie de herramienta.

NotaEl círculo se cierra

Merece la pena detenerse en lo que acaba de pasar. La misma cadena de conexión que escribió dlt al aterrizar los datos, que leyó dbt al construir el vault, es la que alimenta el panel de ahí arriba.

Ni una sola copia intermedia, ni un formato propietario en ningún punto del recorrido, y todos los datos siguen siendo ficheros Parquet que cualquier motor puede leer. Eso es lo que promete un lakehouse abierto, y no siempre se cumple.

20.5 Lo que el BI no arregla

Para cerrar, y en la misma línea que decíamos del catálogo, conviene no depositar en la herramienta expectativas que no puede cumplir.

Un cuadro de mando no convierte un dato malo en bueno, solo lo hace más visible y más fácil de propagar. No sustituye a la definición de las métricas: si no existe, cada informe inventará la suya con más comodidad que antes. Y no crea la costumbre de mirar los datos, que es en última instancia un asunto de cultura y no de software.

Lo que sí hace, cuando lo anterior está en su sitio, es cerrar el ciclo: convertir en decisiones el trabajo de las cuatro partes anteriores de este libro. Que era, desde el principio, el objetivo de todo esto.