高级元数据设计

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

通过语义层小节的学习,相信已经对元数据文件的制作有了初步了解,其实,元数据中除了可以做一些常规的设置外,还可以做一些高级设置,比如智能识别外键分表等,本节将主要针对这些高级元数据设计做进一步介绍。

智能识别外键

有些表间存在着逻辑上的外键关系,但是程序员设计数据库的时候并没有实际定义,因此,从数据库读入物理表结构的时候,会缺少这些外键定义。

智能识别外键的功能,就是根据选中的主表(维表),智能地查找其它表中是否有字段数据类型、长度、值和选中主表的主键完全一致,且数据符合外键规范,没有定义外键的情况,如果有则列出来,用户根据实际情况进行选择确认,一旦被确认的,会自动加到外键定义中。

在连接数据源后,在菜单中可以选择执行智能识别外键

在窗口中选择主表,点击确定后,系统会智能匹配所选表的结构数据,从系统中选择出和所选表相匹配,且未设定外键的对象出来。

对系统自动识别出来的关系,可以进行人工审查,并进行干预和调整,以便最大限度的保证模型的正确性。点击确认可以确认使用一条映射,点击删除则不使用,调整后如下:

点击确认后,模型中会自动生成外键关系

知识点:

1) 对于设计规范的数据库,可直接使用导出的模型结构,建模工作量可以忽略不计。

2) 外键字段与引用表的主键字段,应该具有相同的数据类型以及数据宽度、数据精度等,这样才可以智能识别,否则只能手工指定。

假表层函数

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

 

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

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

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

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

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

举例:

说明:

1) 在层间计算式中用?表示源字段表,表示“”维年字段的值可以由“年月”维的年月字段通过表达式int(?/100)换算而来。

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

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

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

在回款单表中回款日期是个日期类型,在回款单表的外键定义中,我们将回款单表的字段回款日期与日期表的字段日期建立外键关系,如下图:

 

这样,我们就可以在DQL中获得回款日期的年,月等信息了,如回款日期#年,得到回款日期的年份,回款日期#年月就得到了回款日期的年月

举例:

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

知识点:

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

维名

在讲外键的时候,我们说到,表的外键必将指向一个维。因此,只要为某些字段定义了外键,DQL就会自动把外键最终指向的.关键字段作为维存储在维定义里,一般情况不需要单独去定义

但是,表.关键字段这么长的名称作为维名很不方便,写DQL的时候显得太长,所以,可以在维定义里修改维名,使之更短更容易记忆。

比如DQL

-  SELECT 客户ID.客户名称,回款单.SUM(金额)

-  ON 客户.客户ID

-  FROM 回款单BY 客户ID

如上图定义了维名后,就可以写成

-  SELECT 客户ID.客户名称,回款单.SUM(金额)

-  ON 客户

-  FROM 回款单BY 客户ID

基础表与汇总表

很多业务系统的数据量巨大,直接从基础业务表进行查询汇总会非常慢,因此数据库里往往存在一些已经造好的历史汇总表。

 

对于用户来说,当他进行查询时需要知道有哪些历史汇总表存在的难度比较大,尤其是当存在多级汇总表的时候,要能够恰当选择其中一个汇总表难度更大了。

 

因此如果某张表是历史汇总表,那么可以在这张表上定义基础表属性,定义其从哪一张基础表汇总而来。当用户的DQL基于基础表进行分组汇总时,DQL元数据层会智能寻找汇总表,看哪个汇总表和DQL的汇总级别最接近,然后智能地把DQL解析成从这个汇总表查出。汇总表和基础表是相对的概念,表A是表B的基础表,则表B是表A的汇总表;在定义了基础表属性后,这个历史汇总表会自动加入其基础表的汇总表中

举例来说,有一个基于日期的基础表,数据库中存在按月汇总、按年汇总的两张汇总表。当用户的查询DQL是聚合到季这一层时,系统会自动从月汇总表里查出;当聚合到年时,会自动从年汇总表里查出。

汇总表和基础表之间是多对多的关系。

举例:

现有支付单,支付月汇总两张表。支付月汇总表数据是从“支付单”表汇总而来,那么可以定义如下:

上图中的字段名是“支付月汇总”表的字段名,广义外键或表达式是指基于基础表的计算表达式,可以把上述定义理解为这样的DQL

-  SELECT

-   支付单.SUM(支付金额) 支付总额

-   ON 年月

