临时表在Oracle数据库与SQL Server数据库中的异同

临时表在Oracle数据库与SQL Server数据库中的异同

http://www.sina.com.cn 2008年06月24日 13:05  《程序员》
出处:IT专家网
常见应用:

  临时表在数据库设计中,有着举足轻重的作用。

  如我们可以利用临时表的功能来限制同一个用户名多次登陆到同一个系统中去。例如现在有一个财务管理系统,企业希望同一个用户在同一时间里只能登陆一次,这主要是用来限制每位员工都以自己的用户名与密码登陆。如此限制的目的主要是为财务管理系统中的每张单据找到其主人。

  原始方案:

   在以前数据库设计的时候,也有人不用临时表进行这方面的限制,而用实体数据库表来登记相关的信息。如在用户信息表中有一列专门用来记录用户的当前登陆状 态。当用户登陆系统后,该用户登陆状态的字段就改为Y,而当用户退出系统能后,该字段的内容又改为N。这个方案看起来是可行的,但是,其在实际应用中,有 一个非常大的漏洞。若用户登陆到系统后,终端因为各种原因,如病毒、断电等突然状况,发生死机的话,此时,用户虽然没有登陆到系统中去,但是,因为其退出 系统的时候,没有正常退出,这就导致在财务管理系统中的用户信息表中,显示该用户的登陆状态仍然为Y。此时,用户尝试登陆到财务管理系统中去的话,就会被 系统拒绝,系统会认为该用户已经登陆了系统,不能重复登陆。

  所以说,利用实体表来记录用户登陆的信息,存在着管理上的漏洞。

  利用临时表实现用户重新登陆的限制:

  后来,数据库设计师们想,能否把该用户登陆信息记录在一张临时性的表中呢?当用户结束会话,无论是正常的退出还是因为意外情况的退出,只要用户结束一个会话后,那么 该临时表中的内容就会清空。

  若跟这个需求结合的话,数据库设计师就希望能够实现如下功能。

   当用户登陆系统开始一个会话后,数据库系统就建立一张临时表,该表中至少有一个内容,就是用户的帐号(或者该帐号对应的ID)。当有其他用户登陆到系统 的时候,系统会先从这张临时表中查询,是否有相同的用户记录。若有的话,就会拒绝用户的登陆,警告用户已经有相同的用户登陆了。当用户正常退出系统或者因 为以外情况退出系统结束当前会话的时候,那么数据库系统就会清除这张表的内容。如此,当用户下次登陆系统的话,即使是在意外情况下登陆系统的,也可以正常 的登陆。

  可见,数据库的临时表在企业实际应用中有着举足轻重的作用。

  在ORACLE数据库与SQL SERVER数据库中,都实现了临时表的功能。不过两者实现的方式有差异。而不同的实现方式又赋予了其不同的特点,这是我们在数据库选型中不得不重视的一方面内容。

  两个数据库临时表实现方式的异同:

   SQL SERVER临时表跟ORACLE数据库临时表的差异,可以利用一句话来概括。SQL SERVER 临时表是在需要用到的时候创建; 而ORACLE 数据库的临时表,则是在数据库初始化中就开始创建,在具体的会话或者事务开始后进行操作,结束一个会话或者结束一个事务后该数据库的内容就会被清空。

