实现自己的O/R Mapping组件[二]-问题关注:昂贵的字段

前言
       灵感来自于很久以前对Foxpro的数据库结构研究:在FoxPro中,数据库中的表,是采用的表定义表的方式进行的,就我关心的而言表一般分为两类,一种定义表,一种是实体表,其中实体表中的数据存储是通过定义表来实现的,如果你需要修改表中的字段(例如添加与删除或修改),有非常简单的手段,只用修改定义表的形式来进行。这使得字段的代价大大地降低了。上世纪90年左右的时候,一位老工程师就用Foxbase做了充分利用这个特性的财务系统,里面的所有单据、报表、软件界面都是可以在程序运行时再定义再修改再使用的。时至今日,考察他当年的系统,会发现他所做的工作就是现在ERP系统实现的基础,并且完全拥有了实现ERP系统的根基,可惜因为机缘问题,他的系统没有在国内进行应用。就ERP系统的实现来说(非思想层次),这方面我认为他无愧为国内第一人,很有幸偶然认识这位老工程师,他是一个慈祥而幽默的老人,在许多方面给了我启迪。

正文
  以往的数据库开发,面向于基本的关系型数据库,最头痛的莫过于增加一个字段或删除一个字段,因为这往往带来的不仅是数据访问的问题,往往会带来一系列的业务规则的改变。
  就业务规则不谈,哪怕是更改了一个字段类型的话,起码软件中所有与此字段相关数据验证代码就需要更改,如果更不幸地使用了触发器、存储过程的话,这个更改将带来灾难性的后果,影响尤如滚雪球一样会越滚越大。
  在某些业务处理过程中,可能需要进行字段的自由添加与删除,比如国内常见的工资管理系统,每个单位或企业对于工资的发放都有不同的名目,一般情况下,为了处理这种情况,需要制作一个可自定义的表来灵活管理。
  在我想实现的O/R Mapping工具中,对于字段的变化要求有较强的适应能力。以往的O/R Mapping组件,支持从代码到数据库表的自动生成,当然也包括表与字段。但这并没有解决好字段更改的问题。要想对字段有效地管理,是一个比较困难的工作,现在的开发工具也没有很好地支持这一点。
      在构想的工具中,需要重现表定义表的方式来降低数据库字段的代价。NHibernate中,采用的xml的方式对表的字段进行描述,这实际上就是一种定义的体现,当然,在类似的ObjectSpace中,也采用了xml的描述方式。
      我不太想使用xml,首先,采用xml的描述方式,很难进行并行开发,每个人如果对xml文档进行了修改,必须要对大家进行发布,这个上传与下载进行同步的过程是毫无意义的时间浪费;其次,xml的性能比较低,在.net中,尽管你可以采用xml命名空间下的类对它进行操作,从而提高效率,但我还是觉得DataSet.ReadXml()更方便一些。还有,xml最大的特色在于它丰富的描述形式上,这个对我来说没有什么作用,数据库中的描述,可以用比较简单的手段进行表达,何苦呢?
      所以,映射数据信息我计划储存在开发对象的数据库中(目前还没有确定,希望得到大家的意见后再说)。
  
      在组件中处理时,需要区别开发模式与正式使用模式,类似于Debug和Release的模式。
      这个O/R Mapping工具应该提供开发过程中的不断重构与修改的支持,因为在组件中要对历史开发进行一个简单的版本控制功能。具体构思如下:
      当开发者,添加了一个字段时,并不立即更新表,而是创建一个新表,里面存放新的字段。如果一次性创建了多个字段,则创建一张表放这多个字段,并且自动记录定义主表与新建表中的关系(一对一)。这样可以达到类似于PhotoShop中,新建一个层的目的,查询、维护、更新、修改,也自动维护;对于修改过的字段,采用自定义的日志表中进行记录;删除的字段,则不删除后来创建的表,先进行一个记录。如果是对于原有列的修改,也通过日志的方式进行记录,方便日后回滚,当然,这些处理是在开发阶段进行的,到正式release阶段或中间的合并阶段时,让开发者选择哪些一对一表是需要合并的,这样的话,可以更灵活地处理,并且以后的无论是添加还是剪裁上都比较方便。
      这样处理还有一个好处,就是对数据库的修改过程进行了版本上的控制,可以支持在开发中的不断重构,这不可以促进开发人员在开发过程中,对元数据表进行更精细的控制,同时也能够在开发过程中,让开发人员可以定制几种合并方案,
  
  添加一个字段,带来的还有一些问题就是数据验证代码与该字段的空值问题,我打算在添加一个字段时,就在数据访问层次及业务规则层实现数据验证机制,其中数据访问层仅对空值及值域范围进行控制。而业务层则是用户自定的义代码验证,对于简单的验证,可以选择组件中的预定义方案,并进行简单的配置,自动产生验证代码。

