在“面向对象建模与数据库建模两种分析设计方法的比较”一文中我们比较了在对需求分析时两种方法的不同,所谓数据库建模分析,就是项目一开始就根据需求建立数据库模型,如数据表结构和字段等,这种错误现象大量普遍存在我们国内项目实践中,从每年大量招聘启示中就可见一斑:招聘数据库建模人员,招聘Java面向对象程序员。这些说明软件业一边在大量使用Java/.NET/Ruby on Rails这样OO语言同时,还在同时使用与OO体系抵触的围绕关系数据库的分析设计方法。
为进一步说明OO和关系数据库是属于两个不同世界观,存在天然矛盾,就象有神论和无神论,就象水与火那样属于截然相反的两种编程知识。正好最近TheServerSide刊登一篇大谈对象数据库ODBMS的文章:When to use an Embedded ODBMS(以下简称ODBMS一文)
http://www.theserverside.com/tt/articles/article.tss?l=EmbeddedODBMS
这篇文章不但谈到了OO和关系数据库天然阻抗;谈到了ODBMS和RDBMS区别,也谈到了ODBMS和O/R Mapping如Hibernate的区别,甚至谈到了ODBMS在非C/S如嵌入式方面的优点。这篇文章我看最重要价值就是它用大量篇幅阐述了对象和关系数据库存在的天然矛盾,我这里就将这部分篇幅大意转载这里,可以说是经过我咀嚼后反馈的结果,版权思想还是属于这篇文章,我这里只是用中国人更易于接受方式把这个天然矛盾转述出来:
对象和关系数据库累赘转换
在一个面向对象系统中,数据存在于对象中,在关系数据库中,数据存在于数据表的记录中。
在关系数据库世界中,我们必须掌握表结构、表记录等概念,这里面没有任何对象概念,当我们在OO语言中使用关系数据库时,因为在OO世界中是大量对象,所以必须将数据在这两个不同世界之间转换传输。
这就导致了大量垃圾临时对象,增加了应用系统的复杂性。这也是我们很多人使用了Java等这样的OO系统后,反而觉得开发效率并没有OO宣传那么高的原因, 说白了,OO思想没有完全占领应用系统,因为有关系数据库盘踞着数据库这个最后堡垒负隅顽抗。
下面看看我们程序如何为了让OO语言和关系数据库捆绑在一起工作,如何弥补两个世界的裂缝,如何在他们之间和稀泥。 为了将对象保存到关系数据库中,我们必须将对象中的数据解散开来,再将它们组装到SQL中,然后执行SQL。
一个类如下:
public class Course { public string name; public int courseID; int deptID; public int creditHours; } |
将上述对象保存到关系数据库的SQL语句如下:
PreparedStatement insertStatement = connection.prepareStatement( "INSERT INTO Courses (name, courseID, deptID, creditHourse) " + "VALUES (?, ?, ?, ?)"); insertStatement.setString(1, course.name); insertStatement.setInt(2, course.courseID); insertStatement.setInt(3, course.deprtID); insertStatement.setInt(4, course.creditHours); insertStatement.executeUpdate(); |
上述在两个世界之间做的翻译工作与复杂性取决于对象Course这样的复杂性。如果Course字段有十几个,那么这个保存SQL将更复杂。
更重要的是,万一有一个字段发生变化,更改量就很大。我们不但要修改对象,而且还要修改数据表结构,有过数据库编程经验的人知道,如果表中有数据,表结构变动带来的问题可能就象噩梦一样,所以,我们程序员经常以这个需要更改表结构拒绝一些软件的维护和拓展,这其实更是错上加错;在ODBMS一文中提出了对象数据库解决方案:只要更改类结构,其他都有ODBMS搞定;使用ORM如Hibernate也只多一个步骤:更改映射配置。
继承关系的尴尬实现
对象和关系数据库的不匹配还表现在关系数据库难以实现对象世界中的继承关系,如下图:
这是一个典型的对象世界表达客观世界的类图,学生和教授都是人,都具备人一些共性,当然他们之间也有区别,所以我们用上述继承关系来表达这样一个情况。
那么如果这样继承关系的类图如何保存到关系数据库中呢?有两种方式:one-class-per-table(一个类对应一个表)和one-object-per-row(一个对象对应一个表行)。
在one-class-per-table方式中,Student对象放在Student表中,Professor放在Professor表中。但是Student和Professor实际具有共性Person,这实际上将Person这个共性对象中数据分割成两个表保存,从语义上所:也就是将一个对象分割成两个部分了;而且当你要获取这个对象时,需要两次Select。同样道理增删改查都要两次。
如果按照one-object-per-row,将这Student和Professor放到一个表中,就会产生空白字段。Student对象中数据保存到Student对象对应的字段中,那么Professor对象对应的字段就是空的,反之也然。
这些都反映了对象和关系数据库天然不匹配,两者根本就无法搭配在一起工作,只有一方作出妥协,大部分情况是对象作出妥协,这样,一个OO语言Java/.NET系统就做成了一个数据库中心系统,根本无法享受OO语言带来快捷方便,可维护性强,由于Java出现比较早,更多程序员将项目失败归结于Java语言本身,转而使用数据库思维去做.NET,去做Ruby On Rails,还是会碰到上面这些问题,没有碰到,只能说明他们系统中就没有对象概念,解决方式很简单很可笑:矛盾双方,消灭一方不久解决矛盾了。
类的复杂关系实现
下面我们再看看ODBMS一文中列举的类复杂关系如何用关系数据库实现保存:
public class Department { private Professor[] professors; ... }
|
这个Department类很明确告诉我们这样一个意思,在一个Department中,存在很多Professor,大白话就是:一个部门里有很多教授,这个类就自然准确地表达这个意思,这也体现了使用OO表达需求的自然性和方便性。
那么我们下面看看,如果我们使用关系数据库来保存Department这个对象,很显然,这里需要使用关系数据库的表外键,通过表外键来表达Department表和Professor之间1:N关系,关键问题是:这个外键一般是设计在Professor表中,这就造成语义上的误解。
对象Department表达的需求含义是:
1. 我是一个部门对象,在我里面包含很多教授对象。
当这个对象在关系数据库,由于外键在Professor表中,那么意思就是:
2. 我是一个教授对象,这里有一个我所属的部门对象。
前后对比发现,其实完全是两者不同表达方式,这已经属于拷贝走样了,当我们从关系数据库中获得Department 对象时,得按照关系数据库规则绕一个弯来获得完整的Department 对象。也就是说:每次获得一个对象Department,我们得将这个需求意思翻译成关系数据库的表达方式,这种内耗式的翻译不但容易出错,也带来了程序员开发上的负担。万一不留神,翻译出错,问题就严重了。
当然,如果我们使用ODBMS,就不必做这些费力不讨好的翻译转换,也不再绕着弯子编程,只要直接告诉ODBMS或ORM框架如Hibernate,就能够获得一个真正对象意义上的Department。
以上是TSS的ODBMS一文大量篇幅阐述了对象和关系数据库矛盾的方面,所以,我们才认为:如果你使用对象语言,如Java/.NET/Ruby On Rails等,那么就必须坚持OO思想和方法,从程序中杜绝关系数据库对软件的影响,将关系数据库只看成是活动对象的“冬眠”(英文Hibernate)地方,这也就是ORM框架Hibernate的本义所在。
分享到:
相关推荐
对象技术强调耦合、聚合和封装,而关系数据库则是基于数学的集合论原理,两者理论基础不同,导致在实际应用中存在“阻抗不匹配”。这种不匹配体现在访问方式上:对象通常是通过它们的关系来访问,而关系数据库则通过...
面向对象数据库技术是一种为了应对传统关系数据库在处理复杂数据结构和对象关系时的局限性而发展起来的第三代数据库系统。这种技术将面向对象编程的概念,如类、对象、继承、封装和多态性,融入了数据库管理系统中,...
### 将对象映射到关系数据库详解 #### 一、引言 随着现代软件开发项目的不断...通过理解不同的映射策略和技术,开发人员可以有效地克服对象模型与关系数据库模型之间的阻抗失配问题,构建出高性能且易于维护的系统。
面向对象和非面向对象这两种技术存在着阻抗不匹配(impedancemismatch),因为对象由数据和行为组成,而一个关系型数据库则是由表和它们之间的关系组成的。虽然不可能完全消除这个阻抗不匹配,你可以遵循适当的模式...
它结合了对象数据库和关系数据库的优点,能够提供高效的数据存储和处理能力,特别适用于大规模应用和高性能需求的场景。 #### 2. Caché的独特架构 ##### 2.1 架构概述 Caché的核心优势在于其独特的架构设计。...
阻抗设计主要涉及单端阻抗设计、差分阻抗设计和共面阻抗设计三个方面。阻抗设计的目的在于确保电子器件传输信号线中高频信号或电磁波在传播过程中的稳定性,减少信号损失和干扰,提高信号完整性。 #### 三、单端...
特性阻抗和差分阻抗是PCB设计中至关重要的概念,主要涉及到信号传输的完整性和质量。特性阻抗(Z0)是指单根信号线在传输信号时呈现出的等效阻抗,它决定了信号在传输过程中的反射程度。一个理想的PCB走线应该具有...
### 阻抗变换和阻抗匹配的理解 #### 一、引言 在电子工程领域,阻抗匹配是一项至关重要的技术,特别是在无线电通信系统、音频系统以及任何涉及到信号传输的应用中。良好的阻抗匹配可以确保最大功率传输到负载,同时...
### 将对象映射到关系数据库 #### 对象与关系映射(O/R Mapping)详解 在现代商业应用开发中,面向对象技术...通过选择合适的映射策略、实现方式和性能调优措施,可以有效地解决对象与关系型数据库之间的阻抗失配问题。
### 电路的输入阻抗和输出阻抗 #### 一、输入阻抗 输入阻抗是衡量一个电路在其输入端口等效呈现出来的阻抗值。简单来说,当我们向电路的输入端施加一个电压\( U \),并测量通过该端口的电流\( I \),那么输入阻抗\...
阻抗匹配是指使源阻抗、传输线阻抗和负载阻抗相等的过程,目的是最大限度地减少信号反射,提高能量传输效率。在高速数字信号传输中,阻抗匹配尤为重要,因为它能有效降低信号的上升时间和下降时间,减少电磁辐射,...
总结来说,阻抗控制模型和恒阻抗模型在机械臂控制中扮演着至关重要的角色,它们能确保在与环境交互时维持恒定的力反馈,从而提高操作的精确性和稳定性。MATLAB作为强大的数学和工程计算软件,提供了实现和验证这些...
然而,对于高精度和高性能的通信设备、微波器件或者高速数字电路,理解特性阻抗与频率的关系至关重要,因为这可能影响信号的完整性和反射,从而影响系统的性能。 总的来说,特性阻抗与频率的关系是基于电磁理论,...
波阻抗反演涉及到的关键概念包括地震反演、地震记录、地震反射系数、反射系数阻抗和波阻抗本身。 首先,地震反演是地质学家用来解析地下结构的一种方法。它基于地震波在地壳中的传播特性,通过反向推算来重建地下的...
这三篇文献分别是“Hogan1985_implementation.pdf”、“Hogan1985_applications.pdf”和“Hogan1985_theory.pdf”,它们共同构建了一个完整的阻抗控制理论框架,并提供了实践指导。 阻抗控制是电子工程领域中的一项...
综上所述,对象关系模型是数据库技术领域中一项重要的进步,它通过有效地结合关系型数据库和面向对象开发方法的优点,解决了两者之间的阻抗不匹配问题,并为构建复杂系统提供了一种全新的解决方案。
这可能涉及到调整元件的尺寸、形状、材料,或者使用阻抗变换器来改善源阻抗和负载阻抗之间的匹配。通过精确计算和实验验证,可以逐步减小VSWR,从而提高系统的功率传输效率和信号质量。 总之,驻波比是评估和改善...