PostgreSQL 临时表

前端之家收集整理的这篇文章主要介绍了PostgreSQL 临时表前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

sql标准中临时表是一次创建,以后使用的时候无须再次创建的. 并且每个会话保持各自的数据.
但是在Postgresql中,临时表的使用有所改变.
1. 临时表在会话结束后会自动删除(或者在事务结束后删除on commit drop). 也就是说每个会话中需要使用临时表的话需要重新创建.
这个有好处也有坏处,好处是不同的会话能够使用同名但是不同结构的临时表. sql标准无法做到.
坏处是新建的会话如果只是要使用同名同结构的临时表也有重新创建.
2. 临时表可以选择在事务结束后删除数据或者保留数据或者删除表.

【语法】
  1. CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name ( [
  2. { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]
  3. | table_constraint
  4. | LIKE source_table [ like_option ... ] }
  5. [, ... ]
  6. ] )
  7. [ INHERITS ( parent_table [, ... ] ) ]
  8. [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
  9. [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
  10. [ TABLESPACE tablespace_name ]
红色部分是与临时表有关的. 其中GLOBAL和LOCAL在这个语法中是一样的,没有分别,但是在sql标准中是不一样的.
ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP
PRESERVE ROWS 表示临时表的数据在事务结束后保留.
DELETE ROWS 表示 临时表的数据在事务结束后truncate掉.
DROP 表示 临时表在事务结束后删除.
默认使用的是 PRESERVE ROWS.

【例子】
1. 临时表在会话结束后会自动删除(或者在事务结束后删除on commit drop).
会话1 :
  1. pg9
  2. .
  3. 2.0@db
  4. -
  5. 172
  6. -
  7. 16
  8. -
  9. 3
  10. -
  11. 150
  12. ->
  13. psql digoal digoal
  14. psql
  15. (
  16. 9.2
  17. .
  18. 0
  19. )
  20. Type
  21. "help"
  22. for
  23. help
  24. .
  25. digoal=> create temp table t(id int);
  26. CREATE TABLE
  27. digoal=> select relname,relnamespace,oid from pg_class where relname='t';
  28. relname | relnamespace | oid
  29. ---------+--------------+-------
  30. t | 41192 | 41203
  31. (1 row)
  32. digoal=> select nspname from pg_namespace where oid=41192;
  33. nspname
  34. -----------
  35. pg_temp_2
  36. (1 row)
退出会话1后重进,临时表已经被删除了.
  1. digoal=> \q
  2. pg9.2.0@db-172-16-3-150-> psql digoal digoal
  3. psql (9.2.0)
  4. Type "help" for help.
  5. digoal=> select nspname from pg_namespace where oid=41192;
  6. nspname
  7. -----------
  8. pg_temp_2
  9. (1 row)
  10. digoal=> select relname,oid from pg_class where relname='t';
  11. relname | relnamespace | oid
  12. ---------+--------------+-----
  13. (0 rows)

2. 每个会话中需要使用临时表的话需要重新创建. 好处是不同的会话能够使用同名但是不同结构的临时表.
会话1
  1. pg9.2.0@db-172-16-3-150-> psql digoal digoal
  2. psql (9.2.0)
  3. Type "help" for help.
  4. digoal
  5. =>
  6. create temp table t
  7. (
  8. id
  9. int
  10. );
  11. CREATE TABLE
会话2
  1. pg9.2.0@db-172-16-3-150-> psql digoal digoal
  2. psql (9.2.0)
  3. Type "help" for help.
  4. digoal=> create temp table t(id text,id2 int);
  5. CREATE TABLE
  6. digoal=> select relname,oid from pg_class where relname='t';
  7. relname | relnamespace | oid
  8. ---------+--------------+-------
  9. t | 11194 | 41206
  10. t | 41192 | 41209
  11. (2 rows)
  12. digoal=> select nspname from pg_namespace where oid in (11194, 41192);
  13. nspname
  14. -----------
  15. pg_temp_1
  16. pg_temp_2
  17. (2 rows)
会话3
  1. pg9.2.0@db-172-16-3-150-> psql digoal digoal
  2. psql (9.2.0)
  3. Type "help" for help.
  4. digoal=> create temp table t(id text,id2 int,info text);
  5. CREATE TABLE
  6. digoal=> select relname,oid from pg_class where relname='t';
  7. relname | relnamespace | oid
  8. ---------+--------------+-------
  9. t | 11194 | 41206
  10. t | 41192 | 41209
  11. t | 41215 | 41217
  12. (3 rows)
  13. digoal=> select nspname from pg_namespace where oid in (11194, 41192, 41215);
  14. nspname
  15. -----------
  16. pg_temp_1
  17. pg_temp_2
  18. pg_temp_3
  19. (3 rows)

3. 临时表可以选择在事务结束后删除数据或者保留数据或者删除表.
  1. digoal=> begin;
  2. BEGIN
  3. digoal=> create temp table test (id int) on commit preserve rows;
  4. CREATE TABLE
  5. digoal=> create temp table test1 (id int) on commit delete rows;
  6. CREATE TABLE
  7. digoal=> create temp table test2 (id int) on commit drop;
  8. CREATE TABLE
  9. digoal=> select relname,oid from pg_class where relname in ('test', 'test1', 'test2');
  10. relname | relnamespace | oid
  11. ---------+--------------+-------
  12. test | 41215 | 41223
  13. test1 | 41215 | 41226
  14. test2 | 41215 | 41232
  15. (3 rows)
  16. digoal=> insert into test values (1);
  17. INSERT 0 1
  18. digoal=> insert into test1 values (1);
  19. INSERT 0 1
  20. digoal=> commit;
  21. COMMIT
事务提交后test2已经被自动drop掉了.
  1. digoal=> select relname, 'test2');
  2. relname | relnamespace | oid
  3. ---------+--------------+-------
  4. test | 41215 | 41223
  5. test1 | 41215 | 41226
  6. (2 rows)
test的数据事务提交后数据保留.
  1. digoal=> select * from test;
  2. id
  3. ----
  4. 1
  5. (1 row)
test1的数据事务提交后数据已删除.
  1. digoal=> select * from test1;
  2. id
  3. ----
  4. (0 rows)
test2在事务提交后表已删除.
  1. digoal=> select * from test2;
  2. ERROR: relation "test2" does not exist
  3. LINE 1: select * from test2;
  4. ^

4. 如果有临时表和非临时表重名了,那么默认是使用临时表的,如果要使用非临时表,需要带上schema,如schema.table.
  1. digoal=> create table dup_table_name (id int);
  2. CREATE TABLE
  3. digoal=> create temp table dup_table_name (id int);
  4. CREATE TABLE
  5. digoal=> insert into digoal.dup_table_name values (1);
  6. INSERT 0 1
  7. digoal=> select * from dup_table_name ;
  8. id
  9. ----
  10. (0 rows)
  11. digoal=> insert into dup_table_name values (2);
  12. INSERT 0 1
  13. digoal=> select * from dup_table_name ;
  14. id
  15. ----
  16. 2
  17. (1 row)
  18. digoal=> select * from digoal.dup_table_name ;
  19. id
  20. ----
  21. 1
  22. (1 row)

5. 临时表上创建的索引也是临时的.
  1. digoal=> create index idx_test on dup_table_name (id);
  2. CREATE INDEX
  3. digoal=> \d dup_table_name
  4. Table "pg_temp_3.dup_table_name"
  5. Column | Type | Modifiers
  6. --------+---------+-----------
  7. id | integer |
  8. Indexes:
  9. "idx_test" btree (id)
  10. digoal=> \di idx_test
  11. List of relations
  12. Schema | Name | Type | Owner | Table
  13. -----------+----------+-------+--------+----------------
  14. pg_temp_3 | idx_test | index | digoal | dup_table_name
  15. (1 row)

6. 临时表无法选择性的创建在某个schema下面,它是存在于临时schema的,例如pg_temp_?. 对应的TOAST表也在临时的schema下,例如(pg_toast_temp_?) . 虽然无法选择schema但是tablespace是可以指定的.
  1. digoal=> create temp table digoal.tmp_test (id int);
  2. ERROR: cannot create temporary relation in non-temporary schema

7. Postgresql 中临时表的统计信息不会被autovacuum daemo自动收集. 所以如果有复杂查询的话,最好再有DML后自己执行analyze.

【小结】
1. 如果有临时表和非临时表重名了,如schema.table.
2. 临时表上创建的索引也是临时的.
3. 临时表无法选择性的创建在某个schema下面,例如(pg_toast_temp_?) . 虽然无法选择schema但是tablespace是可以指定的.
4. Postgresql 中临时表的统计信息不会被autovacuum daemo自动收集. 所以如果有索引的情况下,最好再有DML后自己执行analyze.
【参考】

猜你在找的Postgre SQL相关文章