sql标准中临时表是一次创建,以后使用的时候无须再次创建的. 并且每个会话保持各自的数据.
但是在Postgre
sql中,临时表的使用有所改变.
1. 临时表在会话结束后会
自动删除(或者在事务结束后
删除on commit drop). 也就是说每个会话中需要使用临时表的话需要重新创建.
这个有好处也有坏处,好处是不同的会话能够使用同名但是不同结构的临时表.
sql标准无法做到.
坏处是新建的会话如果只是要使用同名同结构的临时表也有重新创建.
2. 临时表可以选择在事务结束后
删除数据或者保留数据或者
删除表.
【语法】
CREATE @H_404_32@[ @H_
404_32@[
GLOBAL @H_404_32@| LOCAL @H_
404_32@]
@H_
404_32@{
TEMPORARY @H_
404_32@|
TEMP @H_
404_32@}
@H_
404_32@|
UNLOGGED @H_
404_32@]
TABLE @H_
404_32@[
IF NOT EXISTS @H_
404_32@]
table_name @H_
404_32@(
@H_
404_32@[
@H_404_32@{ column_name data_type @H_
404_32@[
COLLATE collation @H_
404_32@]
@H_
404_32@[
column_constraint @H_
404_32@[
@H_
404_32@...
@H_
404_32@]
@H_
404_32@]
@H_404_32@| table_constraint
@H_404_32@| LIKE source_table @H_
404_32@[
like_option @H_
404_32@...
@H_
404_32@]
@H_
404_32@}
@H_404_32@[ INHERITS @H_
404_32@(
parent_table @H_
404_32@[,
@H_
404_32@...
@H_
404_32@]
@H_
404_32@)
@H_
404_32@]
@H_404_32@[ WITH @H_
404_32@(
storage_parameter @H_
404_32@[=
value@H_
404_32@]
@H_
404_32@[,
@H_
404_32@...
@H_
404_32@]
@H_
404_32@)
@H_
404_32@|
WITH OIDS @H_
404_32@|
WITHOUT OIDS @H_
404_32@]
@H_404_32@[ ON COMMIT @H_404_32@{ PRESERVE ROWS @H_
404_32@|
DELETE ROWS @H_
404_32@|
DROP @H_
404_32@}
@H_
404_32@]
@H_404_32@[ TABLESPACE tablespace_name @H_
404_32@]
红色部分是与临时表有关的. 其中GLOBAL和LOCAL
在这个语法中是一样的,没有分别,但是在
sql标准中是不一样的.
ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP
PRESERVE ROWS
表示临时表的数据在事务结束后保留.
DELETE ROWS 表示
临时表的数据在事务结束后truncate掉.
【例子】
1.
临时表在会话结束后会自动删除(或者在事务结束后删除on commit drop).
会话1 :
pg9
@H_
404_32@.
2.0@db
@H_
404_32@-
172
@H_
404_32@-
16
@H_
404_32@-
3
@H_
404_32@-
150
@H_
404_32@->
psql digoal digoal
Type
"help"
for
help
@H_
404_32@.
digoal@H_404_32@=> create temp table t@H_
404_32@(
id int@H_
404_32@);
CREATE TABLE
digoal@H_404_32@=> select relname@H_
404_32@,
relnamespace@H_
404_32@,
oid from pg_class where relname@H_
404_32@=
't'@H_
404_32@;
relname @H_404_32@| relnamespace @H_
404_32@|
oid
---------+--------------+-------
t @H_404_32@| 41192 @H_
404_32@|
41203
digoal@H_404_32@=> select nspname from pg_namespace where oid@H_
404_32@=
41192@H_
404_32@;
nspname
-----------
pg_temp_2
Type "help" for help@H_404_32@.
digoal@H_404_32@=> select nspname from pg_namespace where oid@H_
404_32@=
41192@H_
404_32@;
nspname
-----------
pg_temp_2
digoal@H_404_32@=> select relname@H_
404_32@,
oid from pg_class where relname@H_
404_32@=
't'@H_
404_32@;
relname @H_404_32@| relnamespace @H_
404_32@|
oid
---------+--------------+-----
2.
每个会话中需要使用临时表的话需要重新创建.
好处是不同的会话能够使用同名但是不同结构的临时表.
会话1
Type "help" for help@H_404_32@.
digoal
@H_
404_32@=>
create temp table t
@H_
404_32@(
id
int
@H_
404_32@);
CREATE TABLE
会话2
Type "help" for help@H_404_32@.
digoal@H_404_32@=> create temp table t@H_
404_32@(
id text@H_
404_32@,
id2 int@H_
404_32@);
CREATE TABLE
digoal@H_404_32@=> select relname@H_
404_32@,
oid from pg_class where relname@H_
404_32@=
't'@H_
404_32@;
relname @H_404_32@| relnamespace @H_
404_32@|
oid
---------+--------------+-------
t @H_404_32@| 11194 @H_
404_32@|
41206
t @H_404_32@| 41192 @H_
404_32@|
41209
digoal@H_404_32@=> select nspname from pg_namespace where oid in @H_
404_32@(
11194@H_
404_32@,
41192@H_
404_32@);
nspname
-----------
pg_temp_1
pg_temp_2
会话3
Type "help" for help@H_404_32@.
digoal@H_404_32@=> create temp table t@H_
404_32@(
id text@H_
404_32@,
id2 int@H_
404_32@,
info text@H_
404_32@);
CREATE TABLE
digoal@H_404_32@=> select relname@H_
404_32@,
oid from pg_class where relname@H_
404_32@=
't'@H_
404_32@;
relname @H_404_32@| relnamespace @H_
404_32@|
oid
---------+--------------+-------
t @H_404_32@| 11194 @H_
404_32@|
41206
t @H_404_32@| 41192 @H_
404_32@|
41209
t @H_404_32@| 41215 @H_
404_32@|
41217
digoal@H_404_32@=> select nspname from pg_namespace where oid in @H_
404_32@(
11194@H_
404_32@,
41192@H_
404_32@,
41215@H_
404_32@);
nspname
-----------
pg_temp_1
pg_temp_2
pg_temp_3
3.
临时表可以选择在事务结束后删除数据或者保留数据或者删除表.
digoal@H_404_32@=> begin@H_
404_32@;
BEGIN
digoal@H_404_32@=> create temp table test @H_
404_32@(
id int@H_
404_32@)
on commit preserve rows@H_
404_32@;
CREATE TABLE
digoal@H_404_32@=> create temp table test1 @H_
404_32@(
id int@H_
404_32@)
on commit delete rows@H_
404_32@;
CREATE TABLE
digoal@H_404_32@=> create temp table test2 @H_
404_32@(
id int@H_
404_32@)
on commit drop@H_
404_32@;
CREATE TABLE
digoal@H_404_32@=> select relname@H_
404_32@,
oid from pg_class where relname in @H_
404_32@(
'test'@H_
404_32@,
'test1'@H_
404_32@,
'test2'@H_
404_32@);
relname @H_404_32@| relnamespace @H_
404_32@|
oid
---------+--------------+-------
test @H_404_32@| 41215 @H_
404_32@|
41223
test1 @H_404_32@| 41215 @H_
404_32@|
41226
test2 @H_404_32@| 41215 @H_
404_32@|
41232
digoal@H_404_32@=> insert into test values @H_
404_32@(
1@H_
404_32@);
INSERT 0 1
digoal@H_404_32@=> insert into test1 values @H_
404_32@(
1@H_
404_32@);
INSERT 0 1
digoal@H_404_32@=> commit@H_
404_32@;
COMMIT
digoal@H_404_32@=> select relname@H_
404_32@,
'test2'@H_
404_32@);
relname @H_404_32@| relnamespace @H_
404_32@|
oid
---------+--------------+-------
test @H_404_32@| 41215 @H_
404_32@|
41223
test1 @H_404_32@| 41215 @H_
404_32@|
41226
test的数据事务提交后数据保留.
digoal@H_404_32@=> select @H_
404_32@*
from test@H_
404_32@;
id
----
1
digoal@H_404_32@=> select @H_
404_32@*
from test1@H_
404_32@;
id
----
digoal@H_404_32@=> select @H_
404_32@*
from test2@H_
404_32@;
ERROR@H_404_32@: relation "test2" does not exist
LINE 1@H_404_32@: select @H_
404_32@*
from test2@H_
404_32@;
4. 如果有临时表和非临时表重名了,那么
默认是使用临时表的,如果要使用非临时表,需要带上schema,如schema.table.
digoal@H_404_32@=> create table dup_table_name @H_
404_32@(
id int@H_
404_32@);
CREATE TABLE
digoal@H_404_32@=> create temp table dup_table_name @H_
404_32@(
id int@H_
404_32@);
CREATE TABLE
digoal@H_404_32@=> insert into digoal@H_
404_32@.
dup_table_name values @H_
404_32@(
1@H_
404_32@);
INSERT 0 1
digoal@H_404_32@=> select @H_
404_32@*
from dup_table_name @H_
404_32@;
id
----
digoal@H_404_32@=> insert into dup_table_name values @H_
404_32@(
2@H_
404_32@);
INSERT 0 1
digoal@H_404_32@=> select @H_
404_32@*
from dup_table_name @H_
404_32@;
id
----
2
digoal@H_404_32@=> select @H_
404_32@*
from digoal@H_
404_32@.
dup_table_name @H_
404_32@;
id
----
1
5. 临时表上创建的索引也是临时的.
digoal@H_404_32@=> create index idx_test on dup_table_name @H_
404_32@(
id@H_
404_32@);
CREATE INDEX
digoal@H_404_32@=> \d dup_table_name
Table "pg_temp_3.dup_table_name"
Column @H_404_32@| Type @H_
404_32@|
Modifiers
--------+---------+-----------
id @H_404_32@| integer @H_
404_32@|
"idx_test" btree @H_404_32@(id@H_
404_32@)
digoal@H_404_32@=> \di idx_test
List of relations
Schema @H_404_32@| Name @H_
404_32@|
Type @H_
404_32@|
Owner @H_
404_32@|
Table
-----------+----------+-------+--------+----------------
pg_temp_3 @H_404_32@| idx_test @H_
404_32@|
index @H_
404_32@|
digoal @H_
404_32@|
dup_table_name
6. 临时表无法选择性的创建在某个schema下面,它是存在于临时schema的,例如pg_temp_?. 对应的TOAST表也在临时的schema下,例如(pg_toast_temp_?) . 虽然无法选择schema但是tablespace是可以指定的.
digoal@H_404_32@=> create temp table digoal@H_
404_32@.
tmp_test @H_
404_32@(
id int@H_
404_32@);
ERROR@H_404_32@: cannot create temporary relation in non@H_
404_32@-
temporary schema
7. Postgre
sql 中临时表的
统计信息不会被autovacuum daemo
自动收集. 所以如果有复杂
查询的话,最好再有DML后自己执行analyze.
【小结】
1. 如果有临时表和非临时表重名了,如schema.table.
2. 临时表上创建的索引也是临时的.
3. 临时表无法选择性的创建在某个schema下面,例如(pg_toast_temp_?) . 虽然无法选择schema但是tablespace是可以指定的.
4. Postgre
sql 中临时表的
统计信息不会被autovacuum daemo
自动收集. 所以如果有索引的情况下,最好再有DML后自己执行analyze.
【参考】
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。