在以前數據庫設計的時候,也有人不用臨時表進行這方面的限制,而用實體數據庫表來登記相關的信息。如在用戶信息表中有一列專門用來記錄用戶的當前登陸狀態。當用戶登陸系統后,該用戶登陸狀態的字段就改為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數據庫的臨時表處理方法,因為在數據庫優化中,相對於硬盤空間來說,數據庫運行的性能,要比其重要得多。想擴大硬盤的空間不需要多少成本,但是,想提高數據庫的運行性能的話,相對來說,要困難得多。
以上是我對兩個數據庫臨時表處理方式的分析,這些個人的觀點僅供大家在數據庫選型中參考。或許評論中有些主觀偏見,還望諒解。