Saltearse al contenido

Cubos y medidas

El elemento Cube

Un cubo (<Cube>) es una colección nombrada de dimensiones y medidas.

Las dimensiones viven dentro de un elemento contenedor <Dimensions>. Por convención se declaran primero, seguidas de las medidas organizadas en grupos de medidas bajo un elemento contenedor <MeasureGroups>. Un grupo de medidas es una colección de medidas que comparten la misma tabla de hechos. Los cubos simples tienen exactamente un grupo de medidas; los cubos más avanzados pueden tener varios — por ejemplo cuando quiere combinar una tabla de hechos transaccional con una tabla de rollup preagregada.

Atributos del cubo

AtributoRequeridoPor defectoDescripción
nameNombre para mostrar usado en consultas MDX
defaultMeasurenoMedida seleccionada cuando no se especifica ninguna en la consulta
captionnoSobrescribir nombre para mostrar para herramientas cliente
descriptionnoDescripción legible por humanos
visiblenotrueSi el cubo aparece a las herramientas cliente
cachenotrueSi Mondrian cachea agregados para este cubo
enablednotrueDeshabilitar un cubo lo oculta sin eliminarlo
enableScenariosnofalseHabilita escenarios de write-back / what-if

Cómo se conectan las tablas de hechos y las dimensiones

El cubo [Sales] en el ejemplo de estructura del schema tiene su grupo de medidas basado en la tabla "sales_fact_1997". Cada tabla referenciada en el schema lógico también debe aparecer en el bloque <PhysicalSchema>.

La tabla de hechos contiene las columnas a partir de las cuales se calculan las medidas, más columnas de clave foránea que enlazan a tablas de dimensión. Mondrian necesita saber sobre todas ellas:

  • Cada columna de medida aparece dentro de una definición <Measure>.
  • Cada columna de clave foránea aparece dentro de un elemento <ForeignKeyLink>, conectando el grupo de medidas con la dimensión apropiada.
measure_groups:
- name: "Sales"
table: "sales_fact_1997"
measures:
- name: "Unit Sales"
column: "unit_sales"
aggregator: "sum"
format_string: "#,###"
- name: "Store Sales"
column: "store_sales"
aggregator: "sum"
format_string: "#,###.##"
- name: "Store Cost"
column: "store_cost"
aggregator: "sum"
format_string: "#,###.00"
dimension_links:
- type: "foreign_key"
dimension: "Customer"
foreign_key_column: "customer_id"
- type: "foreign_key"
dimension: "Time"
foreign_key_column: "time_id"

Medidas

Atributos de medida

Cada elemento <Measure> tiene los siguientes atributos:

AtributoRequeridoPor defectoDescripción
nameNombre para mostrar usado en consultas MDX
columnsí*Columna en la tabla de hechos. Use un nombre de columna calculada si el valor es derivado
aggregatorFunción de agregación — ver más abajo
formatStringnoCómo se formatea el valor para mostrar
datatypenoNumericCómo se almacenan los valores en la caché de Mondrian y se devuelven mediante XML for Analysis
captionnoSobrescribir nombre para mostrar para herramientas cliente
descriptionnoDescripción legible por humanos
visiblenotrueSi la medida aparece a las herramientas cliente
formatternoNombre de clase completamente cualificado de un formateador de celda personalizado
tablenoSobrescribir la tabla del grupo de medidas para esta medida (avanzado)

* column es requerido a menos que apunte a una columna calculada definida en el schema físico.

Tipos de agregador

El atributo aggregator admite los siguientes valores:

ValorSignificado
sumSuma de todos los valores
countRecuento de filas
minValor mínimo
maxValor máximo
avgMedia aritmética
distinct-countRecuento de valores distintos
medianMediana (percentil 50) — no aditivo
percentileUn percentil (defina percentile="0..100", por defecto 50) — no aditivo

distinct-count tiene limitaciones cuando el cubo contiene una jerarquía padre-hijo.

Agregadores no aditivos: median y percentile

