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
| Attribut | Requis | Défaut | Description |
|---|---|---|---|
name | oui | — | Nom d’affichage utilisé dans les requêtes MDX |
defaultMeasure | non | — | Mesure sélectionnée quand aucune n’est spécifiée dans la requête |
caption | non | — | Nom d’affichage de substitution pour les outils clients |
description | non | — | Description lisible par humain |
visible | non | true | Si le cube apparaît aux outils clients |
cache | non | true | Si Mondrian met en cache les agrégats pour ce cube |
enabled | non | true | Désactiver un cube le masque sans le retirer |
enableScenarios | non | false | Active 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"<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>Mesures
Attributs de mesure
Chaque élément <Measure> a les attributs suivants :
| Attribut | Requis | Défaut | Description |
|---|---|---|---|
name | oui | — | Nom d’affichage utilisé dans les requêtes MDX |
column | oui* | — | Colonne dans la table de faits. Utilisez un nom de colonne calculée si la valeur est dérivée |
aggregator | oui | — | Fonction d’agrégation — voir ci-dessous |
formatString | non | — | Comment la valeur est formatée pour l’affichage |
datatype | non | Numeric | Comment les valeurs sont stockées dans le cache de Mondrian et renvoyées via XML for Analysis |
caption | non | — | Nom d’affichage de substitution pour les outils clients |
description | non | — | Description lisible par humain |
visible | non | true | Si la mesure apparaît aux outils clients |
formatter | non | — | Nom de classe pleinement qualifié d’un formatteur de cellule personnalisé |
table | non | — | Substituer 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 :
| Valeur | Signification |
|---|---|
sum | Somme de toutes les valeurs |
count | Nombre de lignes |
min | Valeur minimum |
max | Valeur maximum |
avg | Moyenne arithmétique |
distinct-count | Nombre de valeurs distinctes |
median | Médiane (50e percentile) — non additive |
percentile | Un 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"<Measure name="Median Order Value" column="order_total" aggregator="median"/><Measure 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 :
| Pattern | Exemple de sortie |
|---|---|
#,### | 32,910 |
#,###.## | 69,798.23 |
#,###.00 | 69,798.23 |
$#,##0.00 | $69,798.23 |
Standard | dé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"<Measure 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)"<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>Puis référencez cette colonne comme n’importe quelle autre :
measures:- name: "Promotion Sales" column: "promotion_sales" aggregator: "sum" format_string: "#,###.00"<Measure name="Promotion Sales" aggregator="sum" column="promotion_sales" formatString="#,###.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"<Attribute name="Quarter"> <Key> <Column name="the_year"/> <Column name="quarter"/> </Key></Attribute>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.