Oracle 11g OLAP 新功能简介

http://www.gemini5201314.net/tag/awm

2009年3月5日

oracle 11g 在数据仓库方面也有不少新功能,尤其是新的多维数据集组织的cube (也就是常说的MOLAP).

在开始本文之前,建议先查看otn 上关于介绍oracle 11g 新功能的data warehouse 部分,由oracle ace 总监Arup Nanda 写的, 目前otn 的中文站点已经有翻译版的, 地址如下:

http://www.oracle.com/technology/global/cn/pub/articles/oracle-database-11g-top-features/11g-dw-olap.html?_template=/ocom/print

这篇文章主要介绍上面这篇文章中的一些实验和没有覆盖到的地方. (记住一定先看上面这篇文章)

 

导入数据

首先从http://www.oracle.com/technology/products/bi/olap/doc_sample_schemas/global_11g_schema.zip

下载它的示例数据, 之后使用一个具有DBA 权限的用户建立global 用户,用户名一定要是global (除非你修改里面的一些脚本), 执行

8665fb959e4f46e9d701dc587fea8b93000

它会要求你输入system 的密码和你希望global 用户的密码

之后就会导入global schema . 一共8个表,默认应该是成功并且没有警告的.

不要执行第二个脚本 global_11g_create_cubes.sql, 虽然它global_11g_readme.html 说明里说要执行第二个脚本,但这个脚本有问题,会失败. 执行了也没关系.

 

使用AWM

伴随oracle 11g 发布的还有一个AWM (Analysis Workspace Manager) 工具,版本为11.1.0.7 ,  这是个JAVA 工具,需要JDK 5.0 以上, 你可以到下面地址下载:

http://www.oracle.com/technology/global/cn/products/bi/olap/index.html

oracle 11g 引入了 分析工作区 (aw) 来管理跟OLAP 有关的对象, 而awm 就是一个图形化的用来管理aw 的工具.

解压awm 之后, 在命令行下执行

java –jar awm11.1.0.7.0B.jar

awm 启动后,点击 File –> Connect Database , 选Global 作为你要连接的数据库,输入刚才输入的global 用户名和密码. 之后打开分析工作区 , 你应该看到global 工作分析区下面有dimensions , cubes 文件夹,你点开后里面应该是空的(otn 的示例上有是因为执行了上面第二个脚本,但是它给出的下载的文件里这个脚本有问题而没有执行,所以应该是空的).

现在可以导入dimension 和cube 的定义,右键点击Dimension 文件夹,选择 从模板创建 , 然后倒入CHANNEL , CUSTOMER , PRODUCT , TIME dimension , 文件就在global_schema 文件夹下的templates 下, 对cube 也执行一样的操作导入PRICE_CUBE 和 UNIT_CUBE .

 

填充Cube 数据

完成上面操作之后,你应该有了4个dimension 和2个cube , 但是里面都没有数据,你可以使用两种方法从table 里面导入数据,

1. 用pl/sql  , 在sqlplus 里面使用 exec dbms_cube.build(‘PRICE_CUBE’) ;

2, 还是使用awm , 在awm 的cube 文件夹下的PRICE_CUBE 上点右键,选择 维护立方体 .

image

    awm 会让你选择维护的cube 和dimension , 点击Next 之后,再选择 立即运行 , 如果你想看运行的到底是什么,你可以选择保存文件.

image

之后你可以在Build log 对话框里面查看Output 列,

<CommandOutput>
<CubeLoad
Name="MAP1"
SQL="SELECT /*+  bypass_recursive_check  cursor_sharing_exact  no_expand */
  T16_MONTH_ID ALIAS_114,
  T13_ITEM_ID ALIAS_115,
  SUM(T19_UNIT_PRICE)  ALIAS_116,
  SUM(T19_UNIT_COST)  ALIAS_117
FROM
  (
  SELECT
    T1.ITEM_ID T19_ITEM_ID,
    T1.MONTH_ID T19_MONTH_ID,
    T1.UNIT_PRICE T19_UNIT_PRICE,
    T1.UNIT_COST T19_UNIT_COST
  FROM
    GLOBAL.PRICE_FACT T1   )
  T19,
  (
  SELECT
    T1.MONTH_ID T16_MONTH_ID
  FROM
    GLOBAL.TIME_DIM T1   )
  T16,
  (
  SELECT
    T1.ITEM_ID T13_ITEM_ID
  FROM
    GLOBAL.PRODUCT_DIM T1   )
  T13
