数据库建模的确是个学问,怎么建模都是套路固定,而实际生产出的东西却是各个不一,关键是理解数据内涵的不一致导致最终的产品不一致。例如我们对于授权系统的建模,就可以抽取出很多的方案,有一点是可以确定的,基础元素总是相同的。

数据建模的步骤和构架的步骤差不多:

  1. 理解问题
  2. 定义需求
  3. 找出关键点和关联部分
  4. 将设计可视化
  5. 复核模型计划和测试计划
  6. 测试和复核

在数据建模方面一般而言会遵循第三范式的约束,而经过这些年BI的开发,我发觉在BI项目中很难完全依照第三范式进行数据约束,聚合表的最直接的作用就是将数据访问的速度提高,标准的以空间换时间的做法(另外一个对于OLAP来说非常重要的作用则是构成事实表),在这个理念支持下,很多数据其实是分散存储在不同的表中,例如一张表是按照地域统计收入,而另外一张表则是按照代理商统计收入,两张表的原始数据都是从相同的ODS层数据抽取出来,看起来比较合理,而我们的实务中,为了统计 地域+代理商的收入,会将这两张表糅合在一起,这就不符合范式的规约了。

对于报表系统,有两部分数据模型的设计,一是报表系统的知识库(元数据MetaData)存储,而另外一部分则是报表系统报表数据模型的设计。从报表系统的角度来看,报表系统并不需要关心报表数据的模型设计,本章也只讨论知识库的设计。

知识库存储的数据列表如下:

  1. 报表定义
    • 基础信息
    • 报表列定义
    • 报表参数定义
    • 附加显示风格定义
    • 图形配置定义
  2. 数据源定义
  3. 性能统计信息
  4. 日志信息
  5. 字典定义
    • 数据字典定义(维度定义)
    • 数据字典字典值定义(维度成员)

在这里面,对于数据源定义和字典定义都不存在问题,都可以按照正常的范式规约进行元素的建模,关键是报表定义的建模需要考虑以下因素:

  1. 功能性的扩展会带来模型上面的变更,这需要Java定义和数据库一致同步,就是标准的阻抗失配的问题。
  2. 数据库只是负责存储定义,实际定义的Fetch和解析还是需要Java程序处理,在这点上,我趋向于使用XML数据库或者对象数据库。可惜,两者都不能很好的兼容于其他数据库,亦即我在Oracle上实现之后,没法移植到MySQL或者SqlServer上。
  3. 访问知识库的时候,大部分外部访问(除报表系统自身)不会去访问报表的主体细节定义,只是访问报表的基本信息。

所以,我又一次的越界,采用了擦边球的做法,设计报表的存储结构为

  1. 一张表存储全部的数据,包括基础信息,字段列、参数和附加等等信息,严重违反设计规约:将不同的东西分开存储
  2. 除基本的重要信息之外,其他信息使用XML的格式或者JSON格式保存在数据库的一个字段中,再次违反规约:一个字段应该有明确的职责。

为什么我要这么冒天下之大不韪而执意而为呢?因为我没办法,我宁愿吧更多的精力放在提高用户感受和报表性能上,而非这个地方,BTW,以后也不会优化。

这个东西计划在4.0版本中提供。

PS:写这篇文章的时候我正在听Sorma的《Mirage Of The East 亚》,电子乐+亚洲风格+混音,非常不错,值得听听。虽然正式烽火连城的日子,也需要自己心态的平和,否则受到影响的何止我一个人啊,慎重啊。