Aller au contenu

Cubes et mesures

L’élément Cube

Un cube (<Cube>) est une collection nommée de dimensions et de mesures.

Les dimensions vivent à l’intérieur d’un élément conteneur <Dimensions>. Par convention, elles sont déclarées en premier, suivies des mesures organisées en groupes de mesures sous un élément conteneur <MeasureGroups>. Un groupe de mesures est une collection de mesures qui partagent la même table de faits. Les cubes simples ont exactement un groupe de mesures ; les cubes plus avancés peuvent en avoir plusieurs — par exemple lorsque vous souhaitez combiner une table de faits de transactions avec une table de rollup pré-agrégée.

Attributs de cube

AttributRequisDéfautDescription
nameouiNom d’affichage utilisé dans les requêtes MDX
defaultMeasurenonMesure sélectionnée quand aucune n’est spécifiée dans la requête
captionnonNom d’affichage de substitution pour les outils clients
descriptionnonDescription lisible par humain
visiblenontrueSi le cube apparaît aux outils clients
cachenontrueSi Mondrian met en cache les agrégats pour ce cube
enablednontrueDésactiver un cube le masque sans le retirer
enableScenariosnonfalseActive les scénarios write-back / what-if

Comment les tables de faits et les dimensions se connectent

Le cube [Sales] dans l’exemple de structure de schema a son groupe de mesures basé sur la table "sales_fact_1997". Chaque table référencée dans le schema logique doit également apparaître dans le bloc <PhysicalSchema>.

La table de faits contient les colonnes à partir desquelles les mesures sont calculées, plus les colonnes de clés étrangères qui se lient aux tables de dimension. Mondrian doit toutes les connaître :

  • Chaque colonne de mesure apparaît à l’intérieur d’une définition <Measure>.
  • Chaque colonne de clé étrangère apparaît à l’intérieur d’un élément <ForeignKeyLink>, connectant le groupe de mesures à la dimension appropriée.
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"

Mesures

Attributs de mesure

Chaque élément <Measure> a les attributs suivants :

AttributRequisDéfautDescription
nameouiNom d’affichage utilisé dans les requêtes MDX
columnoui*Colonne dans la table de faits. Utilisez un nom de colonne calculée si la valeur est dérivée
aggregatorouiFonction d’agrégation — voir ci-dessous
formatStringnonComment la valeur est formatée pour l’affichage
datatypenonNumericComment les valeurs sont stockées dans le cache de Mondrian et renvoyées via XML for Analysis
captionnonNom d’affichage de substitution pour les outils clients
descriptionnonDescription lisible par humain
visiblenontrueSi la mesure apparaît aux outils clients
formatternonNom de classe pleinement qualifié d’un formatteur de cellule personnalisé
tablenonSubstituer la table du groupe de mesures pour cette mesure (avancé)

* column est requis sauf si vous pointez vers une colonne calculée définie dans le schema physique.

Types d’agrégateur

L’attribut aggregator prend en charge les valeurs suivantes :

ValeurSignification
sumSomme de toutes les valeurs
countNombre de lignes
minValeur minimum
maxValeur maximum
avgMoyenne arithmétique
distinct-countNombre de valeurs distinctes
medianMédiane (50e percentile) — non additive
percentileUn percentile (définissez percentile="0..100", défaut 50) — non additive

distinct-count a des limitations lorsque le cube contient une hiérarchie parent-enfant.

Agrégateurs non additifs : médiane et percentile

median et percentile sont des agrégateurs feuilles non additifs : il n’y a pas de médiane de médianes, donc ils ne peuvent pas être combinés à partir de sous-agrégats. Saiku les pousse en SQL comme PERCENTILE_CONT(fraction) WITHIN GROUP (ORDER BY column) et les calcule au grain exact que vous avez interrogé — ils sont délibérément exclus de la substitution de table d’agrégat et du rollup-from-cache de segment (pour que vous n’obteniez jamais une « médiane de médianes » erronée).

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

Ils nécessitent le backend Calcite (le défaut Saiku) sur une base de données qui prend en charge PERCENTILE_CONT — PostgreSQL, Oracle, SQL Server, Snowflake, BigQuery, H2, DuckDB et similaires. Sur un backend sans cela, la requête est refusée avec une erreur claire plutôt que de renvoyer un mauvais nombre. Le compromis est intentionnel : vous perdez la pré-agrégation/cache-rollup pour ces mesures, en échange d’une valeur correcte au grain interrogé.

Types de données

L’attribut datatype contrôle comment les valeurs de cellule sont stockées dans le cache de Mondrian et renvoyées via XML for Analysis. Les valeurs acceptées sont String, Integer, Numeric, Boolean, Date, Time et Timestamp. Le défaut est Numeric, sauf pour les mesures count et distinct-count, qui ont Integer par défaut.

Chaînes de format

L’attribut formatString facultatif contrôle comment une valeur est imprimée. Les symboles , et . sont sensibles à la locale — si vous tournez en italien, #,###.00 pourrait produire 48.123,45. Quelques patterns courants :

PatternExemple de sortie
#,###32,910
#,###.##69,798.23
#,###.0069,798.23
$#,##0.00$69,798.23
Standarddéfaut de la locale

Pour des patterns de date avancés et des formats conditionnels, voir la référence des chaînes de format MDX.

Légende

Une mesure peut avoir un attribut caption qui est renvoyé à la place de son name par les API clients. C’est utile lorsque vous voulez localiser un nom de mesure ou afficher des caractères spéciaux :

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

Colonnes calculées dans les mesures

Plutôt que de pointer une mesure sur une colonne brute, vous pouvez dériver la valeur d’une expression SQL. Définissez une colonne calculée dans la déclaration <PhysicalSchema> de la table de faits puis référencez-la par son nom dans la <Measure> :

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

Puis référencez cette colonne comme n’importe quelle autre :

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

Le <PhysicalSchema> rassemble tous les détails d’implémentation en un seul endroit. La définition <Measure> n’a pas besoin de savoir — ni de se soucier — que promotion_sales est calculée. Chaque fois que Mondrian a besoin d’y accéder, le moteur substitue l’expression SQL à la place. Les expressions SQL arbitraires sont prises en charge, y compris les sous-requêtes, tant que la base de données sous-jacente peut les évaluer dans un contexte d’agrégat.

Clés composites et liens de dimension

Lorsque la clé d’une dimension couvre plus d’une colonne, vous l’exprimez avec un bloc <Key> multi-colonnes sur l’<Attribute> :

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

S’il n’y a qu’une seule colonne clé, <Key> et l’attribut raccourci keyColumn sont équivalents — utilisez celui qui est le plus clair. Vous n’avez pas besoin de spécifier nameColumn séparément quand il défaut sur la dernière colonne dans la clé composite.

Lorsqu’une table de dimension a une clé primaire composite, le <ForeignKeyLink> dans le <MeasureGroup> de la table de faits doit fournir une colonne de clé étrangère par colonne dans la clé composite. Voir Schema physique pour la référence complète des liens.