posted @ 2005-03-25 19:32 一根神棍研古今 阅读(2383) 评论(6)  编辑 收藏

 回复 引用 查看   
#1楼2005-03-26 06:43 | 生活、工作      
思路不错,不知有没有更好的,xml文档描述的数据结构放到数据库中,我估计很多实现orm的人都想过,但也有缺点,不如修改时,在某些时候可能不如xml.
 回复 引用 查看   
#2楼2005-03-26 09:14 | progame      
这种维护在有些orm中已经实现了 如dataobjects.net 但更好的解决方案是sharepoint中的定义方式,不过这也使得一些规则必须在客户端完成,而以数据库为中心的应用中,这样有时候是不允许的

要实现对客户端访问的透明化,有两个方法,view和客户端脚本的解析转换,前者在很多情况下不被数据库平台支持(可更新的VIEW),后者对于DBA的维护,数据库的备份、DTS、迁移都不便

而使用多表联接的方式(在对实体类继承的映射中,我首选这个方式),同样会碰到上面两个问题

说到分debug和release两种方式,这也是我persistore中的一个准则,设计期是class->db,支持更新,不使用外键约束,而发布时是db->class,一切从数据的完整性,性能的最优化(查询密集的冗余和更新频繁的精简)考虑。

最后说一下,从对象化出发最后生成的数据库在MIS中是一种灾难。

 回复 引用   
#3楼2005-03-26 13:13 | 寒枫天伤
to progame:
谢谢指教,不过,有一个小问题还需要请教一下:"设计期是class->db,支持更新,不使用外键约束",为什么在设计期不考虑外键约束?

 回复 引用 查看   
#4楼2005-03-28 09:07 | 听棠.NET      
楼主,对于你说的不喜欢采用XML,那么,就算你新建了一个表,这些新字段是动态生成进去的,那么对于ORM来说,此表的实体映射类怎么办??难道要动态生成一个实体类与之对应?动态类如何进行自动编译?
这个问题,我也考虑过的,如果楼主能解决实体类的问题,那楼主的思想是可行的。
对于自定义字段,我想这应试就能归咎于ORM模型里了,而应该是一个业务设计的问题了,比如订单表中,我们可以预留10个字段,然后要新增字段时,用另一个表来记录新字段的情况,比如字段的名称,对应表中的字段名,这种方式不会引起所谓的实体类重写。

 回复 引用 查看   
#5楼2005-03-29 09:00 | bigtall      
可惜,大型数据库好像没有提供类似于foxpro的 GetRecordByIndex的功能,否则就更爽了
 回复 引用   
#6楼2007-07-06 00:12 | 独孤青[未注册用户]
经过整理后的中国.net技术交流社区的所有技术群
现在共享出来,没完整的地方希望知道的朋友帮忙补上。
不用担心群满了,管理员会提示你哪个群有空位,所以随便加一个就OK。嘿嘿~~希望热爱编程的朋友喜欢!!

CNNTEC技术交流01 群号:855762
CNNTEC技术交流02 群号:3462286
CNNTEC技术交流03 群号:1369511
CNNTEC技术交流04 群号:12902496
CNNTEC技术交流05 群号:40618583
CNNTEC技术交流06 群号:40618647
CNNTEC技术交流07 群号:40618672
CNNTEC技术交流08 群号:????????
CNNTEC技术交流09 群号:15050602
CNNTEC技术交流10 群号:40670835
CNNTEC技术交流11 群号:40671196
CNNTEC技术交流12 群号:40340875
CNNTEC技术交流13 群号:23755440
CNNTEC技术交流14 群号:18547557
CNNTEC技术交流15 群号:40832236
CNNTEC技术交流16 群号:40832436
CNNTEC技术交流17 群号:40832531
CNNTEC技术交流18 群号:10664213
CNNTEC技术交流19 群号:17642421
CNNTEC技术交流20 群号:40890624
CNNTEC技术交流21 群号:40890660
CNNTEC技术交流22 群号:40899193
CNNTEC技术交流23 群号:36043801
CNNTEC技术交流24 群号:29466214
CNNTEC技术交流25 群号:????????
CNNTEC技术交流26 群号:????????
CNNTEC技术交流27 群号:40914616
CNNTEC技术交流28 群号:40914866
CNNTEC技术交流29 群号:40914418
CNNTEC技术交流30 群号:????????
CNNTEC技术交流31 群号:32171303
CNNTEC技术交流32 群号:41031518
CNNTEC技术交流33 群号:19346035
CNNTEC技术交流34 群号:????????
CNNTEC信息交流 群号:7654306---职场信息交流、聊天、交友。

公告

昵称:一根神棍研古今
园龄:7年10个月
粉丝:14
关注:1
Web Counter