Home >Database >Mysql Tutorial >从类模型转换到数据库表结构的思考

从类模型转换到数据库表结构的思考

WBOY
WBOYOriginal
2016-06-07 15:06:011125browse

从类模型转换到数据库表结构 的思考 Aaron 从类模型转换到数据库表结构,或者说从UML类图转换为ER图,这个功能并不实用 。 为什麽呢? 如果你的类模型能够完整地转换为表结构(每一个表都能找到与之相关的类,如果类之间是多对多关系,那 么 会增加一个中间

从类模型转换到数据库表结构的思考

                                                            Aaron

 

 

从类模型转换到数据库表结构,或者说从UML类图转换为ER图,这个功能并不实用

 

 

为什麽呢?

 

如果你的类模型能够完整地转换为表结构(每一个表都能找到与之相关的类,如果类之间是多对多关系,那会增加一个中间表),那说明你的类图是不完整的,它们仅仅抽象了领域模型的数据资源,并没有抽象出领域模型的业务行为,因为表结构只能描述静态资源,不能描述业务行为。也就是说,你的类模型是“失血模型”。

我们这里不讨论“失血模型”与“充血模型”的优缺点,有兴趣的朋友可自己去javaeye上搜索。

 

 

当然,你也可以认为,即使使用了充血模型,仍然可以从类模型映射为表结构。但从实际情况来看,数据表的设计与类模型的设计常常有着差异。毕竟从DBA的角度抽象对象(其实DBA只能抽象对象的数据),与程序员从OO的角度抽象对象(数据和业务行为)是不同的。

数据表的关系是二维的(关系性数据库),而类模型的关系是三维的(OO的特性),类模型的关系远比数据表的关系复杂,比如类之间有继承,而表结构是不可能继承的。这就是数据库与类模型的“阻抗”。

 

 

因为数据库与类模型有阻抗,所以从类模型生成表结构是不现实的,它们不可能有标准的规则进行完美转换。除非是小项目,否则从类模型生成表结构,或者从表结构生成类模型,一定需要人工调整——这是致命的问题,哪怕需要手工调整的差异再小,日后的维护也足以让人心惊胆颤——项目的bug常常出现在被忽略的细节

 

 

顺便说一句,小项目(小项目不是指代码少或者数据表少,而是指业务逻辑简单)的开发根本不用这麻烦,不需要领域模型设计的垂直开发模式永远最快。而不用领域设计,已经超出本文的讨论范畴,本文只讨论横向切片----多层开发模式。不明白的朋友可以看看双鱼座的《只有企业级项目才特别需要使用ORM》一文。

 

 

,在设计时该以类模型为核心,还是以数据表为核心?

换个方式说,是先设计出类模型,然后参考类模型设计出数据表;还是先设计出数据表结构,然后再参考数据表结构设计出类模型?

 

 

无论先设计哪一样都不重要,甚至两者并行独立设计也可以。关键是两者不能依赖(参照)对方。

类模型有类模型的设计模式,数据表有数据表的设计原则。面向对象与数据库三大范式既有共同点,也有分岐,“低耦合,高内聚”,这样的面向对象的设计思想在设计数据表时完全用不上。

 

 

说了这多,我的意思就是,类设计和数据表的设计同等重要,不可偏废。只是两者考虑的角度不同,类设计时主要考虑可维护性,数据表设计时主要考虑效率。

 

 

如果从类模型完全映射为表结构,那这样的数据库性能必定很差;反之从数据表结构完全映射为类模型,那这样的系统可维护性必定很差。

这两种设计方式,一定会让DBA和程序员其中一方困惑,觉得难以理解,难以使用。

 

 

如果我们在设计系统时,把类模型和数据表结构分开独立设计,互不干扰是否可行?

答案是肯定的,而且本来就应该如此(分开设计)。

类模型和数据表结构的设计,应该参考业务模型,根据各自的特点(OO和范式)进行设计。

 

 

类模型和数据表结构的阻抗该如何消除?

 

 

ORM可以消除类模型和数据表之间的阻抗

ORM是目前最通用的解决方案,并且ORM已经被证明是行之为效的方案。ORM是类模型和数据表之间的桥梁,有了它,类模型和数据表才能平滑转换(映射)。

 

 

现在已经有了许多成熟的ORM方案,其中不乏庞大的工程(好吧,我承认我水平有限,Hibernate在我眼中就是大工程了,但在真正的高人面前,Hibernate只是“轻量级解决方案”)。

但我们不要被这些ORM方案的“花哨”功能迷惑:除了类模型和数据表之间的映射,其它诸如缓存、类SQL查询等等,都不是ORM的核心。ORM的核心就是“映射”而已,去掉缓存和类SQL查询之后,Hibernate仍然可以称为ORM,但去掉映射功能之后,Hibernate决不是ORM。

 

 

ORM的映射也有层次,比如iBatis和Hibernate的映射层次就不相同。ibatis是基于表映射,而Hibernate才是真正的类模型映射。两者最明显的差异就是,Hibernate支持巢状对象(多对多,对象中嵌入子对象),而iBatis不支持。所以也有人认为iBatis不是“纯粹的”ORM。

 

ORM的一些“缺陷”可以看看双鱼座的《ORM之硬伤》一文。

 

 

以下是我对ORM的一些理解:

1. 使用ORM不是为了赶潮流。小项目我喜欢垂直开发,一个ADO.NET强类型数据模型从Business Layer贯穿UI Layer到底,简单直接。

2. 使用ORM不是为了所谓的提高效率。ORM能提高效率是个笑话:论持久化,ORM的效率比不上ADO.NET;论运行效率,你认为ORM的反射和XML能快到哪里去?好吧,有人提出了ORM打开缓存之后,效率比多次直接查询数据库还快,但缓存关ORM什麽事?没有ORM难道我就不缓存了吗?

3. ORM是为类模型和数据表服务的,不要让ORM“喧宾夺主”,不要无限夸大ORM的作用。

4. 有些ORM侵入性太强,和类模式混合在一起。比如使用Castle的ActiveRecord时,类就必须从ActiveRecordBase继承。这样导致领域模型被“污染”了,增加领域模型的理解和维护的难度。而且C#是不支持多继承的,从ActiveRecordBase继承就限制了程序员的自由发挥。

5. ORM用来消除类模型与数据表之间的阻抗,其目的是为了用OO的思想来实现领域模型。
当我们使用面向对象的数据库代替关系性数据库之后(比如DB4O),ORM就没有存在的必要了。

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn