Kostki i miary
Element Cube
Kostka (<Cube>) to nazwana kolekcja wymiarów i miar.
Wymiary żyją wewnątrz elementu-pojemnika <Dimensions>. Z konwencji są deklarowane najpierw, po czym następują miary zorganizowane w grupy miar pod elementem-pojemnikiem <MeasureGroups>. Grupa miar to kolekcja miar dzielących tę samą tabelę faktów. Proste kostki mają dokładnie jedną grupę miar; bardziej zaawansowane kostki mogą mieć kilka — na przykład, gdy chcesz połączyć tabelę faktów transakcji z pre-agregowaną tabelą rollup.
Atrybuty kostki
| Atrybut | Wymagany | Domyślnie | Opis |
|---|---|---|---|
name | tak | — | Nazwa wyświetlana w zapytaniach MDX |
defaultMeasure | nie | — | Miara wybierana, gdy żadna nie jest określona w zapytaniu |
caption | nie | — | Nadpisanie nazwy wyświetlanej dla klientów |
description | nie | — | Czytelny opis |
visible | nie | true | Czy kostka pojawia się klientom |
cache | nie | true | Czy Mondrian buforuje agregaty dla tej kostki |
enabled | nie | true | Wyłączenie kostki ukrywa ją bez usuwania |
enableScenarios | nie | false | Włącza write-back / scenariusze what-if |
Jak tabele faktów i wymiary się łączą
Kostka [Sales] w przykładzie struktury schemy ma swoją grupę miar opartą na tabeli "sales_fact_1997". Każda tabela, do której odwołuje się logiczna schema, musi też pojawić się w bloku <PhysicalSchema>.
Tabela faktów zawiera kolumny, z których liczone są miary, plus kolumny kluczy obcych, które łączą się z tabelami wymiarów. Mondrian musi wiedzieć o wszystkich z nich:
- Każda kolumna miary pojawia się wewnątrz definicji
<Measure>. - Każda kolumna klucza obcego pojawia się wewnątrz elementu
<ForeignKeyLink>, łączącego grupę miar z odpowiednim wymiarem.
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>Miary
Atrybuty miary
Każdy element <Measure> ma następujące atrybuty:
| Atrybut | Wymagany | Domyślnie | Opis |
|---|---|---|---|
name | tak | — | Nazwa wyświetlana w zapytaniach MDX |
column | tak* | — | Kolumna w tabeli faktów. Użyj nazwy kolumny obliczanej, jeśli wartość jest wyprowadzana |
aggregator | tak | — | Funkcja agregacji — zobacz niżej |
formatString | nie | — | Jak wartość jest formatowana do wyświetlenia |
datatype | nie | Numeric | Jak wartości są przechowywane w cache Mondriana i zwracane przez XML for Analysis |
caption | nie | — | Nadpisanie nazwy wyświetlanej dla klientów |
description | nie | — | Czytelny opis |
visible | nie | true | Czy miara pojawia się klientom |
formatter | nie | — | W pełni kwalifikowana nazwa klasy niestandardowego formattera komórek |
table | nie | — | Nadpisanie tabeli grupy miar dla tej miary (zaawansowane) |
* column jest wymagane, chyba że wskażesz na kolumnę obliczaną zdefiniowaną w physical schema.
Typy agregatorów
Atrybut aggregator obsługuje następujące wartości:
| Wartość | Znaczenie |
|---|---|
sum | Suma wszystkich wartości |
count | Liczba wierszy |
min | Wartość minimalna |
max | Wartość maksymalna |
avg | Średnia arytmetyczna |
distinct-count | Liczba distinct wartości |
median | Mediana (50. percentyl) — nieaddytywna |
percentile | Percentyl (ustaw percentile="0..100", domyślnie 50) — nieaddytywny |
distinct-count ma ograniczenia, gdy kostka zawiera hierarchię parent-child.
Agregatory nieaddytywne: median i percentile
median i percentile to nieaddytywne agregatory liści: nie ma mediany median, więc nie mogą być składane z sub-agregatów. Saiku spycha je do SQL jako PERCENTILE_CONT(fraction) WITHIN GROUP (ORDER BY column) i oblicza na dokładnej granularności, o którą zapytałeś — są celowo wykluczone z podstawiania tabeli agregowanej i rollup-from-cache segmentu (więc nigdy nie dostaniesz złej „mediany median”).
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"/>Wymagają backendu Calcite (domyślnego dla Saiku) na bazie obsługującej PERCENTILE_CONT — PostgreSQL, Oracle, SQL Server, Snowflake, BigQuery, H2, DuckDB i podobne. Na backendzie bez tego zapytanie jest odrzucane z czytelnym błędem zamiast zwracania złej liczby. Kompromis jest celowy: tracisz pre-agregację / rollup cache dla tych miar w zamian za poprawną wartość na pytanej granularności.
Typy danych
Atrybut datatype kontroluje, jak wartości komórek są przechowywane w cache Mondriana i zwracane przez XML for Analysis. Akceptowane wartości to String, Integer, Numeric, Boolean, Date, Time i Timestamp. Wartość domyślna to Numeric, z wyjątkiem miar count i distinct-count, które domyślnie są Integer.
Format strings
Opcjonalny atrybut formatString kontroluje, jak wartość jest drukowana. Symbole , i . są wrażliwe na locale — jeśli chodzisz po włosku, #,###.00 może wyprodukować 48.123,45. Kilka typowych wzorców:
| Wzorzec | Przykładowe wyjście |
|---|---|
#,### | 32,910 |
#,###.## | 69,798.23 |
#,###.00 | 69,798.23 |
$#,##0.00 | $69,798.23 |
Standard | domyślny dla locale |
Dla zaawansowanych wzorców dat i formatów warunkowych zobacz referencję format strings MDX.
Caption
Miara może mieć atrybut caption zwracany zamiast jej name przez API klientów. Przydatne, gdy chcesz lokalizować nazwę miary lub wyświetlać znaki specjalne:
measures:- name: "Sum X" column: "sum_x" aggregator: "sum" caption: "Σ X"<Measure name="Sum X" column="sum_x" aggregator="sum" caption="Σ X"/>Kolumny obliczane w miarach
Zamiast wskazywać miarą surową kolumnę, możesz wyprowadzić wartość z wyrażenia SQL. Zdefiniuj kolumnę obliczaną w deklaracji <PhysicalSchema> tabeli faktów, a potem odwołaj się do niej po nazwie w <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>Potem odwołuj się do tej kolumny jak do każdej innej:
measures:- name: "Promotion Sales" column: "promotion_sales" aggregator: "sum" format_string: "#,###.00"<Measure name="Promotion Sales" aggregator="sum" column="promotion_sales" formatString="#,###.00"/><PhysicalSchema> gromadzi wszystkie szczegóły implementacji w jednym miejscu. Definicja <Measure> nie musi wiedzieć — ani się tym przejmować — że promotion_sales jest obliczana. Ilekroć Mondrian musi do niej sięgnąć, silnik podstawia zamiast tego wyrażenie SQL. Wspierane są dowolne wyrażenia SQL, w tym subzapytania, o ile bazowa baza danych potrafi je ewaluować w kontekście agregacji.
Klucze złożone i linki wymiarów
Gdy klucz wymiaru obejmuje więcej niż jedną kolumnę, wyrażasz to wielokolumnowym blokiem <Key> na <Attribute>:
attributes:- name: "Quarter" key: - "the_year" - "quarter"<Attribute name="Quarter"> <Key> <Column name="the_year"/> <Column name="quarter"/> </Key></Attribute>Jeśli jest tylko jedna kolumna klucza, <Key> i skrót atrybutu keyColumn są równoważne — używaj, co czytelniejsze. Nie musisz określać nameColumn osobno, gdy domyślnie przyjmuje ostatnią kolumnę klucza złożonego.
Gdy tabela wymiaru ma złożony klucz główny, <ForeignKeyLink> w <MeasureGroup> tabeli faktów musi dostarczyć jednej kolumny klucza obcego na każdą kolumnę klucza złożonego. Zobacz Physical schema dla pełnej referencji linków.