WHERE
  ((T16_MONTH_ID = T19_MONTH_ID)
    AND (T13_ITEM_ID = T19_ITEM_ID)
    AND (T16_MONTH_ID = T19_MONTH_ID)
    AND (T13_ITEM_ID = T19_ITEM_ID) )
GROUP BY
  (T13_ITEM_ID, T16_MONTH_ID)
ORDER BY
  T13_ITEM_ID ASC NULLS LAST ,
  T16_MONTH_ID ASC NULLS LAST "
LOADED="2523"
REJECTED="0"
</CommandOutput>

完成之后你就可以看到cube 里面的数据了.

 

查看数据

Oracle 11 g引入一个新的函数cube_table 让我们使用sql 的语法就可以查看到MOLAP 的数据,语法如下

cube 语法: select * from table(cube_table(‘<schema>.<cube_name>’))

示例 PRICE_CUBE : select * from table(cube_table(‘GLOBAL.PRICE_CUBE’))  (如果你是global 登录的,可以不加前面的global.)

dimension 语法: select * from table(cube_table(‘<schema>.<dimension>;<hierarchy>’))

其中hierarchy 部分是可选的, 比如对于global 用户的product dimension:

select * from table(cube_table(‘global.product’));

如果dimension 只有一个hierarchy ,oracle 当然会选择这个,如果dimension 有两个或两个以上的hierarchy , oracle 使用的就是你指定的默认的那个, time dimension 就有CALENDAR 和FISCAL 两个hierarchy , calendar 就是默认的那个,所以你查询time dimension 时没有指定hierarchy , 实际就是查询的calendar hierarchy.

对于每一个cube 和dimension ,oracle 都会创建相应的view , 所以你查询cube 和 dimension 的时候,也是查询的对应的view.

比如global schema 就会默认的创建下面这些view (在你建立cube 的时候) : product_view , product_parmary_view , time_view , time_calendar_view, time_fiscal_view , price_cube_view.

每个dimension 会默认创建 <dimension_name>_view 和 <dimension_name>_<hierarchy_name>_view , cube 则会对应 <cube_name>_cube_view

所以你执行select * from table(cube_table(xxx)); 的时候实际上就是查询的view

比如其中price_cube_view 的定义就是如下:

8665fb959e4f46e9d701dc587fea8b93001

 

cube 的过滤,排序和聚合

更复杂一点的sql:

SELECT * FROM TABLE(CUBE_TABLE(

   ‘global.price_cube HIERARCHY product primary HIERARCHY time calendar’))

   where TIME=’TOTAL_TOTAL’

   ORDER BY PRODUCT   
   ;

 

SELECT SUM(UNIT_COST),SUM(UNIT_PRICE),PRODUCT  FROM TABLE(CUBE_TABLE(

   ‘global.price_cube HIERARCHY product primary HIERARCHY time calendar’))

   where TIME=’TOTAL_TOTAL’   
   GROUP BY PRODUCT

   ORDER BY PRODUCT   
   ;

 

跟普通的sql 基本一样,除了cube_table 里面的写法需要注意一点外, 如果你喜欢通过GUI 界面来看的话,awm 里面右键点击cube 选查看数据.  还可以点击维度展开 , 下面还有图表.

awm_view_cube_data

在查讯构建器里面(上图中 文件 菜单那个下面那个按钮)还可以选择构建复杂的.

awm_query_build

这个界面倒是跟owb 里面的完全一样,估计用的同一代码

owb_sshot-6

最原始的模型应该是从essbase 借鉴过来的,界面布局和操作方式都跟essbase 非常像.

 

 

如何管理cube

