日期:2009-07-29  浏览次数:21199 次

企业级N Tier体系结构解决方案讨论
--NT+SQL Server plantform篇
Writen by pepper_dog999

    关于企业级的数据库结合前台应用程序的解决方案现在成为了整个网络应用的热点问题。很多企业在选择解决的方案
时常会考虑的问题可以归结为三个h,即High performance、High security、High transaction solution。我的这篇文章
意在比较业界流行的几种解决方案之间的优缺点和可行性,本篇讨论的是微软的解决方案。
首先我们在这里不去讨论常规的Server/Client模式,也就是2-Tier模式,虽然这种模式的应用最为广泛,但由于对于企业
级的需求来说,这种模式的performance和security都不能达到要求,所以我们主要讨论的是N>=3 的情况,也就是
Database Server/Application Server/Client的模式。至于Distribution Transaction的情况我们暂时不做讨论。
在这里我首先提出我的一个看法,那就是现在大部分的方案开发者都走入了一个误区,那就是将工作的重点和大部分的精
力放在了3-tier体系结构中的第二层,也就是App Server上,由于整个业界不断的推出新的中间层解决方案,从perl到ASP
到PHP到isapi到现在的JSP,所以开发者的大部分时间和精力都用来熟悉新的解决方案和对比各种方案的优缺点上。诚然,
好的中间层解决方案能够提供更高的性能和安全性,也就是前面三h中的前两个。但是这是在小量数据的时候(tiny
data),那么当大量或者是海量数据出现的时候呢?这里我想借用硬件中常用的一个术语--瓶颈(bottle neck),大家都知
道瓶颈是制约整个体系的最慢的部分,当海量数据出现时,整个3 Tier体系中的瓶颈就成了该体系中的第一层,即
database Server,而在企业级应用中,我想可能以第二种情况为多。大概二者性能影响的比例应该为4:1吧,而且数据量
越大这个比例也就越大了,这也是数据库产品的售价远高于应用程序的原因吧(笑)。现在较高级的数据库产品如SQL
Server、Oracle等都将Autentication、Performance、Transaction紧密的结合在了它们的产品中,那我们的开发重点是否
也应该相应的放在database Server端呢?而在app Server端只是几个简单的调用过程和参数的传递过程,那么app Server
端用哪一种方案就不再是一个很重要的问题了。我觉得是越简单越好,为什么不呢?非要去用isapi吗?这样的话开发的重
点不就本末倒置了吗?如果从开发成本/性能效益的角度来分析的话,那就大大的不值得了。所以我觉得与其将大量的精力
放在前台的app Server上,不如将更多的工作重点放在后台数据库的设计、开发上,将核心的处理过程都转移到database
Server上。将精力用在数据库的合理设计,数据库中实体之间的关系,索引的合理配给等方面。例如2NF、3NF的实现哪,
表中仄余column的分析上啊。我的几位同学都在做这样的项目,他们的程序不能说不好,所用的技术也是日新月异,可他
们数据库的设计可就实在不怎么样了。各个表之间的关系混乱、大量的仄余column,我想这可能是因为他们没有从一个总
体的角度去考虑问题吧,而且一个整体的解决方案需要对各个层次都有所了解,这也是不太容易达到的了。周星弛在大话
西游中说"斗鸡眼其实与常人没什么不同,只是看事物的方法不同罢了,是将视线和注意力放在事物的某一点罢了。"但我
们在项目的总体开发上却不能这样,要不然对项目的可行性分析和总体的考虑还有什么意义呢?前面我说的我的那几位同
学他们的后台数据库也多是SQL Server和Oracle。但他们并没有去发挥这些产品的特性。比如说他们在SQL Server上建立
了一个员工的信息数据库,其中有一个表(member_info)用于保存员工的信息。为了获得该表的数据他们在app Server端写
了如下的语句:
conn.ConnectionString="Driver={SQL Server};Server=sev1;uid=user_name;
                           pwd=password;database=member_database"
conn.open
rs.ActiveConnection=conn
strSQL="select member_ID,address,fri_name,lsr_name…… from member_info
            where……";
rs.open strSQL,conn,,,adCmdText
好了,目的是达到了,但重要的信息也都泄露了。用户名(user_name)、密码(password)、连接的数据库服务器(sev1)、
数据库名(member_database)、该数据库下的表名(member_info)、甚至该表的各个Column名都知道了,是的,ASP是不允许
看到原代码的。但ASP的漏洞大家都知道的。若它用了SSL还好,否则就是整裸体一个了。也许你会说:"我可以只给
user_name用户Grant一个最小的权限,那它就不能为所欲为了,是的,但一个Select权限总得有吧。若该表上有很多的敏
感信息,而你只想让用户看到部分的Column那怎么办呢?那你就一个Column一个Column的去赋予权限好了。但现在很多的
开发者对数据库的设计并不在行,有些又将开发的工作分给了不同的人做,那么在思想的统一上又出现了问题。所以根本
不会考虑很多的问题。我还见过有人在uid字段填个sa,在pwd字段填个""(NULL),哈,开发真的方便了,那我看你还是将
你的数据库设为"dbo use only "吧!·那我们用SQL Server和Oracle上都有的Stored Procedure来做呢?
Create Procedure usp_show_info
@memberID int
……
As
select member_ID,address,fri_name,lsr_name……
from member_info where……
我们仅给db_user一个Execute该Procedure的权限,那么它就只能执行该Procedure,对于表的权限它什么也没有。而且
Procedure是放在database端上的预编译过程,该用户连表名都不知道了,他怎么直接操作表呢?只要不发生权限的断链就
一点问题都没有了。至于性能和可重用性大家也都看得明白拉。前台的调用过程就几句:
comm.CommandType=cmdStoredProcedure
comm..CommandText="usp_show_info"
如果我们在App Server端再加个SSL的话,那就有两层的安全保障了。再不放心,用JSP将原代码编译得了。至于只想显示
一部分的表项,那更好办,SQL Server和Oracle中都有View的概念,然后将Procedure操作于view上,我们看看它的关系链
table-&