基于面向对象(OO)的数据库设计模式探讨

IBMdW 发布于 2011/06/08 09:18
阅读 1K+
收藏 1

前言

软件开发中面临的问题

在软件开发过程中,几乎没有几个程序员喜欢报表开发,报表多、杂,需求多变,特别是给人感觉没有什么技术含量,大家对报表都是退避三舍。如果 采用 BI 工具开发,又会因为 BI 工具五花八门,不同项目 BI 工具不同,需要开发不同的程序,增加了项目开发成本,除非是固定一种报表工具,但是不同的客户需求不同,不得已需要不停的变化展现工具;不用 BI 工具,自己开发应用,如果采用多维数据库,则需要程序员熟悉多维数据库的 SQL 语法,增加了开发的难度;基于关系型数据,采用通用的查询工具又往往面临着查询性能问题,报表的开发似乎成了一个死结。重复劳动、产品通用性差、查询性能 差等问题是当前所面临的一个重要的课题,特别是对于大型的管理系统,多变的查询需求和海量数据处理,往往成为项目迟迟不能验收的一个最重要因素。

本文参照数据仓库建模的思路,解决查询性能问题,采用关系型数据结构,使用和业务系统通用的 Java 开发,给出了一个建立简单清晰的数据模型的方法。

数据仓库的建模思路

在数据仓库建模中经常会采用空间换性能的方法,需要汇总的数据不是临时汇总而是提前汇总好,比如销量指标,其年累计、同期、上期、计划、实际、增长比例等提前汇总计算好,提高查询速度,在此简单介绍几个基本的数据仓库概念:

星型模式:(也称为星形连接的模式,数据立方体,或多维模式 )是最简单的样式数据仓库架构 。星型模式由一个或多个事实表中引用任何数量的维表

维表:维度表可以看作是用户来分析数据的窗口,维度表中包含事实数据表中事实记录的特性,有些特性提供描述性信息,有些特性指定如何汇总事实数据表数据,以便为分析者提供有用的信息,维度表包含帮助汇总数据的特性的层次结构。

事实表:事实数据表可能包含业务销售数据,如销售所产生的数据,事实数据表通常包含大量的行。事实数据表的主要特点是包含数字数据(事实), 并且这些数字信息可以汇总,以提供有关单位作为历史的数据,每个事实数据表包含一个由多个部分组成的索引,该索引包含作为外键的相关性维度表的主键,而维 度表包含事实记录的特性,在本文中称为汇总表。

本文采用的示例数据模型

为了更好的理解本项目的思路,以下以客户关系管理数据模型为例,按照对象关系模型建模,主要的业务对象包含供应商、商品;客户、客户经理、客户业态;销售订单、采购订单等基本业务对象,主要的汇总表包含客户商品日帐(即客户每天每个商品的销售汇总)等,如下图所示:


图 1. 数据对象模型示例( 查看大图
图 1. 数据对象模型示例

另外在本文中提到几个指标:销量,是在一段时间内客户购买的数量;上柜率,是指一个月内购买某一个商品的客户数占所有有效客户数的比率。即上柜率 = 本月购买本商品的客户数 / 有效客户总数。

指标矩阵模型

根据当前所面临的问题,参考数据仓库建模理念,从以分析指标入手,建立指标模型,然后根据汇总维度建立维度矩阵模型,最终结合指标模型和纬度矩阵模型建立指标矩阵模型。

指标模型

在考虑建立那些汇总表之前,首先确定那些指标是原始指标,即已经存在的指标,不再需要进行逐级汇总,可以直接使用的指标,这些指标属于原始指 标,可以直接作为汇总表的原始数据。然后把不能汇总的指标尽量分解为可以汇总或者可以计数的指标,以便于进行数据汇总和查询(这一点对于简化模型很重要, 可以把大部分指标分解为可以进行汇总计算的指标)。整理好所有的指标之后,通过指标进行分类,建立元指标和扩展指标,最终建立指标树模型:

1. 原始指标,从其他系统获取或者采集的原始数据,为原始指标,原始指标是其他指标汇总指标的基础。

有些指标是不可以汇总,但是也无法分解,因为每个级别之间不是汇总关系,一般是单独设置的。比如计划,并不是逐级汇总上去的。因此每一级的指 标都是原始指标。有些指标是从外部引入的,因此并不一定从最基础的地方开始汇总,比如系统外的数据,GPD、人口指标,可能直接从一个某一个级别开始统 计,更细节的数据没有或者没有必要。因此原始指标并不一定就是从最细粒度开始汇总的。

以上两种情况,需要把指标设置为原始指标,即从从其他系统获取或者采集的指标。

2. 计算指标,将不可以汇总、计数的指标分解到可以汇总的指标,比如上柜率,可以分解为客户总数和购买本商品的客户数,在最细粒度数据客户 方面可以分解为是否上柜(可以计数),比如毛利率可以分解为毛利和金额。这一点很重要,只有进行类分解之后,后续的汇总和查询才可以大大简化。被分解的指 标称之为计算指标。

3. 元指标:首先根据业务报表需要,对所有的指标进行分类,找出元指标,元指标是不含有任何维度信息的,比如销量、金额、毛利、上柜率等。一个企业可能有上百个指标,为了便于管理,可以对指标进行分类管理,如销售类、财务类、人力资源类等。

4. 扩展指标,元指标是基本的指标,但实际应用中,根据指标在不同的时间维度、或者某种算法,可以“模式化”很多扩展的指标,如:

a) 年累计、年实际···