并没有直接的pl/sql 可以来删除或者修改cube , 目前dbms_cube 包里面就三个函数 build() , import_xml , validate_xml().  build() 是用来填充数据的 . 如果你对cube 的定义不满意的话,要修改或者删除的话,一般都是通过awm ,  otn 上面给出的那个global_schema 文件里倒是有一个删除的例子,手工拼接xml , 然后dbms_cube.import(xml).

  set serverout on

  declare      xmlCLOB   clob;      v_i       number;      type t_dims is table of all_cube_dimensions%rowtype;      type t_cubes is table of all_cubes%rowtype;      v_dims    t_dims;      v_cubes   t_cubes;      v_cmd     varchar2(400);    

  begin      -- Check if the AW exists
    dbms_output.put_line('... checking for GLOBAL AW in GLOBAL schema');     SELECT COUNT(*)      INTO v_i     FROM all_aws     WHERE owner = 'GLOBAL'      AND aw_name = 'GLOBAL';


    -- Delete the AW if it exists     if v_i > 0 then       dbms_output.put_line('... deleting GLOBAL AW in GLOBAL schema');        dbms_lob.createtemporary(xmlCLOB,TRUE);        dbms_lob.open(xmlCLOB, DBMS_LOB.LOB_READWRITE);        dbms_lob.writeappend(xmlCLOB, 9, '<Metadata');        dbms_lob.writeappend(xmlCLOB, 16, '  Version="1.1">');        dbms_lob.writeappend(xmlCLOB, 5, '  <AW');        dbms_lob.writeappend(xmlCLOB, 19, '    Action="REMOVE"');        dbms_lob.writeappend(xmlCLOB, 18, '    Owner="GLOBAL"');        dbms_lob.writeappend(xmlCLOB, 19, '    Name="GLOBAL"/>');        -- Loop over each of the Dimensions in the AW and delete them        select *  bulk collect  into v_dims   from all_cube_dimensions        where owner = 'GLOBAL'  and aw_name = 'GLOBAL';
        for i in 1 .. v_dims.count loop          v_cmd := '<' || initcap(v_dims(i).dimension_type) || 'Dimension';          dbms_lob.writeappend(xmlCLOB, length(v_cmd), v_cmd);        dbms_lob.writeappend(xmlCLOB, 19, '    Action="REMOVE"');        dbms_lob.writeappend(xmlCLOB, 18, '    Owner="GLOBAL"');         v_cmd := '    Name="' || v_dims(i).dimension_name || '"/>';         dbms_lob.writeappend(xmlCLOB, length(v_cmd), v_cmd);              end loop; 

     -- Loop over each of the cubes and delete them
        select * bulk collect into v_cubes         from all_cubes        where owner = 'GLOBAL'          and aw_name = 'GLOBAL';        for i in 1 .. v_cubes.count loop          dbms_lob.writeappend(xmlCLOB, 7, '  <Cube');        dbms_lob.writeappend(xmlCLOB, 19, '    Action="REMOVE"');          dbms_lob.writeappend(xmlCLOB, 18, '    Owner="GLOBAL"');         v_cmd := '    Name="' || v_cubes(i).cube_name || '"/>';                      dbms_lob.writeappend(xmlCLOB, length(v_cmd), v_cmd);       end loop;            -- Finish off the removal tags
        dbms_lob.writeappend(xmlCLOB, 11, '</Metadata>');            dbms_lob.close(xmlCLOB);            dbms_output.put_line(xmlCLOB);       --  dbms_cube.import_xml(xmlCLOB);       commit;     else       dbms_output.put_line('... GLOBAL AW in GLOBAL schema not found');     end if;     exception       when others then         dbms_output.put_line(' ');         dbms_output.put_line('# ERROR:  Installation failed.');         dbms_output.put_line('# Please ensure that the analytic workspace GLOBAL is not currently open.');         raise_application_error(-20000, 'Can not delete analytic workspace that is currently in use.');
end;
/

我把dbms_cube.import_xml() 那一行注释掉了,输出类似如下:

<Metadata  Version="1.1">  <AW    Action="REMOVE"    Owner="GLOBAL"  Name="GLOBAL"/><StandardDimension    Action="REMOVE"    Owner="GLOBAL"  Name="CHANNEL"/><StandardDimension    Action="REMOVE"    Owner="GLOBAL"  Name="CUSTOMER"/><TimeDimension    Action="REMOVE"    Owner="GLOBAL"  Name="TIME"/><StandardDimension    Action="REMOVE"    Owner="GLOBAL"  Name="PRODUCT"/>  <Cube    Action="REMOVE"    Owner="GLOBAL"  Name="PRICE_CUBE"/></Metadata>

你可以看到它执行删除操作就是通过Action = "REMOVE" .

 

最后

关于cube 的数据储存和刷新 下一篇介绍,另外还有关于oracle 11g 的OLAP 新特性 更频繁地执行查询重写  ,

分区中的陈旧程度检查  otn上都有介绍, 大家可以去看看

 

参考资料

http://www.oracle.com/technology/global/cn/pub/articles/oracle-database-11g-top-features/11g-dw-olap.html?_template=/ocom/print

otn 上介绍oracle 11g olap 新功能的文章.

 

http://www.oracle.com/technology/products/bi/olap/collateral/OLAP_11g_MV_query_rewrite.html?_template=/ocom/print

介绍cube mv 的刷新方式的文章

 

http://www.dba-oracle.com/t_olap_dimensions_cubes.htm

11g 之前的一篇介绍olap 概念的文章, 由oracle ace Mark Rittman 所写, 其中有关于如何在pl/sql 中创建和维护cube 的代码(awm 操作起来还是更简单些)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值