基于中间件的查询优化模型
传统的客户/服务器模式是一种双层的结构,通常是一台个人计算机做客户机使用(运行客户端程序),另外一台服务器用于存放后台的数据库系统,应用程序可客户端直接相连,中间没有其他的逻辑。在MIS系统的软件开发过程中,查询数据是必不可少的一个重要部分,而如何帮助用户在数据库中进行快速而有效的查询数据是软件开发人员十分关心的事情。我从我做过的2个MIS系统中关于数据查询方面,大致总结出以下几种方法:
1. 固定结构方式:即程序员根据客户的业务要求定制客户端查询程序,这种定制的程序没有通用性。或者业务逻辑也存在于后台数据库中,以触发器(trigger)的方式实现。这种方式有一个很大的缺点,就是一旦客户的业务逻辑有所改变的话,将引起应用程序的修改以及后台触发器的修改,将所有程序模块都重新修改、编译、连接的工作量是相当大的。另外由于这种结构将用户界面和业务逻辑以及数据源绑定在一起,会消耗客户机的大量资源,对客户机来说是一个很大的负担。
2. 灵活结构方式:既除了使用固定查询命令以外,再做一些让系统管理人员可以修改查询命令的界面。也就是让系统管理人员可以编写
SQL语句的方式,这种方式虽然可以提高查询质量,但对与非专业的操作人员来讲,是很困难的。
3. 基于中间件的数据查询优化模型:本文就以中间件和分布式系统为理论基础,以曾经开发过的成都市康泰电器MIS系统为例介绍这种数据查询模型,相信它给用户提供了更方便和更快速的服务。
1. 什么是中间件:
为解决分布异构问题,人们提出了中间件(middleware)的概念。中间件是位于平台(硬件和操作系统)和应用之间的通用服务,如图3所示,这些服务具有标准的程序接口和协议。针对不同的操作系统和硬件平台,它们可以有符合接口和协议规范的多种实现。也许很难给中间件一个严格的定义,想了解的读者可以去http://www.huihoo.com/middleware/了解相关资料。
2. 开发人员在做查询模块的时候应该注意的问题:
一般来说,客户只关心他们所需要的数据和怎样查询出这些数据,而对与这条查询语句是和生成的,就不会关心了。举一个例子,一个库房管理系统,包括入库情况,出库情况和结存情况等等。客户只关心如何得到一个产品的出库数量,入库数量和当前的结存数量。而对于这个库房管理系统是如何生成,和查询语句的SQL代码和数据表,一律不感兴趣。以康泰电器MIS系统为例,它采用的是client/server结构,根据我对MIS系统的了解,只要应用系统的客户端数目在200个用户以内而且是在同一个局域网内,那么client/server结构在执行MIS系统就足够了。但是,众所周知client/server结构存在很多问题。既前面固定结构方式中所谈到的一些问题,导致它影响了数据库的执行效率。
加上近年来INTERNET/INTRANET应用的兴起,对于企业的运作方式有了重大的影响,康泰电器的企业主管要求开发产品查询的信息给所有在INTERNET/INTRANET上的潜在用户,所以MIS系统必须能够让客户使用浏览器来查询所有的产品信息,事实上系统结构已经进入了分布式的结构了。因为它多了一台WEB 服务器。以前的系统要提供INTERNET/INTRANET的存取形式时,旧的MIS系统必然以新的技术编写一次。这必然加大了开发人员的工作,也提高了成本。所以我想,只是由于多了B\S的查询方式,为什么不利用现在流行的中间件的思想开发一个新的查询模型呢?
3.查询系统的模型:
我通过分析一些查询的语句,了解到了他们的一些共同性,并且共同性比较
突出,因为他们不是离散出现的。比如所有关于库房查询的语句构成了库房管理查询系统,所有财务收支的查询语句构成了收支查询系统,我将查询的语句进行分类处理,structN_class={Table1,Table2…..Tablen};Datawarehouse={ struct 1_class, struct 2_class……structN_class}.而我就是要在structN_class上使用微软的DCOM 技术创建我们的查询系统。
它的主要技术特征是把查询语句和系统的界面完全分开,不是原来的client/server结构了,我把client分为2个部分,client和SelectCom-Server.。不管用户是在client端,还是在采用浏览器界面。把用户输入的查询条件和类别先提交到SelectCom-Server. SelectCom-Server.根据用户输入的查询条件和类别自动生成查询语句。然后把它们提交给数据库,最后数据库运行查询语句,再将查询 的数据交给SelectCom-Server. SelectCom-Server.在把数据返回给client端,这样就完成了查询工作。
我认为它的好处有以下几点:
由于SelectCom-Server.和client是分离的,那么一个用户使用过的查询条件可以被其它用户使用共享。这样使网络和数据库的开销大大降低了。还可以根据已经使用过的查询条件来缩小查询的范围。在由于我已经把深一级的权限加在了SelectCom-Server.上,它就可以拒绝一些核心数据的查询,提高了数据的安全性
也减轻了代码的从用性,因为这种分布式的系统,考虑安全性按照常规不仅要完善client/server结构,而且要完善B\S结构。再者,它还有利与系统管理人员的维护,他要排错就只需要对SelectCom-Server.上的查询语句进行分析。
4实现:
限与篇幅的问题,我不会把DCOM实现的代码写出来,因为这种分布式系统接口编程牵涉到的东西太多了,只是谈一下查询语句的构成原理和它的优化,这才是最主要的。
但是这其中牵涉的东西也很多,比如:合理使用索引,避免或简化排序,消除对大型表行数据的顺序存取,避免相关子查询,用排序来取代非顺序存取等等。
先说构成的原理,查询subsentence的生成依据是各个字段属于哪个关系表而产生的,当同一个字段属于2个关系表共同拥有的时候,那么它就是连接的字段。
例如有3个关系表:
table1(Rnumber,Name,Guige),table2(Cnumber,Xinghao,Guige),table3(Score,Guige)
那么可以生成一个查询subsentence的成员N=table1.Guige= table2.Guige.
而对于如何实现一个用户使用过的查询条件可以被其它用户使用共享如下所叙述:关键是建立临时文件,(我把其优化方式也加在其中)。以曾经开发过的成都市康泰电器MIS系统为例,把表的一个子集进行排序并创建临时表,有时能加速查询。它有助于避免多重排序操作,而且在其他方面还能简化优化器的工作。例如:
SELECT cust.name,rcvbles.balance,……other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
AND cust.postcode>“98000”
ORDER BY cust.name
如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个临时文件中,并按客户的名字进行排序:
SELECT cust.name,rcvbles.balance,……other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
ORDER BY cust.name
INTO TEMP cust_with_balance
然后以下面的方式在临时表中查询:
SELECT * FROM cust_with_balance
WHERE postcode>“98000”
临时表中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘I/O,所以查询工作量可以得到大幅减少。为了加速查询语句的生成和搜索我们使用的临时缓存表。进行搜索时,首先搜索临时缓存表,再搜索语句生成表。
但是要注意的是临时表创建后不会反映主表的修改。在主表中数据频繁修改的情况下,注意不要丢失数据。但是我到现在还没有完全的解决这个问题,有兴趣的读者可以想想。
5.查询语句的存储结构:
一个查询语句可以分解成一个或许多的查询subsentence,一个查询subsentence还可以分解成多个更小的查询subsentence。实际上他们是一个树型结构,所以每一个新的查询语句就是新的父节点。我们的临时缓存表就是已这种结构进行存储的。
6.结束语
此模型在实际的运用中运行良好,而且对于用户来说简单实用,基本满足了用户的分布式系统的要求。尽管用户对查询的要求不一致,但是利用基于中间件的查询优化模型具有友好的人机交互界面,查询条件能够自动灵活的生成,增加了实用性。对于开发人员来说减少了工作量,在提高了数据的安全性的同时也减轻了代码的二次开发等等。
本文地址:http://com.8s8s.com/it/it5497.htm