b) 月实际、同期、上期、同期增长、环比增长、月累计···

扩展指标是某元指标的一个“模式化”扩展,适用于所有相关的指标。比如销量,可以有年累计销量、年计划销量、年实际销量、月实际销量、同期销 量、上期销量、销量同期增长、销量环比增长、月累计销量等。这种模式化,通过分析会发现基本上可以适应到大部分指标(如金额、毛利),通过扩展指标,可以 建立一个矩阵,大大简化指标体系的复杂度。


表 1. 基于时间维度的汇总表
序号 指标 年累计 同期 同比 上期 环比 ··· 1 销量 有 有 有 有 有 2 金额 有 有 有 有 有 3 毛利 有 有 有 有 有 4 毛利率 无 有 有 有 有 ···

维度矩阵模型

5. 基础维度表,基于对象关系模型(详见 “基于面向对象(OO)的数据库设计模式探讨”), 建立基础维度,以及基于基础维度的原始事实表。基础维度包含日期(日)、数据拥有者(所有者,客户、人员、部门)、商品等(如图 1 所示)。其中日期维度是必须的,因为汇总表都是基于日期维度进行汇总的,没有日期的表是基础维度表。所有者也是是必须的,因为每个数据一定是某一个所有者 所拥有。除此之外的维度是可选的,比如商品,可以有不含商品维度的客户月汇总表,包含商品维度的客户商品月汇总表两个。

根据星型模式建模理论,基础维度应该可以获取所有相关信息,不需要在关联其他的维度,如客户维度表,里面应该有客户经理、销售部门、客户类别等所有相关的信息,便于提高查询效率。

注意,要把日期看成一种普通的维度,如月份,实际上也是一种“分类”,如 201001,代表 20101月,但是还可以直接用 01代表一月,这样后期报表处理就会简化。

6. 原始事实表,对应着对象关系模型中的流水实体对象,流水实体对象按照时间进行汇总之后的为事实表,如:客户商品日表;供应商商品日表, 仓库商品日表、考虑到行政区划信息比较稳定,如 GDP 等,直接按照年表建立,即行政区划年表,作为最原始事实表,当然根据需要,也可以建月表。

理论上,所有的原始事实表建立之后,所有的汇总数据都可以直接查询出来了,但是考到性能问题,通过空间换时间的方式,按照维度的不同方向进行汇总。

7. 维度矩阵模型,基于原始事实表,根据基础维度,在基础维度的不同汇总方向上建立维度汇总关系模型,如客户商品日表的汇总模型可以在不同维度方向上进行汇总,

首先是在日期维度

a) 日 - 月 - 年

b) 日 - 月 - 季度 - 年

c) 日 - 周 - 年

如下图所示,可以分别建立不同的汇总表,其中常见的是日、月、年等。


