Estrutura do schema
Um exemplo completo
Aqui está um schema Mondrian-4 pequeno mas completo — um cubo, uma dimensão, duas medidas. O Saiku aceita schemas em YAML (o default) ou XML; escolha um formato abaixo e cada exemplo no site muda para casar.
schema: name: "Sales Example" metamodel_version: "4.0"physical_schema: tables: - name: "sales_fact" schema: "demo" key: - "sale_id" - name: "dim_customer" schema: "demo"shared_dimensions: Customer: table: "dim_customer" key: "Customer" attributes: - name: "Customer" key: - "customer_id" name_column: "customer_name" - name: "Gender" key: - "gender" has_hierarchy: false hierarchies: - name: "Customers" levels: - "Gender" - "Customer"cubes: Sales: dimensions: - source: "Customer" measure_groups: - name: "Sales" table: "sales_fact" measures: - name: "Unit Sales" column: "units" aggregator: "sum" format_string: "#,###" - name: "Revenue" column: "revenue" aggregator: "sum" format_string: "#,##0.00" dimension_links: - type: "foreign_key" dimension: "Customer" foreign_key_column: "customer_id"<Schema name="Sales Example" metamodelVersion="4.0">
<PhysicalSchema> <Table schema="demo" name="sales_fact"> <Key><Column name="sale_id"/></Key> </Table> <Table schema="demo" name="dim_customer"/> </PhysicalSchema>
<Dimension name="Customer" table="dim_customer" key="Customer"> <Attributes> <Attribute name="Customer"> <Key><Column name="customer_id"/></Key> <Name><Column name="customer_name"/></Name> </Attribute> <Attribute name="Gender" hasHierarchy="false"> <Key><Column name="gender"/></Key> </Attribute> </Attributes> <Hierarchies> <Hierarchy name="Customers"> <Level attribute="Gender"/> <Level attribute="Customer"/> </Hierarchy> </Hierarchies> </Dimension>
<Cube name="Sales"> <Dimensions> <Dimension source="Customer"/> </Dimensions> <MeasureGroups> <MeasureGroup name="Sales" table="sales_fact"> <Measures> <Measure name="Unit Sales" column="units" aggregator="sum" formatString="#,###"/> <Measure name="Revenue" column="revenue" aggregator="sum" formatString="#,##0.00"/> </Measures> <DimensionLinks> <ForeignKeyLink dimension="Customer" foreignKeyColumn="customer_id"/> </DimensionLinks> </MeasureGroup> </MeasureGroups> </Cube></Schema>Estrutura de um schema
A estrutura geral de um documento XML de schema Mondrian-4 parece com isso:
<Schema> <PhysicalSchema> <Table> <Key> <Column/> </Key> </Table> <Query> <SQL/> </Query> <InlineTable> <ColumnDefs> <ColumnDef/> </ColumnDefs> <Key/> <!-- same structure as Table/Key --> <Rows> <Row> <Value/> </Row> </Rows> </InlineTable> <Link/> </PhysicalSchema>
<Dimension/> <!-- shared; same structure as Dimension within a Cube -->
<Cube> <Dimensions> <Dimension> <Attributes> <Attribute> <Key> <Column/> </Key> <Name/> <!-- same structure as Key --> <Caption/> <!-- same structure as Key --> <OrderBy/> <!-- same structure as Key --> <Closure/> <MemberFormatter> <Script/> </MemberFormatter> <Property> <PropertyFormatter> <Script/> </PropertyFormatter> </Property> </Attribute> </Attributes> <Hierarchies> <Hierarchy> <Levels> <Level/> </Levels> </Hierarchy> </Hierarchies> </Dimension> </Dimensions>
<MeasureGroups> <MeasureGroup> <Measures> <Measure/> <MeasureRef/> </Measures> <DimensionLinks> <ForeignKeyLink/> <FactLink/> <ReferenceLink/> <CopyLink/> <NoLink/> </DimensionLinks> </MeasureGroup> </MeasureGroups>
<CalculatedMembers> <CalculatedMember> <Formula/> <CalculatedMemberProperty/> <CellFormatter> <Script/> </CellFormatter> </CalculatedMember> </CalculatedMembers>
<NamedSets> <NamedSet> <Formula/> </NamedSet> </NamedSets> </Cube>
<Role> <SchemaGrant> <CubeGrant> <DimensionGrant/> <HierarchyGrant> <MemberGrant/> </HierarchyGrant> </CubeGrant> </SchemaGrant> <Union> <RoleUsage/> </Union> </Role>
<UserDefinedFunction> <Script/> </UserDefinedFunction>
<Parameter/></Schema>A ordem dos elementos não é significativa. Por exemplo, um elemento <UserDefinedFunction> pode aparecer antes de um <Cube> e depois de outro — o Mondrian-4 parseia o documento posicionalmente mas trata a ordem de elementos como aviso. Esta é uma mudança significativa em relação ao Mondrian 3.x, onde a ordem dos elementos era estritamente exigida.
O conteúdo de cada elemento é descrito nas páginas seguintes desta seção e na referência de schema YAML.
O elemento Schema
<Schema> é o elemento raiz de cada schema Mondrian. Um exemplo mínimo:
schema: name: "Rock Sales" metamodel_version: "4.0"<Schema name="Rock Sales" metamodelVersion="4.0"></Schema>Atributos obrigatórios e comuns
| Atributo | Obrigatório | Default | Descrição |
|---|---|---|---|
name | sim | — | Nome de exibição para este schema |
metamodelVersion | não | auto-detectado | Versão do formato de schema. Use "4.0" para todos os schemas novos |
caption | não | — | Sobrescreve o nome de exibição visto por ferramentas cliente |
description | não | — | Descrição legível |
measuresCaption | não | — | Caption para a dimensão virtual [Measures] |
defaultRole | não | — | Role aplicada quando nenhuma role é especificada pela conexão |
quoteSql | não | true | Se o Mondrian quota identificadores SQL |
missingLink | não | warning | Comportamento quando um dimension link está faltando — warning, error ou ignore |
locales | não | — | Lista separada por vírgula de códigos de locale para captions localizados |
O atributo metamodelVersion diz ao Mondrian para qual versão o schema foi escrito. Se você omiti-lo, o Mondrian infere a versão do conteúdo do schema. Para todos os schemas novos, defina como "4.0".
Annotations
Os tipos de elemento principais — schema, cube, shared dimension, dimension, attribute, hierarchy, level, measure group, measure, calculated member — todos suportam annotations. Uma annotation deixa você anexar metadados key/value arbitrários a qualquer elemento de schema, o que é particularmente útil para ferramentas que precisam armazenar informação sem modificar a definição oficial de schema Mondrian.
Adicione um elemento <Annotations> como filho do elemento que você quer anotar, depois inclua um ou mais elementos <Annotation> dentro dele. Valores name de annotation devem ser únicos dentro do seu elemento pai. Se você está criando annotations para uma ferramenta específica, escolha nomes cuidadosamente para evitar conflitos com outras ferramentas.
schema: name: "Rock Sales" metamodel_version: "4.0"annotations: Author: "Fred Flintstone" Date: "10,000 BC"cubes: Sales: ...<Schema name="Rock Sales" metamodelVersion="4.0"> <Annotations> <Annotation name="Author">Fred Flintstone</Annotation> <Annotation name="Date">10,000 BC</Annotation> </Annotations> <Cube name="Sales"> ... </Cube></Schema>Nomes de annotation convencionais
Alguns nomes de annotation são usados por convenção entre ferramentas:
| Annotation | Elemento(s) | Descrição |
|---|---|---|
AnalyzerBusinessGroup | Level | Cria pastas na UI |
AnalyzerBusinessGroupDescription | Level | Descrição para essas pastas |
AnalyzerDateFormat | Level | Usado para filtros de data relativos |
AnalyzerHideInUI | Measure, CalculatedMember | Esconde o field da UI |
AnalyzerDisableDrillLinks | Cube | Desabilita links de drillthrough no cubo |
Ferramentas cientes de locale usam nomes qualificados com ponto por convenção — por exemplo caption.de_DE para um caption em alemão, description.fr_FR para uma descrição em francês. O schema demo FoodMart mostra este padrão no cubo Sales:
annotations: caption.de_DE: "Verkaufen" caption.fr_FR: "Ventes" description.fr_FR: "Cube des ventes"<Annotations> <Annotation name="caption.de_DE">Verkaufen</Annotation> <Annotation name="caption.fr_FR">Ventes</Annotation> <Annotation name="description.fr_FR">Cube des ventes</Annotation></Annotations>O modelo lógico
Os componentes mais importantes de um schema são cubos, medidas, atributos e dimensões:
- Um cubo é um conjunto de dados descrevendo um ou mais processos de negócio sobre um período de tempo particular.
- Um fato é o dado representando uma ocorrência de um processo — por exemplo, uma line item descrevendo a venda de um produto a um cliente, ou um período de pagamento para um funcionário.
- Uma medida é uma quantidade que você quer agregar dentro de um cubo — por exemplo, vendas em unidades de um produto, ou o salário de um funcionário.
- Um atributo é um valor, possuído por todo fato, pelo qual você pode dividir fatos em subsets. Você pode segmentar vendas de produto por cor, gênero do cliente e a loja onde o produto foi vendido; cor, gênero e loja são todos atributos.
- Uma dimensão é um agrupamento de atributos relacionados. Por exemplo, nome, gênero, CEP e cor dos olhos são atributos de uma dimensão Customer; cor, peso e fabricante são atributos de uma dimensão Product.
Aqui está um exemplo completo e funcional de um schema simples que amarra esses conceitos juntos:
schema: name: "Sales" metamodel_version: "4.0"physical_schema: tables: - name: "sales_fact_1997" - name: "customer" - name: "time_by_day"cubes: Sales: dimensions: - name: "Customer" table: "customer" key: "Id" attributes: - name: "Gender" - name: "Id" - name: "Time" table: "time_by_day" key: "Day" attributes: - name: "Year" - name: "Quarter" key: - "the_year" - "quarter" - name: "Month" key: - "the_year" - "month_of_year" - name: "Day" hierarchies: - name: "Yearly" has_all: false levels: - "Year" - "Quarter" - "Month" 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" calculated_members: - name: "Profit" dimension: "Measures" formula: "[Measures].[Store Sales] - [Measures].[Store Cost]" properties: - name: "FORMAT_STRING" value: "$#,##0.00"<Schema name="Sales" metamodelVersion="4.0"> <PhysicalSchema> <Table name="sales_fact_1997"/> <Table name="customer"/> <Table name="time_by_day"/> </PhysicalSchema>
<Cube name="Sales"> <Dimensions> <Dimension name="Customer" table="customer" key="Id"> <Attributes> <Attribute name="Gender" column="gender"/> <Attribute name="Id" column="customer_id"/> </Attributes> </Dimension>
<Dimension name="Time" table="time_by_day" key="Day"> <Attributes> <Attribute name="Year" column="the_year"/> <Attribute name="Quarter" column="quarter"> <Key> <Column name="the_year"/> <Column name="quarter"/> </Key> </Attribute> <Attribute name="Month" column="month_of_year"> <Key> <Column name="the_year"/> <Column name="month_of_year"/> </Key> </Attribute> <Attribute name="Day" column="time_id"/> </Attributes> <Hierarchies> <Hierarchy name="Yearly" hasAll="false"> <Level attribute="Year"/> <Level attribute="Quarter"/> <Level attribute="Month"/> </Hierarchy> </Hierarchies> </Dimension> </Dimensions>
<MeasureGroups> <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> </MeasureGroups>
<CalculatedMembers> <CalculatedMember name="Profit" dimension="Measures" formula="[Measures].[Store Sales] - [Measures].[Store Cost]"> <CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/> </CalculatedMember> </CalculatedMembers> </Cube></Schema>Este schema contém um único cubo chamado “Sales” com duas dimensões (“Customer” e “Time”), três medidas base e um calculated member (“Profit”). Você pode escrever uma consulta MDX contra ele imediatamente:
SELECT {[Measures].[Unit Sales], [Measures].[Store Sales]} ON COLUMNS, {Descendants([Time].[Yearly].[1997].[Q1])} ON ROWSFROM [Sales]WHERE [Customer].[Gender].[F]Que produz resultados como:
[Time] | [Measures].[Unit Sales] | [Measures].[Store Sales] |
|---|---|---|
[1997].[Q1] | 32,910 | $69,798.23 |
[1997].[Q1].[Jan] | 10,932 | $23,309.04 |
[1997].[Q1].[Feb] | 10,266 | $21,773.93 |
[1997].[Q1].[Mar] | 11,712 | $24,715.26 |
As seções a seguir explicam cada parte deste schema em detalhe.
Conteúdo adaptado do guia de schema do projeto Mondrian, disponível sob a Eclipse Public License v1.0 (http://www.eclipse.org/legal/epl-v10.html).