您的位置:首页 > 数据库

基于数据库的应用程序架构设计原则

2010-06-02 11:22 183 查看
基于数据库的应用程序基础架构设计原则

一、数据库系统在数据库应用程序中的定位

虽然各个数据库系统提供了丰富多彩的功能和特性,包括大部分数据库系统都会提供存储过程、触发器、约束、自定义函数等功能,而且也有很多人使用它们来开发各种各样的程序。但是,我们认为,数据库系统应当只充当存储工具和数据管理工具。存储工具是指我们只应当使用它的数据存储和查询功能,管理工具是给DBA使用,用来优化、维护数据库之用。而一般业务逻辑,不应当在数据库系统中实现,包括使用存储过程、触发器、约束、自定义函数等特性。
所以,不管是Sql Server、Oracle、MySql、SqlCE,还是SQLite、firebird、PostgreSql、berkeley db,甚至是Access、Excel文件,都一样只是数据的存储工具而已。
备注:多年前,笔者曾经使用了很久时间的存储过程作为数据访问层代码,所有SQL语句都在存储过程中,程序中没有出现任何一个sql语句。这个框架在web开发中用了很多年。但是,当有一天,我想开发一个单机版的数据库应用程序,对数据库选型做了很久的比较,发现如果我还用这个方法,那么可选的数据库只有Sql Server Express。而Sql Server Express部署到客户端的成本(包括下载、安装时间、维护)都是巨大的。如果当时只是将数据库作为存储工具,而没有将数据访问层代码放在数据库中的话,我大可选择SQLite等嵌入式小型数据库系统,要知道SQLite整个数据库引擎系统也只不过两三百K。

二、可移植性

一个优秀的数据库应用程序的基础框架(即数据访问基础框架),应当考虑到可移植性。即数据库的异构性,如:从Sql Server移植到Oracle,或者从SqlServer移植到MySql等。虽然对于大多数应用来说,移植数据库免不了或多或少地修改程序,但一个好的数据访问框架,可让移植成为可能,且移植所带来的成本尽可能地低,移植过程更加可控。使用第三方的框架(如hibernate和Ado.Net Entity Framework),如果完全使用HQL,而不使用SQL查询,甚至可以不用修改程序,只修改配置,就可以达到迁移的目的(当然这只是理想状态下)。
可移植性设计的第一个原则,对于可移植性的数据库系统设计,数据库的类型,或者数据库驱动类型(如jdbc驱动的类),应当是可配置的,而不是在程序中硬编码。hibernate和nhibernate就是通过hibernate.cfg.xml文件,配置数据库的类型和数据库连接。
可移植性的第二个原则,就是在教导程序员开发中尽可能使用标准的SQL92语句进行查询和数据操作。因为这样能使SQL语句的兼容性更强,从而减少移植成本。同时,尽量减少存储过程的使用。

三、可伸缩性

数据库应用程序的可伸缩性,是指可以通过管理配置的手段,在不改动或很少改动系统的情况下,快速对系统进行分布式部署、优化。这对于一个正在运行的项目,某天遇到数据库性能、存储瓶颈时,快速有效地通过增加服务器的方法,将其中的一部分表,移植到新的数据库服务器上。这个移植对程序应当是透明的,不需要修改程序,通过修改配置的方式,即可将部分表拆出。另外,对于某些大型应用,还应可以通过数据库镜像手段,将数据库的读和写操作分别指向到两个不同的数据库服务器上。
可伸缩性对于应用开发有一些要求,其中最主要的要求,就是表与表之间应当是松耦合的关系。即对于有可能拆离到不同库的两个表,在程序中不应当通过join以及子查询的方式,在同一个语句中联合两个表进行查询。而应当通过两次不同查询,分别取到数据后在程序中做比对。另外,对于通过数据库实现的事务,事务中所涉及的多个表,也不太适合这种可伸缩性应用(如订单和订单明细表),除非在设计该项事务时,采用的是分布式事务。

四、错误日志记录

对于数据访问时发生的错误,不论是服务器连接失败,还是SQL语句超时、语法错误,都应当有一个有效的错误日志记录机制,以便运营、开发,随时发现并解决在开发、测试和正式运营过程中所发现的与数据库有关的问题。
虽然有很多手段,如系统日志,可以自动记录程序中未被捕获的异常,同时,有部分系统架构中,也有统一处理异常的地方。但一方面,这些异常很多情况下信息量太大,查找困难,另一方面,作为系统架构师,应当在数据访问架构增加一个记录日志的选项。

五、可配置性

不管是什么理由,正式项目的数据库连接串,都不应当硬编码在程序中。因为如果这么做了,更改数据库密码、地址、帐号等信息时,都需要重新修改并发布程序。
或许有人认为我上面的话有点多余,因为现在几乎没有一个程序员会这么干,大家都知道应当将连接或者include在别的文件中,或者使用配置文件。但是,我想说的,不仅仅是数据库连接,而是与数据库有关的所有设置信息,都尽可能通过配置的手段来修改。
与数据库相关的配置,我认为,应至少包含如下项目:
1、数据库连接串
2、数据库类型:对应的连接串用的是Sql Server、MySql还是Oracle等关系型数据库。
3、连接串加密:大多数生产环境,网管与DBA是分开的。有时候运营需要网管不能获取数据库真实连接串,而应由DBA提供加密后的连接串,所以,配置中应提供对数据库连接串的加密方法。
4、错误日志审核:如上面提到的,一个好的数据访问架构,应当提供错误日志的选项。选项应当规定是否记录错误日志、记录在哪里、日志文件生成规则等。

