随笔 - 181  文章 - 15  trackbacks - 0
<2009年4月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

常用链接

留言簿(1)

随笔分类

随笔档案

My Tech blog

搜索

  •  

最新评论

阅读排行榜

评论排行榜

1、数据库与面向对象编程语言的不同
关系数据库的关注点是数据结构的声明。这样的话一些封装手段就不可用了。没有封装,数据访问就不会被明显的约束。
表是通过外键关联的。这同样不能够被封装。
存在于数据库中的数据是持久化的,并且存活得比程序要长。数据库的结构一旦发生变化,数据就要进行迁徙。

如果系统被多次安装,那么就会有不同的数据库。那么如果数据库结构发生变化,这个变化同样要作用于每一份安装。

不同的用户可以同时访问数据,但是他们可以每人拥有一份程序的拷贝。

类可以继承,但数据不行。
源代码可以在本地进行维护和测试,之后发布到源代码管理服务器中。版本冲突可以被识别到,然后通过一些强有力的工具可以帮助解决这些问题。在大多数项目中,同一个数据库往往为多个开发人员服务。
维护源代码可以使用工具。数据库的结构和数据则只能够由人花更多的精力去维护。
访问数据库所花费的时间比起访问访问内存中对象的时间来要多上好几倍。

关系型数据库中的数据结构是浅层结构,然而当它们变成对象处于面向对象的系统中时,他们的含义变得更加深入,他们的关系变得更加错综复杂。

2程序与数据库打交道时产生的一些问题

当程序与数据库交互时,会产生这样一些问题:

程序与数据库之间的关联往往不是类型安全的(想象JDBC)。编译器无法评估程序与数据库是否结构性兼容。某些映射类和持久层把这些问题拿到了一边,却没有解决它们。类型安全性将会在影射类或持久层中失去,而不是其他的地方。

数据库将会“隐藏”一些对象。这种情况发生在对象被写入数据库或者在读取出来的地方。因此对象可以被程序的两个部分交换使用,而不需要显式得暴露于接口中。

大多数情况下往往采用表和对象一一对应的模式。这往往在强调数据的应用程序中是错误的做法。特别是当需要从数据库读取对象时,可能会需要多个表的极联,或者为了满足数据展示的需要,建立一些视图。结果,当数据库发生变化时,很难找到一个合适的途径来决定那些类也要跟着修改。反过来说,通常无法明确类的那些变化会影响到查询和视图。

还有一些琐碎的问题。数据库中的数据类型与程序语言中的基本数据类型之间的映射会造成一些困难。比如时间戳的尺度,采用浮点数尺度或采用string或变长字符串集合就会有相当大的差别。

在面向对象的系统当中,关联关系的建模是基于概念的(例如,账目和收支有关)。在关系数据库中,一对多关系和多对一关系都是适用的。所以也就无法找到一套确定的方案来实施重构。

因此我们在重构的时候需要着重考虑这样三个地方:

1)有关数据库结构、数据库模型的重构;

2)不同版本的数据库之间的数据迁移;

3)有关数据库访问代码的重构。

3重构关系数据库的数据库结构

在实践中,往往有一定数量的数据库模式平行存在。至少有两个模式:一个为开发者所使用(开发数据库)一个为用户所使用(产品数据库)。

因此开发者总是可以尝试着修改数据库而不去惊扰用户。只有当数据库被彻底的测试完成,并且适合于构建与其上的系统,这样才会将数据库、程序作为一个稳定版本提交给用户。

此外,每一个开发者应当拥有自己的数据库实例,这样他们才能够独立的测试他们对于数据库的一些变动而不会影响到开发团队的其他人员。这些不同版本数据库实例的存在使得数据的迁移变成了一个关键话题。在下面的部分,我们将会讨论这个话题。

“逐步进化”这样一个核心的原理不论在程序重构中还是数据结构的重构中都在重演着:老的结构并不会马上被新的所取代。新旧数据库结构往往会并存一段时间。老的数据库结构会被标记为“过期”以让那些新编写的程序不去访问它。然后已有的程序会被修改,一步又一步的向新数据库过渡。一旦这个过程结束,老的数据结构就算完成了它的使命,他会被终结然后删除。图5-1示出了表“Customer”的变革。一开始的时候,姓和名是作为一个字段存储的,他们合称作“Name”。现在姓和名会被存放在两个字段中,最后Name字段将被取代并被删除。

dbrefactor

在中间的状态,表Customer包含冗余字段Name。程序或触发器需要保障它们之间的一致性。

在Java中,你可以把那些过时的程序标记上“已过时”。但是在大多数数据库和其他程序开发语言中没有提供相关的功能。

在关系数据库中,字段、表、视图甚至整个数据库的结构都有可能需要被标记为“过时”,当然,这视具体的重构过程而定。我们往往通过访问层面的限制或提示来体现这些独立的“已过时”标注。比如我们使用O/R mapping工具来生成这些数据的映射类,那么对于这些类或方法我们就可以用“已过时”进行标记了。当然,前提就是你许诺不会通过其他的手段来直接访问数据库。如果确实这样,在你的下一个版本中使用这种方式标记“过时”的数据库结构也就足够了。

如果你无法保证对于数据库的访问只是通过O/R mapping的映射类,那么就和你的开发团队订立协议吧。列一张表,在这个表列举因为重构而过时的那些东西。当然所有的开发者都要同意这个表上列举的重构结果,并且能够去贯彻它。

dbrefactor2

 

Ambler在他的网站上收集了很多数据库中会被频繁用到的重构方法。这些重构方法为数据库重构提供了一些依据。

Ambler的重构方法的目的在于为数据库的结构带来改观。因而只是独立的添加一列并不能组成一次重构。独立的添加一列不能够给数据库结构带来任何的改观。

有这样几种形式的重构:重构而提升数据的质量;重构而优化数据的结构;重构而提高数据的性能;重构而整合数据;重构而优化数据库框架。

posted on 2007-08-10 22:47 littlegai 阅读(288) 评论(0)  编辑 收藏 引用 所属分类: 我的读书笔记

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理