ORM-可视化动态数据建模
骆金松
1 背景
面向对象的基本哲学是认为世界是由各种各样具有自己的运动规律和内部状态的对象所组成的;不同对象之间的相互作用和通讯构成了完整的现实世界。因此,人们应当按照现实世界这个本来面貌来理解世界,直接通过对象及其相互关系来反映世界。这样建立起来的系统才能符合现实世界的本来面目。
遗憾的是世界是面向对象的,而关系数据库是面向关系的,人们一直在实践如何从现实世界中客观存在的事物(即对象)出发来构造软件系统,并在系统构造中尽可能运用人类的自然思维方式,强调直接以问题域(现实世界)中的事物为中心来思考问题,认识问题,并根据这些事物的本质特点,把它们抽象地表示为系统中的对象,作为系统的基本构成单位。这可以使系统直接地映射问题域,保持问题域中事物及其相互关系的本来面貌。
企业级管理系统的开发都不可避免的卷入到其中,许多的ORM的框架试图解决这个问题,但大都仅仅解决数据的变换和存取。然而软件系统所涉及的内容还包括数据建模、权限系统、用户管理、组织结构、工作流程、状态模型、协作模型等一大批紧密相关的内容,如果相关的框架没有进行整合形成一个全套的平台,学习和使用这些框架对于开发人员仍然是一个噩梦,我们的最终目标是将开发人员从无休无止的框架和技术中解放出来,真正关心如何快速满足客户的需求,创造高端的价值。
2 唯一标识和识别
在面向对象的系统中,任何数据都是对象,为了统一标识每个对象,在本平台中为每个对象分配一个唯一标识符,称为对象ID,对象ID必须在对象的整个生命周期中保持不变。为了确保每个对象的标识符不重复,即使不同的类型,ID也不重复,ID用GUID(全局唯一标识符)。
在数据库中,所有的数据都存储在二维表中,通过ER分析转换为数据库结构也可以部分表达面向对象模型中抽象、组合、关联等概念,但不能很好处理继承关系,对象模型的数据不能简单的存储在关系数据库中。
为了方便OR映射和开发实现,数据库中所有的表都使用ID作为主键,避免使用复合主键,复合主键会导致数据库设计和编码复杂化。通过ID就可以唯一标识一个对象,通过一个ID也容易建立对象之间的关系,编程传参数时也方便。
对象唯一标识ID一般只作为系统运行的内部标识,人不容易识别,系统使用者一般不需要看到ID。一般为不同的业务对象还会添加诸如编码类型的属性,以便方便人眼识别该对象。
一种简单的做法就是提供流水号编码,可支持定义编码的前缀、后缀、码的位数、填充字符等信息,每当创建对象时,对于“序列”类型的字段系统根据规则自动生成流水码,生成过程一般不需要人的干预,一般也不允许修改系统自动生成的流水码。
还有更加复杂的编码,比如机械行业经常为零部件编码,一般采用分段编码的方式,系统应该可自定义编码规则,例如定义编码的各个段,包括常量段、流水段、分隔符段、交互段等。在生成一个编码的时候,有些段自动生成,有些段需人机交互生成。
对于ID识别码、流水号码和自定义编码数据库都采用字符串方式存储,但是在开发平台中分别作为独立的数据类型提供,使得我们的平台的类型比数据库更加丰富。
3 类型系统
数据库中的数据类型是与业务完全无关的,一般都是原子类型,而我们的系统希望提供更加高层次的类型,以方便开发各类管理信息系统应用,比如我们的系统提供Sequence类型(表达流水码)、Code类型(自定义编码),当然也提供不过User、Organization、Directory、File等更加高层的类型。不同的数据库的数据类型也略有差异,而我们的平台应该做到数据库系统无关,通过ORM的框架屏蔽不同的数据系统之间的差异,业务逻辑的开发人员和二次开发人员不需要关心底层的类型系统,只需要基于平台提供的高层次的类型系统,可以更快的开发应用,由ORM实现与数据库类型的自动映射。
在系统中支持的复杂数据类型,在架构设计中我们通常称为实体类(Entity Class),在我们的数据模型中称对象类型(Item Type),而数据库一般是没有对象的概念的,都是关系表。我们的办法是,在我们的平台中创建一个Item Type,一般数据库中创建一张表,将Item Type的属性映射到表的字段。数据库的简单类型可以理解为表的某个列,一个简单类型的值可以理解为该表中一行某个列的实例。数据库中的复杂数据类型可以理解为表,复杂数据类型的一个实例可以理解为数据库的表的一行。复合对象在数据库中通过外键关系和关联表来实现。
4 创建对象类型
为了方便理解对象类型与子类型,下面举例说明一下物料(Material)的概念,生产企业习惯将最终产品之外的,在生产领域流转的一切材料(不论其来自生产资料还是生活资料),燃料,零部件(Part),半成品,外协件以及生产过程中必然产生的边,角,余料,废料以及各种废物统称为"物料"。物料是制造业企业很重要的一个类型。
在系统中创建“物料”对象类型,左边可以指定对象类型的基本属性,右边有一系列标签页,可以定义类的属性,类的关联等内容。创建一个类,系统会自动生成一些基本属性,如ID,创建人,创建时间,修改人,修改时间等。在属性标签页可以添加物料的自定义属性,如物料的“编码”、“名称”等。在数据库中将自动按模型生成表Material,用来存储“物料”对象类型的实例数据。