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
| Atributo | Requerido | Por defecto | Descripción |
|---|---|---|---|
name | sí | — | Nombre para mostrar usado en consultas MDX |
defaultMeasure | no | — | Medida seleccionada cuando no se especifica ninguna en la consulta |
caption | no | — | Sobrescribir nombre para mostrar para herramientas cliente |
description | no | — | Descripción legible por humanos |
visible | no | true | Si el cubo aparece a las herramientas cliente |
cache | no | true | Si Mondrian cachea agregados para este cubo |
enabled | no | true | Deshabilitar un cubo lo oculta sin eliminarlo |
enableScenarios | no | false | Habilita 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"<MeasureGroup name="Sales" table="sales_fact_1997"> <Measures> <Measure name="Unit Sales" column="unit_sales" aggregator="sum" formatString="#,###"/> <Measure name="Store Sales" column="store_sales" aggregator="sum" formatString="#,###.##"/> <Measure name="Store Cost" column="store_cost" aggregator="sum" formatString="#,###.00"/> </Measures> <DimensionLinks> <ForeignKeyLink dimension="Customer" foreignKeyColumn="customer_id"/> <ForeignKeyLink dimension="Time" foreignKeyColumn="time_id"/> </DimensionLinks></MeasureGroup>Medidas
Atributos de medida
Cada elemento <Measure> tiene los siguientes atributos:
| Atributo | Requerido | Por defecto | Descripción |
|---|---|---|---|
name | sí | — | Nombre para mostrar usado en consultas MDX |
column | sí* | — | Columna en la tabla de hechos. Use un nombre de columna calculada si el valor es derivado |
aggregator | sí | — | Función de agregación — ver más abajo |
formatString | no | — | Cómo se formatea el valor para mostrar |
datatype | no | Numeric | Cómo se almacenan los valores en la caché de Mondrian y se devuelven mediante XML for Analysis |
caption | no | — | Sobrescribir nombre para mostrar para herramientas cliente |
description | no | — | Descripción legible por humanos |
visible | no | true | Si la medida aparece a las herramientas cliente |
formatter | no | — | Nombre de clase completamente cualificado de un formateador de celda personalizado |
table | no | — | Sobrescribir 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:
| Valor | Significado |
|---|---|
sum | Suma de todos los valores |
count | Recuento de filas |
min | Valor mínimo |
max | Valor máximo |
avg | Media aritmética |
distinct-count | Recuento de valores distintos |
median | Mediana (percentil 50) — no aditivo |
percentile | Un 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"<Measure name="Median Order Value" column="order_total" aggregator="median"/><Measure 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ón | Salida de ejemplo |
|---|---|
#,### | 32,910 |
#,###.## | 69,798.23 |
#,###.00 | 69,798.23 |
$#,##0.00 | $69,798.23 |
Standard | por 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"<Measure 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)"<Table name="sales_fact_1997"> <ColumnDefs> <CalculatedColumnDef name="promotion_sales"> <ExpressionView> <SQL dialect="generic">(case when <Column name="promotion_id"/> = 0 then 0 else <Column name="store_sales"/> end)</SQL> </ExpressionView> </CalculatedColumnDef> </ColumnDefs></Table>Luego referencia esa columna igual que cualquier otra:
measures:- name: "Promotion Sales" column: "promotion_sales" aggregator: "sum" format_string: "#,###.00"<Measure name="Promotion Sales" aggregator="sum" column="promotion_sales" formatString="#,###.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"<Attribute name="Quarter"> <Key> <Column name="the_year"/> <Column name="quarter"/> </Key></Attribute>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.