Linux中国 Linux中国门户站!
设为主页 设为主页
收藏本站 收藏本站
 
当前位置 :首页 ->Linux技术 ->系统管理 ->正文

对象/关系映射--概述

来源:Linux-cn.com 作者:Webmaster 时间:2007-05-05 点击: [收藏] [投稿]

摘要

一方面使用面向对象的编程语言,另一方面又由于某些原因不使用面向对象数据库,而改用关系型数据库。这种情形存在一天,我们就需要考虑对象到表的映射问题。对象到表的映射问题只是对象/关系访问层中的一种问题,在这篇文章中,我们只考虑对象到表的映射问题。

简介

面向对象技术已经成为软件开发的一种趋势,越来越多的人开始了解、学习和使用面向对象技术。而大多数的面向对象技术都只是解决了内存中的面向对象的问题。但是鲜有提到持久性的面向对象问题。

面向对象的持久性对于大部分的应用来说是使用数据库技术和文件技术。这里我们只考虑数据库技术,在数据库技术中,关系型数据库技术又是其中最有影响的技术,这里的影响包括使用的广泛性以及数据库厂商的支持程度。虽然,对于面向对象技术来说,使用同种类型的面向对象数据库是实现持久性机制的最好选择,但是目前我们却不得不根据实际情况来考虑:可能你会选择一种成熟的关系型数据库技术,可能你需要配合目前已经在运行的老的关系型数据库,可能你把价格因素纳入考虑的范围。种种的因素都可能导致你同时选择了面向对象技术和关系型数据库技术。

面向对象设计的机制与关系模型有很大的不同,这造成了面向对象设计与关系数据库设计之间的不匹配。面向对象设计基于如耦合、聚合、封装等理论,而关系模型基于数学原理。不同的理论基础导致了不同的优缺点。对象模型侧重于使用包含数据和行为的对象来构建应用程序;关系模型则主要针对于数据的存储。

面向对象和关系模型可以说是完全不同的编程模式。当对象需要保存在关系型数据库中的时候,代沟就出现了,此时我们需要的是在它们之间架起联系的桥梁。如果说我们的问题只是集中在数据映射的问题上,那么我们并不会如此的头疼。除此之外,还有面向对象编程中的许多概念需要映射到关系型的表结构中。它们包括:

  1. 聚合(Aggregation)
  2. 继承(inheritance)和多态(polymorphism)
  3. 类间的关联(association)
  4. 比SQL数据类型更加灵活的数据类型

以上的每个概念都会有不同的解决方法,我们将会把它们组织成为独立的模式。模式的组织形式允许我们思考解决方法的因果关系,有助于思考思考通常的约束(下面会列出)。数据类型映射比较复杂,未来如果有机会的话我们再讨论它。

一般约束

  1. 性能:在把对象映射到表时,性能将是最主要的考虑因素。对象映射到表的方式将会对数据库访问的次数有显著的影响。数据库访问通常是在磁盘上或其它外部媒介上执行,它们的访问时间数量级大约在毫秒级,而CPU的处理周期是在纳秒级。因此,较好的做法时浪费一些存储周期和内存空间,来提高慢速IO的性能。其中有一些做法是计算机可以自己做的,例如Cache、DMA方式等等,有一些则需要我们通过编程来手动处理,减少对数据库的访问次数,例如延迟读、为数据置标志位等等。

    这里我们简单的讨论一下延迟读和数据标志位技术。延迟读的核心思想是假定用户不需要访问所有的数据。比如说,用户访问的数据分别存放在A、B两个表中,但是用户需要知道的主要的数据放在A表,而放在B表的数据的访问可能性只有30%左右。A、B两个表之间通过外键相连。如果我们在每次用户访问的时候都同时读入A表和B表的内容,很明显我们需要两次访问数据库(或是通过连接)。另一种做法是用户访问时只打开A表,而B表的部分暂时不读取,只有当用户发出明确的请求,例如点击某个字段时才执行读取B表的操作。这样平均的访问次数就可以计算出来,如果我们明确的知道访问的概率的话,甚至可以量化的计算出平均访问次数来。这种做法就称为延迟读,这种技术在日常的应用非常的广泛,例如我们在操纵Word文档的时候,就可以发现它的图片一开始都不显示,这其实就是延迟读。延迟读的设计可以参考设计模式中的Proxy模式。

    数据标志位的主要目的是为了减少内存和磁盘间的IO开销。一般来说,从数据库读入到内存中的数据,不论有没有修改,最后都需要全部写回到数据库中。这是最简单、最通常,但也是最糟糕的做法。一个100K的数据可能只有1K的数据发生了改动,但却不得不写入99K的额外数据。可以考虑为每一行,甚至每个字段的数据甚至修改位,然后根据修改位的状态来选择性的写回数据库。这听起来似乎很麻烦,但所幸的是,目前的很多编程平台中都提供了这种做法。你直接用就可以了。

  2. 读性能和写/更新性能:我们即将谈到的解决方案中在读性能和写/更新性能方面有着不同的特色。某些映射允许在单词的数据库访问中读取所有数据,而用多次的数据库操作来写入一个对象,这是继承映射。因此在确定表设计之前,需要确保了解读和写/更新操作的频率。
  3. 弹性和维护成本:有时你打算在原型开发过程中引入数据库映射,这种情况下弹性就要比性能更为重要,因为你需要插入和删除属性,增加和删除类。以及重新组织类层次。一旦层次和类稳定之后,你就可以把映射调整到最佳的性能。
  4. 性能和冗余/维护成本和一般窗体:通过使用一般窗体和因式分解,关系运算能够帮助你消除冗余。另一方面,关系数据库应用在数据库访问次数最小时才可以表现出最好的性能。最大开销包括对特定记录的寻道时间,以及找到记录后的传送时间。因此如果能够在单次的数据访问中获得所有的用例所需数据,或是命中数据所在簇,那么效率机会提高。

    1. 可以通过放弃使用因式分解和一般窗体的方法来减少数据库的访问次数,但这会对应用的可维护性产生负面的影响。
    2. 可以通过数据库管理改变簇的分布。

    数据库的可维护性和性能是两个相互冲突的目标。所以呢,在优化数据模型性能的同时,改变应用的维护成本也在上升。冗余和其它各种各样的不规则,都会限制一般窗体的使用,因此需要考虑维护的因素。

  5. 空间消耗/性能:某些映射不会浪费数据库空间(类似于空值字段),另一些则需要大量无用的数据库记录。毫无疑问,空间的浪费将会提高性能。
  6. 查询处理:由于数据同时必须服务于信息系统,因此数据的安排上有两种相互冲突的目的。

    1. 数据需要配合事务处理,以获得最佳性能。这就意味着需要重新组织数据。

       如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<



      上一篇:Linux怎样做计费服务器   下一篇:对象/关系映射--聚合模式

      文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论
更多相关文章
Power by linux-cn.com 粤ICP备05006655号