median y percentile son agregadores de hoja no aditivos: no hay mediana de medianas, así que no pueden combinarse a partir de subagregados. Saiku los empuja a SQL como PERCENTILE_CONT(fraction) WITHIN GROUP (ORDER BY column) y los computa en la granularidad exacta que consultó — están deliberadamente excluidos de la sustitución de tabla agregada y del rollup de segmentos desde caché (para que nunca obtenga una incorrecta “mediana de medianas”).

measures:
- name: "Median Order Value"
column: "order_total"
aggregator: "median"
- name: "P90 Latency"
column: "latency_ms"
aggregator: "percentile"
percentile: "90"

Requieren el backend Calcite (el predeterminado de Saiku) sobre una base de datos que soporte PERCENTILE_CONT — PostgreSQL, Oracle, SQL Server, Snowflake, BigQuery, H2, DuckDB y similares. En un backend sin él, la consulta se rechaza con un error claro en lugar de devolver un número incorrecto. La compensación es intencional: pierde la pre-agregación/rollup de caché para estas medidas, a cambio de un valor correcto en la granularidad consultada.

Tipos de datos

El atributo datatype controla cómo se almacenan los valores de celda en la caché de Mondrian y cómo se devuelven sobre XML for Analysis. Los valores aceptados son String, Integer, Numeric, Boolean, Date, Time y Timestamp. El valor por defecto es Numeric, excepto para las medidas count y distinct-count, que por defecto son Integer.

Cadenas de formato

El atributo opcional formatString controla cómo se imprime un valor. Los símbolos , y . son sensibles al locale — si está ejecutando en italiano, #,###.00 podría producir 48.123,45. Algunos patrones comunes:

PatrónSalida de ejemplo
#,###32,910
#,###.##69,798.23
#,###.0069,798.23
$#,##0.00$69,798.23
Standardpor defecto del locale

Para patrones de fecha avanzados y formatos condicionales consulte la referencia de cadenas de formato MDX.

Caption

Una medida puede tener un atributo caption que las APIs cliente devuelven en lugar de su name. Esto es útil cuando quiere localizar el nombre de una medida o mostrar caracteres especiales:

measures:
- name: "Sum X"
column: "sum_x"
aggregator: "sum"
caption: "Σ X"

Columnas calculadas en medidas

En lugar de apuntar una medida a una columna cruda, puede derivar el valor de una expresión SQL. Defina una columna calculada en la declaración <PhysicalSchema> de la tabla de hechos y luego referénciela por nombre en la <Measure>:

calculated_columns:
- name: "promotion_sales"
expression:
generic: "(case when {col:promotion_id} = 0 then 0 else {col:store_sales}\
\ end)"

Luego referencia esa columna igual que cualquier otra:

measures:
- name: "Promotion Sales"
column: "promotion_sales"
aggregator: "sum"
format_string: "#,###.00"

El <PhysicalSchema> reúne todos los detalles de implementación en un solo lugar. La definición <Measure> no necesita saber — ni le importa — que promotion_sales es calculada. Cada vez que Mondrian necesita acceder a ella, el motor sustituye la expresión SQL en su lugar. Se admiten expresiones SQL arbitrarias, incluyendo subconsultas, mientras la base de datos subyacente pueda evaluarlas en un contexto de agregado.

Claves compuestas y enlaces de dimensión

Cuando la clave de una dimensión abarca más de una columna, lo expresa con un bloque <Key> multi-columna en el <Attribute>:

attributes:
- name: "Quarter"
key:
- "the_year"
- "quarter"

Si solo hay una columna clave, <Key> y el atributo abreviado keyColumn son equivalentes — use el que sea más claro. No necesita especificar nameColumn por separado cuando por defecto es la última columna en la clave compuesta.

Cuando una tabla de dimensión tiene una clave primaria compuesta, el <ForeignKeyLink> en el <MeasureGroup> de la tabla de hechos debe suministrar una columna de clave foránea por columna en la clave compuesta. Consulte Schema físico para la referencia completa de enlaces.