六、透明的连接管理

数据库连接管理,包括数据库连接的打开和关闭、连接池的管理等,对于程序员来说,都应当是透明的。数据库连接资源是有限的宝贵的资源,一旦没有正确释放,将对数据库系统和应用程序都会造成灾难。而作为公司的架构师和技术团队管理者而言,不能只依赖于程序员的素质和自觉,以及编程习惯来解决数据库连接的关闭问题。所以,一个基本的数据库应用基础框架中,应当对程序员封装数据库打开和关闭的接口,让框架自动管理连接,而不是让程序员来管理连接。

七、可控制性

对于大型数据库应用系统或网站来说,开发和生产运营过程中,程序员往往需要配合DBA,对系统中的每个细节进行优化,主要是SQL语句查询优化、索引优化、分页优化等。同时,对于应当缓存的数据,也应严格控制缓存的内容、范围、数量、大小、缓存策略等。也就是说,对于系统中出现的每个问题、可能出现的问题,都要能做到精确控制。
很多初学者喜欢使用.net或者vb中的数据控件拖拽控件来编写一个数据库访问程序。虽然说做到了傻瓜化,但这种操作对程序员太过透明,以至于大多程序员即使做出了程序,对很多问题还是一知半解,出了问题更不知道从何入手去解决。微软新出的ADO.NET Entity framework也好像有“异曲同工”之妙。我访问过几个使用了ADO.NET Entity framework的朋友,他们大多数都说EF好,方便使用,但是问到它执行操作时的实际语句、缓存机制等问题,好像还没见谁真正去研究过,哪怕只是简单地在Sql Server Profile中捕获一下语句。对一个稳定性、维护响应要求较高的系统来说,出现这么多未知的,不可控的问题,是很可怕的。

八、简单易懂

开发不是一个人的事,更不是架构师或项目经理、开发经理的事情。合理的架构设计、简单的数据访问类封装、有效的代码生成工具,可大幅度提高开发效率,降低错误率。同时,应使数据库开发架构尽可能简单,尽可能没有歧义,尽可能不给开发人员太多的选择,尽量不需要让开发人员在数据访问的问题上做太多思考和选择。即使是一个没有太多经验的程序员,在一两个小时的学习后,也应当能按部就班地根据你的范例代码,使用你的数据库访问架构进行快速的数据库应用程序开发。

九、支持事务处理

事务处理的重要性不必再多说。要么支持分布式事务,要么支持数据库的事务。当然不是指存储过程中的事务。

数据库设计与开发的四大原则

一、避免使用约束

前面文说到,我们认为,数据库系统只是用于数据存储的工具,所以,应当在应用程序中处理数据的完整性与合法性,而不是使用约束。另外,为了确保数据访问的性能,同时,也为了提高可移植性、伸缩性等,数据库中不应当建立外键约束、范围约束等。

二、尽可能使用最基本的数据类型

为了提高数据库的移植性,数据库字段类型应当选用最常用的类型。如varchar、smallint、int、bigint、decimal、datetime、bit(bool)、text等。避免使用polygram(mysql)、binary等非通用类型。

三、适当的冗余设计

对于部分应用需求,或查询需求,不能完全按照数据库第三范式设计思路进行数据库设计。如:订单表中需要记录下单时收货人的姓名、地址、电话,而不是记录收货人的编号。因为下单后,即使收货人表中名址、电话发生变化,也不应当影响到已下订单的信息。同时,在订单表与收货人表数据较大的情况下,根据收货人姓名或电话查询订单,冗余设计(单表查询)比范式设计(需要join查询)要快得多。

四、尽量降低表间藕合度

降低表间耦合度,是基于数据库的可伸缩性考虑。在程序中,如果有可能,则应尽量避免使用join和子查询,从两个不同的表中一次性获取数据,取而代之的是分别从两个表获取数据,在应用程序中做比对和处理。

五、有效的时间戳设计和审计日志

在数据创建、更新、删除等操作发生时,都应当设置一个恰当的时间戳(timestamp),以标记该记录最后的修改时间。对于重要的信息和敏感的操作,还应当记录操作发生时间、地点、操作人、操作内容等信息。

六、尽量做逻辑删除

大部分业务数据,都应当保存。一般情况下,删除记录时,不应当从数据库中物理删除,而是应当设置删除标记位,或者将记录移动到其它表中。当然,这个原则并不是原则,仅作为参考建议,是否实施该原则,要看实际应用,以及IT审计对被删除记录的敏感度。

上述观点是我及我的开发团队在多年的经验中摸索总结出来的经验,每个IT开发公司都有一套自己的开发架构、规范和习惯,都有自己的优点。希望大家共同探讨。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