臨時表在Oracle資料庫與SQL Server資料庫中的異同

iSQlServer發表於2009-02-17
常見應用:

  臨時表在資料庫設計中,有著舉足輕重的作用。

  如我們可以利用臨時表的功能來限制同一個使用者名稱多次登陸到同一個系統中去。例如現在有一個財務管理系統,企業希望同一個使用者在同一時間裡只能登陸一次,這主要是用來限制每位員工都以自己的使用者名稱與密碼登陸。如此限制的目的主要是為財務管理系統中的每張單據找到其主人。

  原始方案:

  在以前資料庫設計的時候,也有人不用臨時表進行這方面的限制,而用實體資料庫表來登記相關的資訊。如在使用者資訊表中有一列專門用來記錄使用者的當前登陸狀態。當使用者登陸系統後,該使用者登陸狀態的欄位就改為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資料庫的臨時表處理方法,因為在資料庫優化中,相對於硬碟空間來說,資料庫執行的效能,要比其重要得多。想擴大硬碟的空間不需要多少成本,但是,想提高資料庫的執行效能的話,相對來說,要困難得多。

  以上是我對兩個資料庫臨時表處理方式的分析,這些個人的觀點僅供大家在資料庫選型中參考。或許評論中有些主觀偏見,還望諒解。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-553569/,如需轉載,請註明出處,否則將追究法律責任。

相關文章