Przejdź do głównej zawartości

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

AtrybutWymaganyDomyślnieOpis
nametakNazwa wyświetlana w zapytaniach MDX
defaultMeasurenieMiara wybierana, gdy żadna nie jest określona w zapytaniu
captionnieNadpisanie nazwy wyświetlanej dla klientów
descriptionnieCzytelny opis
visiblenietrueCzy kostka pojawia się klientom
cachenietrueCzy Mondrian buforuje agregaty dla tej kostki
enablednietrueWyłączenie kostki ukrywa ją bez usuwania
enableScenariosniefalseWłą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"

Miary

Atrybuty miary

Każdy element <Measure> ma następujące atrybuty:

AtrybutWymaganyDomyślnieOpis
nametakNazwa wyświetlana w zapytaniach MDX
columntak*Kolumna w tabeli faktów. Użyj nazwy kolumny obliczanej, jeśli wartość jest wyprowadzana
aggregatortakFunkcja agregacji — zobacz niżej
formatStringnieJak wartość jest formatowana do wyświetlenia
datatypenieNumericJak wartości są przechowywane w cache Mondriana i zwracane przez XML for Analysis
captionnieNadpisanie nazwy wyświetlanej dla klientów
descriptionnieCzytelny opis
visiblenietrueCzy miara pojawia się klientom
formatternieW pełni kwalifikowana nazwa klasy niestandardowego formattera komórek
tablenieNadpisanie 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
sumSuma wszystkich wartości
countLiczba wierszy
minWartość minimalna
maxWartość maksymalna
avgŚrednia arytmetyczna
distinct-countLiczba distinct wartości
medianMediana (50. percentyl) — nieaddytywna
percentilePercentyl (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"

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:

WzorzecPrzykładowe wyjście
#,###32,910
#,###.##69,798.23
#,###.0069,798.23
$#,##0.00$69,798.23
Standarddomyś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"

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)"

Potem odwołuj się do tej kolumny jak do każdej innej:

measures:
- name: "Promotion Sales"
column: "promotion_sales"
aggregator: "sum"
format_string: "#,###.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"

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.