1. 程式人生 > >Postgresql中臨時表(temporary table)的特性和用法

Postgresql中臨時表(temporary table)的特性和用法

.net 他會 acl tmp 就會 fonts 功能 不能 聲明

熟悉Oracle的人,相比對臨時表(temporary table)並不陌生,很多場景對解決問題起到不錯的作用,開源庫Postgresql中,也有臨時表的概念,雖然和Oracle中臨時表名字相同,使用方法和特性也有類似的地方,但還是有很多不同的方面,下面就對比Oracle中臨時表舉例說明下。

1、Postgresql 臨時表的會話隔離性

Oracle中的臨時表,創建後,雖然各個會話間的數據是互相隔離的,也就是一個會話看不到其他會話的數據,但定義是共用的。而Postgresql中的臨時表,創建後,不但不同會話間的數據是相互隔離的,就連臨時表的定義也是不同會話間相互隔離的,也就是一個會話創建的臨時表,不能被其他會話看到,如下圖所示:

session1:創建了臨時表t_tmp。

技術分享圖片

session2:以另一個會話登錄相同用戶名和數據庫,查看session1中創建的臨時表,既不能查詢表,也不能查看表結構,但可以通過系統視圖看到該臨時表的存在。

技術分享圖片

2、Posgresql臨時表的易揮發性

Oracle中的臨時表,一個會話的數據在會話退出時會自動消失,但臨時表的定義一旦創建,就會已會一直存在,知道用戶刪除。而Postgresql的臨時表不是這樣,雖然會話退出會話數據也會自動消失,但定義也會隨著會話的退出而消失,也就是說,Postgresql中的臨時表的生命周期最長就是會話生命周期,甚至更短,如圖所示:

技術分享圖片

上圖是前面session1退出會話後,再次登錄查詢之前創建的臨時表t_tmp,已經查不到了,哪怕是臨時表定義也沒了。

此外,在創建Postgresql臨時表時,還可以設置相關選項,使得臨時表在事務結束時消失,哪怕會話沒結束,也會消失,如圖所示:

技術分享圖片

上圖中,雖然創建臨時表成功了,但回頭查看時卻怎麽也看不到表定義,雖然接連創建了兩邊,還是看不到表定義,也不能查,原因就是定義臨時表是用了on commit drop選項,這意味著事務結束時,自動刪除臨時表,本人用的psql客戶端工具中,每當完成一個ddl或dml時,會默認認為事務結束,所以,創建臨時表的ddl語句被認為一個事務,雖然創建語句成功了,表也創建了,但隨後,事務結束後被很快又刪除了,所以,無論如何也看不到臨時表的定義。但如果顯式聲明一個事務的開始和結束,即使使用了on commit drop選項,創建臨時表後,也是可以看到定義的,插入數據後,也一樣可以看到數據,如下圖所示:

技術分享圖片

然後,使用on commit drop選項創建的臨時表,一旦創建它的事務結束,臨時表和其中的數據也就消失了,如下圖所示:

技術分享圖片

3、Postgresql臨時表數據的易揮發性

Oracle中臨時表的數據,會隨著會話事務或會話的結束而自動消失,主要看創建臨時表時的相關選項。Postgresql臨時表中的數據,也有類似的功能,除了通過on commit drop選項可以設置事務結束臨時表就消失外,還可以通過on commit相關選項,分別控制臨時表的數據在事務結束消失(僅僅數據消失,定義還存在)和會話結束消失(數據和表定義都消失),如下通過on commit delete rows定義了臨時表:

技術分享圖片

上圖可以看到,雖然成功創建了臨時表,也往其中成功插入了數據,可是再查詢數據時,雖然表定義還在,但數據沒了,這是因為定義時用了on commit delete rows選項,就是事務結束,數據就消失,這裏的insert into語句默認為一個事務,執行完事務就算結束,所以,插入的數據立刻又消失了,如下圖,顯式的定義了事務的開始和結束,事務期間,插入的數據可以查到:

技術分享圖片

但一旦事務結束,這些剛剛插入臨時表的數據又立刻不見了,如下圖:

技術分享圖片

此外,還可以用on commit preserve rows選項來定義臨時表,通過該選項定義的臨時表,事務結束時,數據依然還會存在,直到會話結束為止,如下圖所示:

技術分享圖片

可見,單個語句的insert事務結束後,依然可以查到數據的存在,這也是臨時表定義不設置on commit選項時的默認行為。

Postgresql中臨時表(temporary table)的特性和用法