图 2. 基于时间维度的汇总表( 查看大图
图 2. 基于时间维度的汇总表

在客户维度:

d) 客户 - 客户经理 - 部门经理 - 公司

e) 客户 - 客户业态

如下图所示,通常按照组织机构建立汇总表。


图 3. 基于时间、客户维度的汇总表( 查看大图
图 3. 基于时间、客户维度的汇总表

在产品维度

f) 商品 - 品牌 - 供应商 - 省份

g) 商品 - 品类

h) 商品 - 大类


图 4. 基于时间、客户、商品维度的汇总表( 查看大图
图 4. 基于时间、客户、商品维度的汇总表

维度矩阵模型,实际上是维表在不同的可以汇总的方向上的笛卡尔乘积,其中有些是不需要的,如上图所示,根据这个模型,可以列出所有需要的汇总表。

维表的建设,可以参考当前比较成熟的建模方法,比如经常见到的数据高阶建模,一般分为参与者、地点、产品、交易等,本文不再详述。

指标矩阵模型

8. 指标矩阵模型,分析每一个元指标及扩展指标在维度矩阵模型中是否存在,并根据指标进一步完善维度矩阵模型。有些指标并不是在所有的汇总 表中存在的,比如上柜率是月度指标,所以在所有的年表、日表中是不存在的;比如日表中不需要同期、上期,但是年累计、月累计等指标可能是需要的。

同维度矩阵模型一样,指标矩阵模型是在维度矩阵基础上的笛卡尔积的笛卡尔积矩阵,数据是很庞大的(这也是为什么建立这个模型的原因,通过这个 模型,可以建立更加容易理解的数据模型),但是并不是每一个指标在不同的矩阵中都是存在的,需要根据这个模型来分析哪些指标是存在的,哪些指标是不存在 的。

在最终确定的模型中,有些数据表可能因为数据量很小,不存在性能问题,但是考虑到统一风格,统一处理方便性,全部按照一个思路,即一个“模式”,这样程序开发就会简单。

9. 对于指标灵活多变的,建立基于指标的汇总表,将每个指标的值存放在列上,指标可以灵活增加。详见对象关系模型中不定属性对象的描述。

通过以上方式,即可建立一个汇总表模型,但是在实际建模过程中会出现一些特殊情况,如过于个性化的指标,不好计算,则作为原始指标来看待,单 独进行汇总处理。有些指标因为维度值的变化不同,比如客户经理因为人员的更换以及客户所属客户经理更换,同期销量,实际上可以有两个值,一个是所管理的当 前客户的同期,一个是本人同期管理的客户的实际值,因此需要根据需要,看看取哪一个指标。

根据“模式化”的思路,可以进一步把指标矩阵模型进一步进行扩展,有汇总数据,一般会对应着有一个计划数据,结合以上思路,可以进一步建立一个计划、汇总模型的“模式化”框架,本文不再详述。

模型在实际环境中的应用

为了更好的让指标矩阵模型发挥作用,以下分别从存储设计、性能角度及实际开发过程中的应用功能来看本模型的应用。

模型表结构设计

根据查询频次,在不同的维度方向上确定是否需要建立汇总表进行物理存储,对于不经常用的数据,可以采用实时汇总的方式,实时汇总基于最近的维 度汇总表进行汇总的方式,比如查询客户商品季度汇总,可以直接客户商品月汇总表中汇总数据;查询公司客户业态月汇总数据直接从公司客户商品月汇总表中获取 数据。

在数据查询的时候建议通过视图获取数据,一方面可以解决计算指标的问题,通过视图,把计算指标直接封装,二是可以通过视图实现部分物理存储, 如客户业态商品汇总表,可以通过视图的方式进行汇总,而实际上并没有进行物理存储,适应于不是很常用的一些汇总、数据量比较少的汇总表,这些汇总可以通过 设置查询一次存在缓存中的方式,进一步优化。

如果字段比较多,可以按照业务主题,分成多个表,在查询的时候通过多个表分别获取数据。按照以上模型建立的汇总表,同样级别的数据可能会存放 在不同的表中,比如客户的销量信息和客户的上柜率可能是存放在不同的表中,如果在一个报表中同时查询这两个信息,就需要同时查询两个表,可能会存在性能问 题,解决这个的办法是在查询的时候需要考虑如何优化查询性能,比如在考虑从多个汇总表表获取数据,然后合并为一个,可以先建立几个临时表,分别把需要的数 据从各个地方获取存放在临时表中,然后在从临时表中获取数据,同时写入到一个表中,而不是先写一列,然后在修改,这样性能会比较差。

是否建立汇总表,可以通过在这个维度上是否有大量的减少, 比如客户经理对客户来说,一下子就减少了 200 倍的数据,所以汇总时值得的。如果是 10 倍,可以不汇总,这需要根据实际数据来分析。10000 万的数据和 1000 万,性能还是会差别很大的。

模型查询性能优化

通过前文所提到的表结构方面的优化,从查询性能角度来看,本模型主要从几个层面,采用空间换时间的思路,进行了优化:

基于星型模式的优化:建立简单星型模式,设置了维表,通过维表的冗余存放,减少的维表之间的关联,取消了雪花模型带来的性能问题。

基于指标的优化:建立指标扩展模型,同时查询的数据存放在表的一行中,可以一次获取,减少查询的次数,如同时获取同期、上期数据,避免数据的多次查询。

基于索引的优化:直接在事实表中建立外键,分类汇总不需要关联更多的维表中,可以直接进行查询。同时直接在事实表中建立外键之后,可以保留历史痕迹,完整的反应当时的数据情况,如客户的客户业态更换之后,还可以按照客户当时所属的客户客户业态进行统计。

基于汇总表的优化:根据维表的不同汇总方向,建立多级汇总表,汇总的数据直接在汇总表中查询,实现数据的优化。

灵活查询系统建设过程

基于汇总表体系,建立灵活查询系统,是本模型的目标之一,按照组件化的方式,可以将灵活查询系统分成查询组件、数据获取组件、数据展示组件、 数据汇总组件、元数据组件。数据库层面还需要完善的内容包含数据权限、元数据两个部分,数据权限用与限定使用者看到的数据范围,元数据用与描述本模型,如 下图所示:


图 5. 灵活查询系统组件模型
图 5. 灵活查询系统组件模型

灵活查询系统建立之后,可以实现自动的数据汇总,自定义查询条件和查询显示结果,如果完全实现灵活查询系统,需要一个漫长的过程,而且很可能因为工期太长,系统过于复杂,最终导致系统开发会失败,可以分步建设,逐步实现:

首先建立基于指标矩阵模型的数据库,基于本数据库进行查询,具体的查询可以采用原来的查询方式和报表展示,数据汇总可以通过直接写程序或者手工汇总。

建立元数据管理,对数据模型进行管理,基于元数据管理建立独立查询模块,实现定义各种查询条件,输出结果为一个标准化之后的查询的 XML,然后根据查询 XML 生成查询结果。查询模块可以进一步完善,如保存查询条件等。

建立数据获取模块,数据获取模输入条件为标准化之后的查询的 XML,输出也是标准化的 XML,进一步将数据获取模块进行分离,只要输入一个查询的 XML,就可以获取一个查询结果,并以 XML 方式输出。

建立数据展示模块,根据 XML 格式自动展示,最终实现自定义数据展示。

建立数据汇总模块,基于元数据,实现自动汇总。

通过以上分析可以看到,虽然整个灵活查询系统体系非常复杂,但是可以分解为不同的组件,分步建设,逐步实现。当然,也可以直接采用成熟的商品 软件,特别对于大型的项目,可以直接部分或者全部采用商品软件,如 IBM 产品体系,可以采用:数据汇总,采用 ETL 工具,如 Datastage,数据展示采用 Cognos 等,进一步简化系统的开发,如下图所示。


图 6. 基于 IBM 系统软件的灵活查询系统
图 6. 基于 IBM 系统软件的灵活查询系统

以上根据前文提到的指标矩阵模型,就模型表结构设计、性能优化及灵活查询系统建设做了一个简单说明。

文章转自 IBM developerWorks

加载中
0
咖啡碼農
咖啡碼農
光有理论,不见实现
0
再见理想
再见理想
求教--IBM这套产品是怎么报价的
返回顶部
顶部