Cube DSL
Contents
Copyright Notice
All rights are reserved by Compex Systemhaus GmbH. In particular, duplications, translations, microfilming, saving and processing in electronic systems are protected by copyright. Use of this manual is only authorized with the permission of Compex Systemhaus GmbH. Infringements of the law shall be punished in accordance with civil and penal laws. We have taken utmost care in putting together texts and images. Nevertheless, the possibility of errors cannot be completely ruled out. The Figures and information in this manual are only given as approximations unless expressly indicated as binding. Amendments to the manual due to amendments to the standard software remain reserved. Please note that the latest amendments to the manual can be accessed through our helpdesk at any time. The contractually agreed regulations of the licensing and maintenance of the standard software shall apply with regard to liability for any errors in the documentation. Guarantees, particularly guarantees of quality or durability can only be assumed for the manual insofar as its quality or durability are expressly stipulated as guaranteed. If you would like to make a suggestion, the Compex Team would be very pleased to hear from you.
(c) 2016-2024 Compex Systemhaus GmbH
Introduction
MDX and OLAP Cube
MDX(MultiDimensional eXpressions) is a query language for OLAP (OnLine Analytical Processing) databases, much like SQL is a query language for relational databases. It is also a calculation language, with syntax similar to spreadsheet formulas.
SQL was designed to query three-dimensional data structures, called tables, where data are organized in rows, columns and values. In OLAP, data are organized around multiple measures, dimensions, hierarchies, and levels.
Similar to the way tables and columns are central to SQL, dimensions, hierarchies, and levels are the centerpieces of MDX. In this way, business models are mapped to language-specific concepts (e.g. a list of countries will be mapped as an MDX dimension). Measures in MDX are a special case of dimensions and they hold numeric values. The concrete value of a dimension (e.g. Paris) is a member of the dimension and is similar to the value contained in an SQL table.
An OLAP Cube is a collection of dimensions indexing a list of measures. For example, a geometrical cube can have three dimensions, whereas a logistical "cube" can have many more dimensions.
More information can be found at:
http://en.wikipedia.org/wiki/MultiDimensional_eXpressions
http://en.wikipedia.org/wiki/OLAP_cube
Mondrian
Mondrian is an open source OLAP server, written in Java. It supports the MDX query language and XML for analysis and olap4j interface specifications. It reads from SQL and other data sources and aggregates data in a memory cache.
Mondrian is used for:
- high performance, interactive analysis of large or small volumes of information
- dimensional exploration of data, for example analysis of sales by product line, by region, by time period
- parsing the MDX language into SQL to retrieve answers to dimensional queries
- high-speed queries through the use of aggregate tables in the RDBMS (Relational DataBase Management System)
- advanced calculations using the calculation expressions of the MDX language
Schema
A schema defines a multi-dimensional database. It contains a logical model, consisting of cubes, hierarchies, and members, and a mapping of this model onto a physical model.
The logical model consists of the constructs used to write queries in the MDX language: cubes, dimensions, hierarchies, levels, and members.
The physical model is the source of the data which is presented through the logical model. It is typically a star schema, which is a set of tables in a relational database.
Schema file
The schema file is an XML file that defines the dimensions and measures for the cube and maps them to the database tables. The product and location dimensions contain several levels each. Each level defines its corresponding field in the database table. The different values of the field become the members of the level.
Note: The levels must be specified in the intended order of breakdown.
- The structure of the XML document is as follows:
<Schema> <Cube> <Table> <AggName> aggElements <AggPattern> aggElements <Dimension> <Hierarchy> relation <Closure/> <Level> <KeyExpression> <SQL/> <NameExpression> <SQL/> <CaptionExpression> <SQL/> <OrdinalExpression> <SQL/> <ParentExpression> <SQL/> <Property> <PropertyExpression> <SQL/> <DimensionUsage> <Measure> <MeasureExpression> <SQL/> <CalculatedMemberProperty/> <CalculatedMember> <Formula/> <CalculatedMemberProperty/> <NamedSet> <Formula/> <VirtualCube> <CubeUsages> <CubeUsage> <VirtualCubeDimension> <VirtualCubeMeasure> <Role> <SchemaGrant> <CubeGrant> <DimensionGrant> <HierarchyGrant> <MemberGrant/> <Union> <RoleUsage/> <UserDefinedFunction/> <Parameter/>
- relation ::=
<Table> <SQL/> <View> <SQL/> <InlineTable> <ColumnDefs> <ColumnDef> <Rows> <Row> <Value> <Join> relation
- aggElement ::=
<AggExclude> <AggFactCount> <AggIgnoreColumn> <AggForeignKey> <AggMeasure> <AggLevel>
Logical elements
Element | Description |
---|---|
<Cube> | A collection of dimensions and measures, all centered on a fact table. |
<VirtualCube> | A cube defined by combining the dimensions and measures of one or more cubes. A measure originating from another cube can be a <CalculatedMember>. |
<CubeUsages> | Base cubes that are imported into a virtual cube |
<CubeUsage> | Usage of a base cube by a virtual cube. |
<VirtualCubeDimension> | Usage of a dimension by a virtual cube. |
<VirtualCubeMeasure> | Usage of a measure by a virtual cube. |
<Dimension> | Dimension |
<DimensionUsage> | Usage of a shared dimension by a cube. |
<Hierarchy> | Hierarchy |
<Level> | Level of a hierarchy |
<KeyExpression> | SQL expression used as key of the level, in lieu of a column. |
<NameExpression> | SQL expression used to compute the name of a member, in lieu of Level.nameColumn. |
<CaptionExpression> | SQL expression used to compute the caption of a member, in lieu of Level.captionColumn. |
<OrdinalExpression> | SQL expression used to sort members of a level, in lieu of Level.ordinalColumn. |
<ParentExpression> | SQL expression used to compute a measure, in lieu of Level.parentColumn. |
<Property> | Member property. The definition is against a hierarchy or level, but the property will be available to all members. |
<Measure> | Measure |
<CalculatedMember> | A member whose value is derived using a formula, defined as part of a cube. |
<NamedSet> | A set whose value is derived using a formula, defined as part of a cube. |
Physical elements
Element | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Aggregate tables
Access control
Extensions
Miscellaneous
CubesA cube is a named collection of measures and dimensions. The one thing the measures and dimensions have in common is the fact table. The fact table holds the columns from which measures are calculated, and contains references to the tables which hold the dimensions. ► Syntax: <Cube name="{cube name}">
<Table name="{table name}"/>
...
</Cube>
<Table schema="{schema name}" name="{table name}"/>
You can also use the
MeasuresEach measure has a name, a column in the fact table, and an aggregator. ► Syntax: <Measure name="{measure name}" column="{column name}"
aggregator="{aggregator name}" datatype="{type name}"
formatString="{format}"/>
<Measure name="Store Sales" column="store_sales" aggregator="sum"
datatype="Numeric" formatString="#,###.00"/>
The optional datatype attribute specifies how cell values are represented in Mondrian's cache, and how they are returned via XML for Analysis. The datatype attribute can have values
An optional formatString attribute specifies how the value is to be printed. The ',' and '.' symbols are locale-sensitive. A measure can have a caption attribute to be returned by the Member.getCaption() method instead of the name. Defining a specific caption does make sense if special letters (e.g. Σ or Π) are to be displayed: ► Example: <Measure name="Sum X" column="sum_x" aggregator="sum" caption="Σ X"/>
Dimensions, hierarchies, levelsA member is a point within a dimension determined by a particular set of attribute values. The gender hierarchy has the two members 'M' and 'F'. 'San Francisco', 'California' and 'USA' are all members of the store hierarchy. A hierarchy is a set of members organized into a structure for convenient analysis. For example, the store hierarchy consists of the store name, city, state, and nation. The hierarchy allows you to form intermediate sub-totals: the sub-total for a state is the sum of the sub-totals of all of the cities in that state, each of which is the sum of the sub-totals of the stores in that city. A level is a collection of members which have the same distance from the root of the hierarchy. A dimension is a collection of hierarchies which discriminate on the same fact table attribute (say, the day that a sale occurred). ► Syntax: <Dimension name="{dimension name}" foreignKey="{key name}">
<Hierarchy hasAll="true" primaryKey="{key name}">
<Table name="{table name}"/>
<Level name="{level name}" column="{column name}"
uniqueMembers="true"/>
</Hierarchy>
</Dimension>
<Dimension name="Gender" foreignKey="customer_id">
<Hierarchy hasAll="true" primaryKey="customer_id">
<Table name="customer"/>
<Level name="Gender" column="gender" uniqueMembers="true"/>
</Hierarchy>
</Dimension>
This dimension consists of a single hierarchy, which consists of a single level called Gender. The values for the dimension come from the gender column in the customer table. The "gender" column contains two values, 'F' and 'M', so the Gender dimension contains the members For any given sale, the gender dimension is the gender of the customer who made that purchase. This is expressed by joining from the fact table "sales_fact_1997.customer_id" to the dimension table "customer.customer_id".
► Syntax: <Table schema="{schema name}" name="{table name}"/>
You can also use the
"ALL" memberBy default, every hierarchy contains a top level called If the
Time dimensionsTime dimensions based on year/month/week/day are coded differently in the Mondrian schema due to the MDX time related functions :
Time dimensions have
<Dimension name="Time" type="TimeDimension">
<Hierarchy hasAll="true" allMemberName="All Periods" primaryKey="dateid">
<Table name="datehierarchy"/>
<Level name="Year" column="year" uniqueMembers="true"
levelType="TimeYears" type="Numeric"/>
<Level name="Quarter" column="quarter" uniqueMembers="false"
levelType="TimeQuarters"/>
<Level name="Month" column="month" uniqueMembers="false"
ordinalColumn="month" nameColumn="month_name" levelType="TimeMonths"
type="Numeric"/>
<Level name="Week" column="week_in_month" uniqueMembers="false"
levelType="TimeWeeks"/>
<Level name="Day" column="day_in_month" uniqueMembers="false"
ordinalColumn="day_in_month" nameColumn="day_name"
levelType="TimeDays" type="Numeric"/>
</Hierarchy>
</Dimension>
Multiple hierarchiesA dimension can contain more than one hierarchy. By default, a hierarchy has the same name as its dimension. A dimension can contain more than one hierarchy. By default, a hierarchy has the same name as its dimension. When generating the SQL for a join, Mondrian needs to know which column to join to. If you are joining to a join, then you need to tell it which of the tables in the join that column belongs to (usually it will be the first table in the join). Because shared dimensions don't belong to a cube, you have to give them an explicit table (or other data source). When you use them in a particular cube, you specify the foreign key. This example shows the Store Type dimension being joined to the Sales cube using thesales_fact_1997.store_id foreign key, and to the Warehouse cube using the warehouse.warehouse_store_id foreign key:
<Dimension name="Store Type">
<Hierarchy hasAll="true" primaryKey="store_id">
<Table name="store"/>
<Level name="Store Type" column="store_type"
uniqueMembers="true"/>
</Hierarchy>
</Dimension>
<Cube name="Sales">
<Table name="sales_fact_1997"/>
...
<DimensionUsage name="Store Type" source="Store Type"
foreignKey="store_id"/>
</Cube>
<Cube name="Warehouse">
<Table name="warehouse"/>
...
<DimensionUsage name="Store Type" source="Store Type"
foreignKey="warehouse_store_id"/>
</Cube>
Snowflake schema (Join)A dimension can be based upon more than one table, provided that there is a well-defined path to join these tables to the fact table. This kind of dimension is known as a snowflake, and is defined using the ► Example: <Cube name="Sales">
...
<Dimension name="Product" foreignKey="product_id">
<Hierarchy hasAll="true" primaryKey="product_id"
primaryKeyTable="product">
<Join leftKey="product_class_key" rightAlias="product_class"
rightKey="product_class_id">
<Table name="product"/>
<Join leftKey="product_type_id" rightKey="product_type_id">
<Table name="product_class"/>
<Table name="product_type"/>
</Join>
</Join>
<!-- Level declarations ... -->
</Hierarchy>
</Dimension>
</Cube>
We require a The arrangement of the tables seems complex; the simple rule of thumb is to order the tables by the number of rows they contain. The Note that the outer Cube DSLA Cube can be considered a multi-dimensional generalization of a two- or three-dimensional spreadsheet. Each cell of the cube holds a number that represents some measure of the business, such as sales, profits, expenses, budget and forecast. The elements of a dimension can be organized as a hierarchy, a set of parent-child relationships, typically where a parent member summarizes its children. CubeDSL generates the schema file. The main semantic elements of the CubeDSL are:
KeywordsThe CubeDSL generates a Schema File in XML file type. It should be defined with the following keywords in *.cube file: package, schema► Syntax: package <package name> schema <schema name>{
...
}
► Example: package local.test4doku.cubes schema TEST{
...
}
It generates the following schema code in xml file: <Schema name="TEST">
...
</Schema>
dimension, hierarchy, level, property► Syntax: dimension <dimension name> {
hierarchy [hierarchy name] [has All] [allMemberName=<all member name>]
[defaultMember=<default member>]{
entity <entity name> key=<key name> {
level <level name> column=<column name> [uniqueMembers];
...
}
}
...
}
Notes:
dimension CustomerGenders {
hierarchy allMemberName="All Genders" defaultMember="[All Genders]"{
entity Tcustomer key=cus_id {
level Gender column=gender ;
}
}
}
It generates the following schema code in xml file: <Dimension name="CustomerGenders">
<Hierarchy hasAll="false" allMemberName="All Genders" defaultMember="[All
Genders]" primaryKey="CUS_ID">
<Table name="TCUSTOMER" />
<Level name="Gender" column="GENDER" uniqueMembers="false"
type="String"/>
</Hierarchy>
</Dimension>
join► Syntax: dimension <dimension name> {
hierarchy [<hierarchy name>] [has All] [allMemberName=<all member name>]
[defaultMember=<default member>] {
entity <entity name> key=<primarykey name> {
level <level name> column=<column name> [uniqueMembers];
...
entity <entity name> [key=<key name>] {
over <leftkey name>;
level <level name> column=<column name> [uniqueMembers];
...
}
}
}
...
}
dimension ProductTypes {
hierarchy hasAll {
entity Tproduct key=pro_id {
level proName column=pro_name uniqueMembers;
entity Tproduct_type key=pro_type_id {
over type;
level proTypeName column=pro_type_name uniqueMembers;
}
}
}
}
It generates the following schema code in xml file: <Dimension name="ProductTypes">
<Hierarchy hasAll="true" primaryKey="PRO_ID" primaryKeyTable="TPRODUCT">
<Join leftKey="TYPE_ID" rightKey="PRO_TYPE_ID">
<Table name="TPRODUCT" />
<Table name="TPRODUCT_TYPE"/>
</Join>
<Level name="proTypeName" table="TPRODUCT_TYPE"
column="PRO_TYPE_NAME" uniqueMembers="true" type="String"/>
<Level name="proName" table="TPRODUCT" column="PRO_NAME"
uniqueMembers="true" type="String"/>
</Hierarchy>
</Dimension>
Notes:
typeTime► Syntax: dimension <dimension name> typeTime {
hierarchy <hierarchy name> [has All] [allMemberName=<all member name>]
[defaultMember=<default member>]{
entity <entity name> key=<key name> {
level <level name> column=<column name> [uniqueMembers]
levelType=<type name>;
...
}
}
...
}
Note:
dimension TimeTheDate typeTime {
hierarchy {
entity Ttime_by_day key=the_date {
level Year column=the_year uniqueMembers levelType=TimeYears;
level Quarter column=quarter levelType=TimeQuarters;
level Month column=month_of_year levelType=TimeMonths;
}
}
}
It generates the following schema code in xml file: <Dimension name="TimeTheDate" type="TimeDimension">
<Hierarchy hasAll="false" primaryKey="THE_DATE">
<Table name="TTIME_BY_DAY" schema=""/>
<Level name="Year" column="THE_YEAR" uniqueMembers="true"
levelType="TimeYears" type="String"/>
<Level name="Quarter" column="QUARTER" uniqueMembers="false"
levelType="TimeQuarters" type="String"/>
<Level name="Month" column="MONTH_OF_YEAR" uniqueMembers="false"
levelType="TimeMonths" type="Integer"/>
</Hierarchy>
</Dimension>
property► Syntax: dimension <dimension name> {
hierarchy <hierarchy name> [has All] [allMemberName=<all member name>]
[defaultMember=<default member>]{
entity <entity name> key=<key name> {
level <level name> column=<column name> [uniqueMembers]{
property <property name> column=<column name>
[type=<type name>];
}
...
}
}
...
}
Note:
dimension ProductTypes {
hierarchy {
entity TproductType key= pro_type_id {
level proTypeId column= pro_type_id uniqueMembers {
property proTypeName column= pro_type_name type=String;
}
}
}
}
It generates the following schema code in xml file: <Dimension name="ProductTypes">
<Hierarchy hasAll="false" primaryKey="PRO_TYPE_ID">
<Table name="TPRODUCT_TYPE" schema=""/>
<Level name="proTypeId" column="PRO_TYPE_ID" uniqueMembers="true"
type="Integer">
<Property name="proTypeName" column="PRO_TYPE_NAME"
type="String" />
</Level>
</Hierarchy>
</Dimension>
cube, dimensionUsage, measure► Syntax: cube <cube name> [defaultMeasure <measure name>]{
entity <entity name> [key=<key name>]{
dimensionUsage <dimension name> over <key name>;
...
measure <measure name> <aggregator name> column=<column name>
[notVisible];
...
}
...
}
Note:
► Example: dimension ProductTypes {
hierarchy {
entity TproductType key= pro_type_id {
level proTypeId column= pro_type_id uniqueMembers {
property proTypeName column= pro_type_name type=String;
}
}
}
}
It generates the following schema code in xml file: <Dimension name="ProductTypes">
<Hierarchy hasAll="false" primaryKey="PRO_TYPE_ID">
<Table name="TPRODUCT_TYPE" schema=""/>
<Level name="proTypeId" column="PRO_TYPE_ID" uniqueMembers="true"
type="Integer">
<Property name="proTypeName" column="PRO_TYPE_NAME"
type="String" />
</Level>
</Hierarchy>
</Dimension>
|