1、 在创建时的异同。

   SQL SERVER 数据库的临时表,是在实际需要时创建的。具体的来说,可以利用SELECT语句与CREAT语句创建临时表。如可以利用SELECT * INTO #USER_TEMP FROM USER; 通过这条语句就可以在需要的时间创建一张临时表。除此之外,还可以利用CREATE语句,在需要的时候创建临时表。

  而ORACLE数 据库,是在数据库系统初始化的过程中,就需要建立临时表。也就是在用户安装财务管理软件系统时,初始化数据库系统时,系统就会创建临时表。而不是在临时表 需要用到的时候,才被创建。故,ORACLE数据库的临时表创建方式只有一种,在数据库初始化的时候,利用CREATE创建数据库临时表。所以, ORACLE数据库临时表,又有另一种说法。我们一般称ORACLE数据库的临时表是永久性的,只是临时表的内容是临时的,在需要用到临时表时,只要直接 调用即可,而不用临时创建。这不像SQL SERVER数据库那样,只有在用到时,才创建该临时表; 当结束会话时,不仅表中的数据被清空了,而且该表也被删除了。

  笔者评论:

  笔者还是比较喜欢ORACLE数据库临 时表的实现方式。为什么呢?因为我们都知道,数据库定义语言,如CREATE等,比较占用系统资源。若在数据库SQL SERVER数据库系统设计的过程中,前台程序频繁的使用CREATE等数据库定义语言创建临时表的话,会对SQL server数据库系统的运行效率产生很大的不利影响; 而且,每次运行的话,都会有类似的不利影响,因为每次运行都会有一个创建临时表的过程。而ORCLE数据库中,则是在系统初始化的时候才利用CREATE 语句,所以,只是在系统初始化的时候,可能性能会受到影响,而在以后的数据库运行中,就不会为这个老是运行CREATE语句而困饶。所以,我个人还是比较 喜欢采用ORACLE系统的临时表处理方案。

  2、 数据释放时的异同。

  SQL SERVER数据库系统有两种临时表,一种是本地临时表,一种是全局临时表。本地临时表只在当前会话中可以查找到。也就是说,某个用户创建了一个临时表, 只有本人可以查询得到,而其他用户是查询不到这张临时表的。第二种是全局临时表,这张表无论是谁创建的,只要该表的会话没有结束,即该临时表只要存在与数 据库中,则任何登陆该数据库的用户都可以查询到该临时表的内容。无论是采取哪种表,只要创建该临时表的用户结束该对话时,则该表就会被自动删除。如要实现 上面所讲的用户帐户重复登陆的问题,需要用到全局临时表。当一个系统用户登陆时,就新建一张以该用户名命名的临时表; 当另外一个用户也试图想以这个用户名登陆时,系统就会查到以该用户名为名字的临时表已经存在,如此,就会拒绝该用户名的再次登陆。而当该用户退出时,或者 意外中断该会话时,则该临时表就会被系统删除。该帐户名下次登陆时,就可以正常使用。

  ORACLE数据库系统的临时表也有两种,一种 是事务型临时表,一种是会话型临时表。事物型临时表是当一个事物结束时清空临时表的内容; 而会话型临时表就当一个会话中断或者被重新连接时数据表的内容就会清空了。从中,我们可以看到在数据清空方面,两个数据库处理方式的两个重大区别。一是 ORACLE 数据库在清除临时表是,只清楚数据,而不清楚临时表的本身。二是从功能上来讲,ORACLE还提供了一种更加细分的事务型临时表。一个会话中,可能有多个 事务。也就是说,ORACLE 清空临时型数据表的时间更加细腻,可以根据同一个会话中的不同事务来清空临时表。

  另外还要说明的一点 就是,ORACLE的会话型临时中的内容对于各个用户来说,内容都是独立的。具体的说,就是各个用户在会话的过程中,都可以往一张临时表中存储数据; 但是用户查询临时表中的数据的时候,只能够查询到自己所创建的内容,而不能看到其他用户所增加的记录。这对于临时表的安全性来说,是非常有保障的。

  笔者评论:

  ORACLE的临时表跟SQL SERVER数据库的临时表比起来,有优点也有缺点。如ORACLE数据库的临时表支持事务型的临时表,可以把一个会话分割成几个独立的事务,以事务的级别来管理临时表,这对于我们来说,处理起来比较方便。

   而缺点就是,ORACLE数据库的临时表,出于数据库本身性能的考虑,在某些方面,作了一些限制。如在默认情况下,ORACLE数据库的临时表不能采用 外键; 也不支持LOB对象。确实,若临时表中存在外键或者LOB对象的话,会对临时表的性能产生很大的影响。但是,在实际工作中,有时候确实需要在临时表上采用 外键或者LOB对象。此时,我们只能够采用一些变通的方式加以解决。

  3、 表存储时的异同。

  上面我已经简要介绍过两个数据库对于表处理时的异同。下面再对此相关的内容进行一下总结。

  SQL SERVER在结束一个会话后,就会把用户所创建的临时表删除。而ORACLE在结束一个会话或者一个事务时,删除的只是表的内容,表的结构仍然会存在。ORACLE就是凭借牺牲一点表结构的存储空间,来达到提高ORACLE 数据库临时表处理性能的目的。

  笔者评论:

  个人比较钟情于ORACLE数据库的临时表处理方法,因为在数据库优化中,相对于硬盘空间来说,数据库运行的性能,要比其重要得多。想扩大硬盘的空间不需要多少成本,但是,想提高数据库的运行性能的话,相对来说,要困难得多。

  以上是我对两个数据库临时表处理方式的分析,这些个人的观点仅供大家在数据库选型中参考。或许评论中有些主观偏见,还望谅解。
<script type="text/javascript"> function chgSearchType(Id){ for(var i=1;i<=2;i++){ if(GetObj("sTb"+i)){ GetObj("sTb"+i).style.display = "none"; } } if(GetObj("sTb"+Id)){ GetObj("sTb"+Id).style.display = "block"; if(Id==2){ GetObj("hotwords").style.display = "none"; GetObj("pbg").innerHTML = '<a href="http://iask.com" target="_blank" style="text-decoration:none;">爱问(iAsk.com)</a>'; }else if(Id==1){ if(GetObj("hotwords_link").innerHTML == ""){ GetObj("hotwords").style.display = "none"; }else{ GetObj("hotwords").style.display = "block"; } GetObj("pbg").innerHTML = '<a href="http://www.google.cn/webhp?client=aff-sina&ie=gb&oe=utf8&hl=zh-CN&channel=contentlogo" target="_blank" style="text-decoration:none;">Powered By Google</a>'; } } } </script> <script type="text/javascript"> function checkSearchValue1_2(){ if(document.gform2.q.value=="请输关键词"||document.gform2.q.value=="请输入关键字"||document.gform2.q.value==""){ document.gform2.q.value=""; } document.gform2.channel.value = "contentsearchblow"; return true; } </script> <script type="text/javascript"> function checkSearchValue2_2(){ if(document.sb02_2.k.value=="请输入关键字"||document.sb02_2.k.value==""){ document.sb02_2.k.value = "请输入关键字"; return false; } return true; } </script>
Powered By Google

 

<script type="text/javascript"> var objFlash = new sinaFlash("http://d1.sina.com.cn/200806/25/142325_jhtechxt625.swf", "", "585", "50", "7", "", false,"high"); objFlash.addParam("wmode", "opaque"); objFlash.write("flashcontent_A11BCD3273DB"); </script>

《程序员》的其他文章


http://tech.sina.com.cn/s/2008-06-24/1305706081.shtml
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值