Structure du schema
Un exemple complet
Voici un schema Mondrian-4 petit mais complet — un cube, une dimension, deux mesures. Saiku accepte les schemas en YAML (par défaut) ou en XML ; choisissez un format ci-dessous et chaque exemple du site change pour correspondre.
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>Structure d’un schema
La structure globale d’un document XML de schema Mondrian-4 ressemble à ceci :
<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>L’ordre des éléments n’est pas significatif. Par exemple, un élément <UserDefinedFunction> peut apparaître avant un <Cube> et après un autre — Mondrian-4 parse le document positionnellement mais traite l’ordre des éléments comme indicatif. C’est un changement significatif par rapport à Mondrian 3.x, où l’ordre des éléments était strictement requis.
Le contenu de chaque élément est décrit dans les pages suivantes de cette section et dans la référence de schema YAML.
L’élément Schema
<Schema> est l’élément racine de chaque schema Mondrian. Un exemple minimal :
schema: name: "Rock Sales" metamodel_version: "4.0"<Schema name="Rock Sales" metamodelVersion="4.0"></Schema>Attributs requis et courants
| Attribut | Requis | Défaut | Description |
|---|---|---|---|
name | oui | — | Nom d’affichage pour ce schema |
metamodelVersion | non | auto-détecté | Version du format de schema. Utilisez "4.0" pour tous les nouveaux schemas |
caption | non | — | Substituer le nom d’affichage vu par les outils clients |
description | non | — | Description lisible par humain |
measuresCaption | non | — | Légende pour la dimension virtuelle [Measures] |
defaultRole | non | — | Rôle appliqué quand aucun rôle n’est spécifié par la connexion |
quoteSql | non | true | Si Mondrian échappe les identifiants SQL |
missingLink | non | warning | Comportement quand un lien de dimension manque — warning, error ou ignore |
locales | non | — | Liste séparée par virgules de codes de locale pour les légendes localisées |
L’attribut metamodelVersion indique à Mondrian pour quelle version le schema a été écrit. Si vous l’omettez, Mondrian infère la version à partir du contenu du schema. Pour tous les nouveaux schemas, définissez-le à "4.0".
Annotations
Les principaux types d’éléments — schema, cube, dimension partagée, dimension, attribut, hiérarchie, niveau, groupe de mesures, mesure, membre calculé — prennent tous en charge les annotations. Une annotation vous permet d’attacher des métadonnées clé/valeur arbitraires à n’importe quel élément de schema, ce qui est particulièrement utile pour les outils qui doivent stocker des informations sans modifier la définition officielle du schema Mondrian.
Ajoutez un élément <Annotations> comme enfant de l’élément que vous voulez annoter, puis incluez un ou plusieurs éléments <Annotation> à l’intérieur. Les valeurs name d’annotation doivent être uniques au sein de leur élément parent. Si vous créez des annotations pour un outil spécifique, choisissez les noms avec soin pour éviter les collisions avec d’autres outils.
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>Noms d’annotation conventionnels
Certains noms d’annotation sont utilisés par convention entre les outils :
| Annotation | Élément(s) | Description |
|---|---|---|
AnalyzerBusinessGroup | Level | Crée des dossiers dans l’UI |
AnalyzerBusinessGroupDescription | Level | Description pour ces dossiers |
AnalyzerDateFormat | Level | Utilisé pour les filtres de date relative |
AnalyzerHideInUI | Measure, CalculatedMember | Masque le champ de l’UI |
AnalyzerDisableDrillLinks | Cube | Désactive les liens de drillthrough sur le cube |
Les outils sensibles à la locale utilisent des noms à qualification par point par convention — par exemple caption.de_DE pour une légende allemande, description.fr_FR pour une description française. Le schema de démo FoodMart montre ce pattern sur le cube 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>Le modèle logique
Les composants les plus importants d’un schema sont les cubes, mesures, attributs et dimensions :
- Un cube est un jeu de données décrivant un ou plusieurs processus métier sur une période de temps particulière.
- Un fait est la donnée représentant une occurrence d’un processus — par exemple, une ligne décrivant la vente d’un produit à un client, ou une période de paie pour un employé.
- Une mesure est une quantité que vous voulez agréger au sein d’un cube — par exemple, les ventes unitaires d’un produit, ou le salaire d’un employé.
- Un attribut est une valeur, possédée par chaque fait, par laquelle vous pouvez diviser les faits en sous-ensembles. Vous pourriez découper les ventes de produits par couleur, genre du client, et magasin où le produit a été vendu ; couleur, genre et magasin sont tous des attributs.
- Une dimension est un regroupement d’attributs liés. Par exemple, nom, genre, code postal et couleur des yeux sont des attributs d’une dimension Customer ; couleur, poids et fabricant sont des attributs d’une dimension Product.
Voici un exemple complet et fonctionnel d’un schema simple qui lie ces concepts ensemble :
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>Ce schema contient un seul cube appelé « Sales » avec deux dimensions (« Customer » et « Time »), trois mesures de base et un membre calculé (« Profit »). Vous pouvez écrire une requête MDX dessus immédiatement :
SELECT {[Measures].[Unit Sales], [Measures].[Store Sales]} ON COLUMNS, {Descendants([Time].[Yearly].[1997].[Q1])} ON ROWSFROM [Sales]WHERE [Customer].[Gender].[F]Ce qui produit des résultats comme :
[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 $ |
Les sections qui suivent expliquent chaque partie de ce schema en détail.
Contenu adapté du guide de schema du projet Mondrian, disponible sous l’Eclipse Public License v1.0 (http://www.eclipse.org/legal/epl-v10.html).