Cubes und Measures
Das Cube-Element
Ein Cube (<Cube>) ist eine benannte Sammlung von Dimensionen und Measures.
Dimensionen leben innerhalb eines <Dimensions>-Holder-Elements. Konventionell werden sie zuerst deklariert, gefolgt von Measures, die in Measure-Gruppen unter einem <MeasureGroups>-Holder-Element organisiert sind. Eine Measure-Gruppe ist eine Sammlung von Measures, die dieselbe Faktentabelle teilen. Einfache Cubes haben genau eine Measure-Gruppe; fortgeschrittenere Cubes können mehrere haben — zum Beispiel, wenn Sie eine Transaktions-Faktentabelle mit einer vor-aggregierten Rollup-Tabelle kombinieren möchten.
Cube-Attribute
| Attribut | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
name | ja | — | Anzeigename, der in MDX-Abfragen verwendet wird |
defaultMeasure | nein | — | Measure, das ausgewählt wird, wenn keines in der Abfrage angegeben ist |
caption | nein | — | Überschreibt den Anzeigenamen für Client-Tools |
description | nein | — | Menschenlesbare Beschreibung |
visible | nein | true | Ob der Cube für Client-Tools erscheint |
cache | nein | true | Ob Mondrian Aggregate für diesen Cube cacht |
enabled | nein | true | Das Deaktivieren eines Cubes versteckt ihn, ohne ihn zu entfernen |
enableScenarios | nein | false | Aktiviert Write-back- / What-if-Szenarien |
Wie Faktentabellen und Dimensionen verbunden werden
Der [Sales]-Cube im Schema-Struktur-Beispiel hat seine Measure-Gruppe auf der Tabelle "sales_fact_1997" basierend. Jede im logischen Schema referenzierte Tabelle muss auch im <PhysicalSchema>-Block erscheinen.
Die Faktentabelle enthält die Spalten, aus denen Measures berechnet werden, plus Fremdschlüsselspalten, die zu Dimensionstabellen verlinken. Mondrian muss von allen wissen:
- Jede Measure-Spalte erscheint innerhalb einer
<Measure>-Definition. - Jede Fremdschlüsselspalte erscheint innerhalb eines
<ForeignKeyLink>-Elements, das die Measure-Gruppe mit der entsprechenden Dimension verbindet.
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>Measures
Measure-Attribute
Jedes <Measure>-Element hat die folgenden Attribute:
| Attribut | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
name | ja | — | Anzeigename, der in MDX-Abfragen verwendet wird |
column | ja* | — | Spalte in der Faktentabelle. Verwenden Sie einen berechneten Spaltennamen, wenn der Wert abgeleitet ist |
aggregator | ja | — | Aggregationsfunktion — siehe unten |
formatString | nein | — | Wie der Wert für die Anzeige formatiert wird |
datatype | nein | Numeric | Wie Werte in Mondrians Cache gespeichert und über XML for Analysis zurückgegeben werden |
caption | nein | — | Überschreibt den Anzeigenamen für Client-Tools |
description | nein | — | Menschenlesbare Beschreibung |
visible | nein | true | Ob das Measure für Client-Tools erscheint |
formatter | nein | — | Vollqualifizierter Klassenname eines Custom-Cell-Formatters |
table | nein | — | Überschreibt die Tabelle der Measure-Gruppe für dieses Measure (fortgeschritten) |
* column ist erforderlich, es sei denn, Sie zeigen auf eine berechnete Spalte, die im physischen Schema definiert ist.
Aggregator-Typen
Das aggregator-Attribut unterstützt die folgenden Werte:
| Wert | Bedeutung |
|---|---|
sum | Summe aller Werte |
count | Zeilenanzahl |
min | Minimaler Wert |
max | Maximaler Wert |
avg | Arithmetisches Mittel |
distinct-count | Anzahl unterschiedlicher Werte |
median | Median (50. Perzentil) — nicht-additiv |
percentile | Ein Perzentil (setzen Sie percentile="0..100", Standard 50) — nicht-additiv |
distinct-count hat Einschränkungen, wenn der Cube eine Parent-Child-Hierarchie enthält.
Nicht-additive Aggregatoren: Median und Perzentil
median und percentile sind nicht-additive Blatt-Aggregatoren: Es gibt keinen Median-of-Medians, sodass sie nicht aus Sub-Aggregaten kombiniert werden können. Saiku schiebt sie zu SQL als PERCENTILE_CONT(fraction) WITHIN GROUP (ORDER BY column) und berechnet sie auf der exakten Granularität, die Sie abgefragt haben — sie sind absichtlich von Aggregate-Tabellen-Substitution und Segment-Rollup-from-Cache ausgeschlossen (sodass Sie nie einen falschen „Median der Mediane” bekommen).
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"/>Sie erfordern das Calcite-Backend (Saiku-Standard) auf einer Datenbank, die PERCENTILE_CONT unterstützt — PostgreSQL, Oracle, SQL Server, Snowflake, BigQuery, H2, DuckDB und ähnliche. Auf einem Backend ohne dies wird die Abfrage mit einem klaren Fehler abgelehnt, statt eine falsche Zahl zurückzugeben. Der Kompromiss ist beabsichtigt: Sie verlieren Pre-Aggregation/Cache-Rollup für diese Measures, im Gegenzug für einen korrekten Wert auf der abgefragten Granularität.
Datentypen
Das datatype-Attribut steuert, wie Zellwerte in Mondrians Cache gespeichert und über XML for Analysis zurückgegeben werden. Akzeptierte Werte sind String, Integer, Numeric, Boolean, Date, Time und Timestamp. Der Standard ist Numeric, außer für count- und distinct-count-Measures, die auf Integer standardmäßig setzen.
Format-Strings
Das optionale formatString-Attribut steuert, wie ein Wert gedruckt wird. Die Symbole , und . sind locale-sensitiv — wenn Sie auf Italienisch laufen, könnte #,###.00 48.123,45 erzeugen. Ein paar gängige Muster:
| Muster | Beispielausgabe |
|---|---|
#,### | 32.910 |
#,###.## | 69.798,23 |
#,###.00 | 69.798,23 |
$#,##0.00 | $69.798,23 |
Standard | Locale-Standard |
Für fortgeschrittene Datumsmuster und bedingte Formate siehe die MDX-Format-Strings-Referenz.
Caption
Ein Measure kann ein caption-Attribut haben, das anstelle seines name von Client-APIs zurückgegeben wird. Dies ist nützlich, wenn Sie einen Measure-Namen lokalisieren oder Sonderzeichen anzeigen möchten:
measures:- name: "Sum X" column: "sum_x" aggregator: "sum" caption: "Σ X"<Measure name="Sum X" column="sum_x" aggregator="sum" caption="Σ X"/>Berechnete Spalten in Measures
Statt ein Measure auf eine rohe Spalte zu zeigen, können Sie den Wert aus einem SQL-Ausdruck ableiten. Definieren Sie eine berechnete Spalte in der <PhysicalSchema>-Deklaration der Faktentabelle und referenzieren Sie sie dann namentlich im <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>Dann referenzieren Sie diese Spalte wie jede andere:
measures:- name: "Promotion Sales" column: "promotion_sales" aggregator: "sum" format_string: "#,###.00"<Measure name="Promotion Sales" aggregator="sum" column="promotion_sales" formatString="#,###.00"/>Das <PhysicalSchema> sammelt alle Implementierungsdetails an einem Ort. Die <Measure>-Definition muss nicht wissen — oder sich kümmern —, dass promotion_sales berechnet wird. Jedes Mal, wenn Mondrian darauf zugreifen muss, ersetzt die Engine stattdessen den SQL-Ausdruck. Beliebige SQL-Ausdrücke werden unterstützt, einschließlich Subqueries, solange die zugrundeliegende Datenbank sie in einem Aggregatkontext auswerten kann.
Zusammengesetzte Schlüssel und Dimension-Links
Wenn der Schlüssel einer Dimension mehr als eine Spalte umfasst, drücken Sie das mit einem Multi-Spalten-<Key>-Block auf dem <Attribute> aus:
attributes:- name: "Quarter" key: - "the_year" - "quarter"<Attribute name="Quarter"> <Key> <Column name="the_year"/> <Column name="quarter"/> </Key></Attribute>Wenn es nur eine Schlüsselspalte gibt, sind <Key> und das keyColumn-Kurzschreib-Attribut äquivalent — verwenden Sie, was klarer ist. Sie müssen nameColumn nicht separat angeben, wenn es standardmäßig die letzte Spalte im zusammengesetzten Schlüssel ist.
Wenn eine Dimensionstabelle einen zusammengesetzten Primärschlüssel hat, muss das <ForeignKeyLink> in der <MeasureGroup> der Faktentabelle eine Fremdschlüsselspalte pro Spalte im zusammengesetzten Schlüssel bereitstellen. Siehe Physisches Schema für die vollständige Link-Referenz.