高级元数据设计

阅读(599) 标签: 高级元数据, 元数据,

通过语义层小节的学习,相信你已经对元数据文件的制作有了初步了解,其实,元数据中除了可以做一些常规的设置外,还可以做一些高级设置,比如外键、假表层函数、子表等。在上一小节中讲述了高级设置的使用,本节将主要针对这些高级元数据设计做进一步介绍。

外键

在元数据中可以自定义外键。与数据库中的概念相似,DQL中,表的外键字段指向另一张表主键,从而产生关联。

Foreign key name外键的名称可以直接编辑,设定时不允许与本表的其它外键名称相同,否则引用外键时会产生错误;如果当前外键是由单外键字段组成的,那么外键名称通常可以不使用,而是用外键字段来代替;如果当前外键是由多个外键字段组合成的,那么在引用外键指向表的字段时,只能使用Foreign key name,如上图中fk1fk2fk3均为外键名称,选中外键的外键名称是fk2

Referenced table name外键所指向的表名,当指向表的主键唯一且非外键时,那么这个表称为维表,简称如上图所示的维是:Product

Referenced field外键指向表的主键,如上图所示的引用字段是:ProductID,即ProductIDProduct表的主键。

Foreign key filed当前表的字段,和引用字段一一对应,如上图中所示Inventory表的外键字段是:ProductID

 

DQL中,外键字段和维字段的地位是完全一样的,可以把外键字段看成维字段

任何表的主键都可以视为维字段。如果某个表的主键是外键,那么这个主键的维即为外键指向的维;如果主键并非外键,那么这个主键的维就是它本身。对于非主键的字段,只有当它是外键时才是维字段,字段的维即为外键指向的维。

举例:

 

根据上图所示,ReturnedPmt表中的CustomerID字段指向Customer表的CustID字段,ReturnedPmt表与Customer表之间的数据关系为多对一的关系,其中的相关概念描述如下:

外键字段:ReturnedPmt表的CustomerID字段

维表:Customer

引用字段:Customer表的主键CustID字段

 

DQL的时候,可以像引用属性一样引用外键表的字段,比如:SELECT CustomerID.CustName,Date,Amount FROM ReturnedPmt,这里CustomerID.CustName引用的是CustomerID指向的Customer表的CustName字段。

 

知识点:

1) 对于单一字段形成的外键,在使用DQL时,可以用外键字段.外键表的字段名的方式来直接使用。

2) 对于多字段组成的外键,在使用DQL时,可以用外键名称.外键表的字段名的方式来直接使用。

3) 使用外键名称.外键表的字段名方式引用,既可用于多字段组成的外键,也可用于单一字段形成的外键情况。

假表层函数

在表中,参数为维的函数,且返回维与原维不同时,称为层函数

所谓假表,就是虚表中实际不存在的单字段表。在DQL中引入假表的概念,主要是为了解决两类问题

第一类通过定义维的各个层次结构,使用户能够在不同的粒度上观察数据。

通过假表与层函数的配合使用,我们能够定义类似于,年、年月、日期,这样的日期层次,从而使用户获得能够在不同时间粒度上观察数据的能力,同样的,我们也能够定义国家、省、市这样的结构,这取决于具体的业务规范,对于这种结构,在元数据编辑设计器中都可以一次定义,到处使用。

对于层次结构的定义,通常有几个维度就定义几张表(或假表)。比如上述的日期,一般就定义年、年月、日这样三张表。如果业务表中的日期字段存储的是日信息,就让它指向表,如果是年月信息,则指向年月表,依次类推。

在元数据定义中,当表间的外键关系设定之后,会根据外键设定中,产生的维信息,自动生成维的相关定义。然后可以在元数据的维和层页面里,定义这几个维度间的计算关系。

 

举例:

日期维中定义层函数,比如demo.glmd中通过DayYearYearMonth三张假表定义的日期层次:

 

 

 

说明:

1) 在层间计算式中用?表示源字段表

,表示Year维年字段的值可以由YearMonth维的年月字段通过表达式int(?/100)换算而来。

2) 层间计算式也可以说成从细向粗计算。比如“Day”维,只能从日算出年,不能从年算出日。