-  FROM

-  支付单

-  BY 支付日期#年月

此时,如果需要基于支付单,进行年汇总,即下面的DQL

-  SELECT

-    支付单.SUM(支付金额) 支付总额

-    ON

-  FROM

-    支付单

-  BY 支付日期#

DQL元数据层会自动从已有的支付月汇总的数据中进一步汇总,即执行以下SQLSELECT INT(T1_1_1.年月/100) ,SUM(T1_1_1.支付总额) 支付总额 FROM 支付供应商月汇总 T1_1_1 GROUP BY INT(T1_1_1.年月/100),通过对基础表的设定,可以充分利用事先汇总完成的数据,以提高效率。

 

知识点:

1) 定义基础表功能,可以简化业务视图,降低用户对业务系统的学习难度,用户只需要记住基础表即可,不需要记忆汇总表。

2) 在定义基础表功能时,其中的字段名,必须包括主表的所有关键字段,如上图中的年月为支付月汇总主键,必须定义广义外键或表达式。计算字段可以全写,或只写一个。

3) 在上述定义中,我们定义年月的广义外键或表达式为支付日期#年月,如果层函数或者假表中出现错误或异常,也会导致系统不能自动找到汇总表。

4) 当基础表中有多个汇总表可用时,会通过对表中记录数的设置选择记录数少的使用,记录数相同或都为空时取第一个符合条件的汇总表。

 

子表

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

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

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

客户ID客户表中的主键字段,回款单中客户ID和回款单ID为主键字段,回款单的客户ID外键指向客户表的客户ID

回款单中外键设置如下:

客户表中会自动添加子表回款单,子表外键为对应主表主键的外键字段,如下:

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

-  SELECT

-   客户.名称 客户名称

-   客户.# 省份

-   客户@回款单.sum(金额) 回款金额

-  FROM

- 

知识点:

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

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

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

分表

在数据库中,有时,数据会分开存储在多个数据结构完全相同的表中,如分年度存储的销售数据、分部门存储的员工资料、分地区存储的客户信息等等。在数据查询与分析时,往往需要将这些表中的数据联合起来,比如查询历年销售数据、查询所有部门的员工资料或者查询全部客户信息等,此时,可以通过在DQL元数据文件中,设定分表

建立分表,可以直接点击增加分表按钮执行,也可以在菜单栏中选择编辑>增加分表,或者使用快捷键Ctrl+B

选择后,可以选择组成分表的各个物理表来源:

物理表可以在当前数据源的数据库表中选择,也可以在元数据表中选择,选择的物理表必须具有相同的数据结构:

选定分表的数据表来源后,可以为分表命名,字段定义会自动生成:

与元数据中的普通表定义不同,分表中还需定义分区属性,根据指定的分段字段,设定分表中的分段列表。分段字段需是维字段,而且,分表中的各个分区表的分段字段的值需要是严格单调的,这样才可以根据分段字段的设定,在查询时,合理将分表拆分。设定分段列表时,每个物理表作为一个分区,由小到大设定段界,设定段界的值将包含在分区内,如下面的设置:

图中的设定,相当于设定分区订单2011 中,分段字段订单编号<=10554;最后的一个分区订单2012 的段界可以为空白,此时最后一个分区无上限。

在查询时,分表的使用和元数据中其它表的DQL语法相同,比如:

SELECT * FROM订单总表

DQL元数据层会自动将分表中的各个物理表联合访问,相当于执行:

SELECT T1_1.订单编号 订单ID FROM (SELECT * from 订单2011 UNION ALL SELECT * from 订单2012) T1_1

那么,分表中,分区的设定有什么意义呢?在执行有条件的查询时,有时候查询的数据并非来源于分表中所有的物理表,此时如果筛选条件是分段字段,在DQL元数据文件中就可以根据分段列表中的段界设定,寻找到数据来源于哪个或者哪些物理表,从数据查询时只访问相关的数据库。

如:SELECT * FROM 订单总表 WHERE 订单编号<10250

DQL会解析为:SELECT T1_1.订单ID 订单ID FROM (SELECT * from 订单2011) T1_1 WHERE T1_1.订单ID<10250

如:SELECT * FROM 订单总表 WHERE 订单ID in (10620,10630,10640)

DQL会解析为:SELECT T1_1.订单编号 订单ID FROM (SELECT * from 订单2012) T1_1 WHERE T1_1.订单ID IN (10620,10630,10640)