Pular para o conteúdo

Cubos e medidas

O elemento Cube

Um cubo (<Cube>) é uma coleção nomeada de dimensões e medidas.

Dimensões vivem dentro de um elemento contêiner <Dimensions>. Por convenção, elas são declaradas primeiro, seguidas das medidas organizadas em measure groups sob um elemento contêiner <MeasureGroups>. Um measure group é uma coleção de medidas que compartilham a mesma tabela de fato. Cubos simples têm exatamente um measure group; cubos mais avançados podem ter vários — por exemplo, quando você quer combinar uma tabela de fato transacional com uma tabela de rollup pré-agregada.

Atributos de Cube

AtributoObrigatórioDefaultDescrição
namesimNome de exibição usado em consultas MDX
defaultMeasurenãoMedida selecionada quando nenhuma é especificada na consulta
captionnãoSobrescreve o nome de exibição para ferramentas cliente
descriptionnãoDescrição legível
visiblenãotrueSe o cubo aparece para ferramentas cliente
cachenãotrueSe o Mondrian cacheia agregados para este cubo
enablednãotrueDesabilitar um cubo o esconde sem removê-lo
enableScenariosnãofalseHabilita cenários de write-back / what-if

Como tabelas de fato e dimensões se conectam

O cubo [Sales] no exemplo de estrutura do schema tem seu measure group baseado na tabela "sales_fact_1997". Cada tabela referenciada no schema lógico também deve aparecer no bloco <PhysicalSchema>.

A tabela de fato contém as colunas das quais as medidas são calculadas, mais colunas de foreign key que ligam às tabelas de dimensão. O Mondrian precisa saber de todas:

  • Cada coluna de medida aparece dentro de uma definição <Measure>.
  • Cada coluna de foreign key aparece dentro de um elemento <ForeignKeyLink>, conectando o measure group à dimensão apropriada.
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 Measure

Cada elemento <Measure> tem os seguintes atributos:

AtributoObrigatórioDefaultDescrição
namesimNome de exibição usado em consultas MDX
columnsim*Coluna na tabela de fato. Use um nome de coluna calculada se o valor for derivado
aggregatorsimFunção de agregação — veja abaixo
formatStringnãoComo o valor é formatado para exibição
datatypenãoNumericComo os valores são armazenados no cache do Mondrian e retornados via XML for Analysis
captionnãoSobrescreve o nome de exibição para ferramentas cliente
descriptionnãoDescrição legível
visiblenãotrueSe a medida aparece para ferramentas cliente
formatternãoNome qualificado da classe de um cell formatter customizado
tablenãoSobrescreve a tabela do measure group para esta medida (avançado)

* column é obrigatório a menos que você aponte para uma coluna calculada definida no schema físico.

Tipos de agregador

O atributo aggregator suporta os seguintes valores:

ValorSignificado
sumSoma de todos os valores
countContagem de linhas
minValor mínimo
maxValor máximo
avgMédia aritmética
distinct-countContagem de valores distintos
medianMediana (50º percentil) — não-aditivo
percentileUm percentil (defina percentile="0..100", default 50) — não-aditivo

distinct-count tem limitações quando o cubo contém uma hierarquia parent-child.

Agregadores não-aditivos: median e percentile

median e percentile são agregadores folha não-aditivos: não existe mediana das medianas, então não podem ser combinados a partir de sub-agregados. O Saiku os empurra para SQL como PERCENTILE_CONT(fraction) WITHIN GROUP (ORDER BY column) e os computa no grão exato que você consultou — eles são deliberadamente excluídos da substituição por tabela agregada e do rollup de segmento por cache (para que você nunca obtenha uma “mediana de medianas” errada).

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

Eles exigem o backend Calcite (o default do Saiku) em um banco que suporte PERCENTILE_CONT — PostgreSQL, Oracle, SQL Server, Snowflake, BigQuery, H2, DuckDB e similares. Em um backend sem ele, a consulta é recusada com um erro claro em vez de retornar um número errado. A troca é intencional: você perde pré-agregação/rollup de cache para essas medidas, em troca de um valor correto no grão consultado.

Tipos de dados

O atributo datatype controla como os valores de célula são armazenados no cache do Mondrian e retornados por XML for Analysis. Valores aceitos são String, Integer, Numeric, Boolean, Date, Time e Timestamp. O default é Numeric, exceto para medidas count e distinct-count, que default para Integer.

Format strings

O atributo opcional formatString controla como um valor é impresso. Os símbolos , e . são sensíveis à locale — se você está rodando em italiano, #,###.00 pode produzir 48.123,45. Alguns padrões comuns:

PadrãoExemplo de saída
#,###32,910
#,###.##69,798.23
#,###.0069,798.23
$#,##0.00$69,798.23
Standarddefault de locale

Para padrões avançados de data e formatos condicionais, veja a referência de format strings do MDX.

Caption

Uma medida pode ter um atributo caption que é retornado em vez do name pelas APIs cliente. Isso é útil quando você quer localizar o nome de uma medida ou exibir caracteres especiais:

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

Colunas calculadas em medidas

Em vez de apontar uma medida para uma coluna bruta, você pode derivar o valor de uma expressão SQL. Defina uma coluna calculada na declaração <PhysicalSchema> da tabela de fato e referencie-a por nome na <Measure>:

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

Depois referencie essa coluna como qualquer outra:

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

O <PhysicalSchema> reúne todos os detalhes de implementação em um lugar. A definição <Measure> não precisa saber — nem se importar — que promotion_sales é calculada. Toda vez que o Mondrian precisa acessá-la, o engine substitui pela expressão SQL. Expressões SQL arbitrárias são suportadas, incluindo subqueries, contanto que o banco subjacente possa avaliá-las em contexto de agregado.

Quando a chave de uma dimensão abrange mais de uma coluna, você expressa isso com um bloco <Key> multi-coluna no <Attribute>:

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

Se há apenas uma coluna de chave, <Key> e o atributo shorthand keyColumn são equivalentes — use o que for mais claro. Você não precisa especificar nameColumn separadamente quando default para a última coluna da chave composta.

Quando uma tabela de dimensão tem uma primary key composta, o <ForeignKeyLink> no <MeasureGroup> da tabela de fato deve fornecer uma coluna de foreign key por coluna na chave composta. Veja Schema físico para a referência completa de links.