3) 目标维可分别通过多个源维进行换算。比如“Year”维,可能是从日聚集到年,也可能从年月聚集到年,因此,对于“Year”维,就要定义两个层间计算式,分别从“Day”表的日期和“YearMonth”表的年月计算而来。

4) 定义好这种结构之后,我们就可以在DQL中直接使用定义中的任何结构,如下例:

 

ReturnedPmt表中Date是个日期类型,在ReturnedPmt表的外键定义中,我们将ReturnedPmt表的字段DateDay表的字段Day建立外键关系,如下图:

这样,我们就可以在DQL中获得Date的年,月等信息了,如Date#Year,得到Date的年份,Date#YearMonth就得到了Date的年月

DQL: SELECT CustomerID,ID,Date,Date#YearMonth YearMonth,Date#Year Year,Amount,SellerID FROM ReturnedPmt

DQL: SELECT sum(Amount) Sum_Amount ON Year FROM ReturnedPmt by Date#Year

DQL: SELECT sum(Amount) Sum_Amount ON YearMonth FROM ReturnedPmt by Date#YearMonth

举例:

整数维中定义层函数,比如demo.glmd中通过ProvinceAreaCity表定义的层次:

DQL查询语句及结果:

DQL: SELECT CustID,CustName,Contact,ContactTitle,CityCode,CityCode#Province Province,CityCode#Area Area FROM Customer

DQL: SELECT count(CustID) CustNumber ON Area FROM Customer BY  CityCode#Area

DQL: SELECT count(CustID) CustNumber ON Province FROM Customer BY  CityCode#Province

第二类可以充当数据库视图,这种情况下,可以把假表视为表来使用,可以为其定义主键、外键等属性,在用户眼中和表是相同的。

知识点:

有了假表和层函数等概念,用户就可以按照希望的层次来观察数据,并且用户也可以更灵活的使用数据。

子表

在元数据中,当A表中有多个主键时,对部分主键字段添加外键后,在外键对应的主表中会自动将A表做为子表列出。通过添加子表,可以在主表中直接对子表字段进行汇总查询。如Customer,根据子表ReturnedPmt,可在查询Customer表字段的同时对ReturnedPmt表中的字段做汇总查询。

部分主键字段构成外键指向的表是主表;单字段主键的层函数的维表是主表;主表的主表是主表;同维表的主表是主表;主表的同维表是主表。

注意:要求主子表的主键按次序对应,主子表还要求按主键有序。子表外键必须关联主表主键字段。

通过在元数据中添加子表,可以使相关查询语句更为精简方便。例如:

 

CustIDCustomer表中的主键字段,ReturnedPmtCustomerIDID为主键字段,ReturnedPmtCustomerID外键指向Customer表的CustID

ReturnedPmt中外键设置如下:

 

Customer表中会自动添加子表ReturnedPmt,如下:

在主表中对子表字段的汇总查询与主表中字段的查询语法不同,如:

SELECT

  CustName ,

  Customer@ReturnedPmt.sum(Amount) Total

FROM

Customer by CustName

知识点:

1) 在主表中可对子表字段做汇总,子表外键必须指向主表主键字段。

2) 在主表中对子表字段的汇总查询语法:

T@S.f(F) 表示表T的子表S的广义字段F的聚合表达式,f为聚合函数count/avg/sum/max/min

伪字段

通过设定主键和外键,使得表与表相互关联。根据外键关联,可以获得Customer表以及与Customer表同维的VIPCustomer等表的信息。通过Employee表的外键关联,可以获得City表的信息,等等。

表的外键,同维表的外键,广义外键关联表的外键,通称为广义外键,另外,广义外键的层函数也是一种广义外键。

表的字段,同维表的字段,广义外键关联表的字段,广义字段的层函数通称为广义字段

用广义字段定义的表达式,通称为伪字段,按普通字段处理,但不作为外键。

 

通过在元数据中设定伪字段,可以命名一些常用的广义字段,可以使得对它们的查询语句更为精简方便。例如:

如果在ReturnedPmt中定义广义字段VIPCustomer_End结束如下:

伪字段可以相当于普通字段使用,如查询的DQL可以写成:SELECT VIPCustomer_End FROM ReturnedPmt,而不必写为SELECT CustomerID.EndTime#YearMonth FROM ReturnedPmt

 

注意:伪字段是用宏替换方式实现的,不能再使用层函数。