PostgreSQL

前言

PostgreSQL目前到最新12版本只支持本地临时表不支持全局临时表特性 ,会话退出后临时表定义和数据被删除,创建临时表语法如下:

  1. CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NO
  2. T EXISTS ] table_name ( [
  3. { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]
  4. | table_constraint
  5. | LIKE source_table [ like_option ... ] } [, ... ]
  6. ] )
  7. [ INHERITS ( parent_table [, ... ] ) ]
  8. [ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) }
  9. [ COLLATE collation ] [ opclass ] [, ... ] ) ]
  10. [ USING method ]
  11. [ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ]
  12. [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
  13. [ TABLESPACE tablespace_name ]

虽然语法上支持GLOBAL,但GLOBAL与LOCAL并没有区别。

1、全局临时表插件pgtt安装

  1. $ wget https://codeload.github.com/darold/pgtt/tar.gz/v2.1
  2. $ tar xvf v2.1
  3. $ cd pgtt2.1/
  4. $ which pg_config
  5. /opt/pgsql/bin/pg_config
  6. $ make
  7. $ make install
  8. $ ll /opt/pgsql/share/postgresql/extension/pgtt*
  9. rwr‐‐r‐‐ 1 postgres postgres 824 Sep 1 09:53
  10. /opt/pgsql/share/postgresql/ extension/pgtt‐‐2.1.0.sql
  11. rwr‐‐r‐‐ 1 postgres postgres 177 Sep 1 09:53
  12. /opt/pgsql/share/postgresql/ extension/pgtt.control
  13. $ ll /opt/pgsql/lib/postgresql/pgtt.so
  14. rwxrxrx 1 postgres postgres 43504 Sep 1 09:53
  15. /opt/pgsql/lib/postgresql/pgtt.so

2、非超级用户使用临时表需做如下设置

  1. export libdir$(pg_config ‐‐pkglibdir)
  2. sudo mkdir $libdir/plugins/
  3. cd $libdir/plugins/
  4. sudo ln s ../pgtt.so

3、运行单元测试用例

  1. $ make installcheck
  2. /opt/pg122/lib/postgresql/pgxs/src/makefiles/../../src/test/regress/pg_regr ess ‐‐inputdir=.
  3. / ‐‐bindir='/opt/pg122/bin' ‐‐inputdir=test ‐‐dbname=cont rib_regression
  4. 00_init 01_oncommitdelete 02_oncommitpreserve 03_createont runcate 04_rename
  5. 05_useindex 06_createas 07_createlike 08_plplgsql 09_tr ansaction 10_foreignkey 11_partition
  6. (using postmaster on Unix socket, port 6000)
  7. ============== dropping database "contrib_regression" ============== DROP DATABASE
  8. ============== creating database "contrib_regression" ============== CREATE DATABASE
  9. ALTER DATABASE
  10. ============== running regression test queries test 00_init ... ok 44 ms
  11. test 01_oncommitdelete test 02_oncommitpreserve test 03_createontruncate
  12. ok 39 ms
  13. ok 35 ms
  14. ok 40 ms
  15. test 04_rename test 05_useindex test 06_createas test 07_createlike test 08_plplgsql
  16. ok 63 ms
  17. ok 52 ms
  18. ok 37 ms
  19. ok 54 ms
  20. ok 40 ms
  21. test 09_transaction test 10_foreignkey test 11_partition
  22. ok 40 ms
  23. ok 15 ms
  24. ok 8 ms
  25. ======================
  26. All 12 tests passed.
  27. ======================

4、启用开关

1.session级别临时启用或关闭

  1. postgres=# SET pgtt.enabled TO off; SET
  2. postgres=# SET pgtt.enabled TO on;

2.单个数据库永久启用或关闭

  1. alter database postgres set pgtt.enabled to on;

5、普通用户使用

创建普通用户

  1. postgres=# create user test; CREATE ROLE
  2. postgres=# create database test owner test; CREATE DATABASE
  3. postgres=# \c test postgres
  4. You are now connected to database as user "postgres".

创建扩展,在每一个需要使用全局临时表的数据库上使用超级权限用户创建pgtt扩展。

  1. test=# create extension pgtt;
  2. CREATE EXTENSION

使用普通用户连接测试

  1. postgres=# \c test test
  2. test=> show search_path;
  3. search_path
  4. ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
  5. "$user", public
  6. (1 row)
  7. 加载动态库文件,数据库重启之后需要重新load
  8. test=> load '$libdir/plugins/pgtt';
  9. LOAD
  10. test=> show search_path;
  11. search_path
  12. ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
  13. public,pgtt_schema
  14. (1 row)

使用load加载之后自动的修改了search_path同时需要注意pgtt_schema要放在最后。

创建全局临时表ON COMMIT PRESERVE

  1. CREATE /*GLOBAL*/ TEMPORARY TABLE test_gtt_table (
  2. id integer,
  3. lbl text
  4. ) ON COMMIT PRESERVE ROWS;
  5. test=> insert into test_gtt_table values(1,'data1');
  6. INSERT 0 1
  7. test=> select * from test_gtt_table ;
  8. id | lbl
  9. ‐‐‐‐+‐‐‐‐‐‐‐
  10. 1 | data1
  11. (1 row)

再打开一个session连接查看

  1. $ psql test test
  2. postgres=# set search_path to public,pgtt_schema;
  3. SET
  4. test=> select * from test_gtt_table;
  5. id | lbl
  6. ‐‐‐‐+‐‐‐‐‐
  7. (0 rows)
  8. 可以看到表结构是存在的,数据为空

创建全局临时表ON COMMIT DELETE

  1. test=> load'$libdir/plugins/pgtt'
  2. LOAD
  3. CREATE /*GLOBAL*/ TEMPORARY TABLE test6_gtt_table (
  4. id integer, lbl text
  5. ) ON COMMIT DELETE ROWS;
  6. test=> begin;
  7. BEGIN
  8. test=> insert into test2_gtt_table values(2,'data2');
  9. INSERT 0 1
  10. test=> select * from test2_gtt_table ; id | lbl
  11. ‐‐‐‐+‐‐‐‐‐‐‐
  12. 2 | data2
  13. (1 row)
  14. test=> commit;
  15. COMMIT
  16. test=> select * from test2_gtt_table ;
  17. id | lbl
  18. ‐‐‐‐+‐‐‐‐‐
  19. (0 rows)

6、删除全局临时表

与删除普通表没有任何区别,需要超级用户权限

  1. test # load '$libdir/plugins/pgtt'
  2. LOAD
  3. test=# drop table test2_gtt_table ;
  4. DROP TABLE
  5. 同时需要检查下pg_global_temp_tables表是否删除成功
  6. select * from pg_global_temp_tables where relname='test2_gtt_table ';

7、创建索引

需要超级用户权限

  1. test=# CREATE INDEX ON test_gtt_table (id);
  2. CREATE INDEX
  3. test=# \d test_gtt_table
  4. Unlogged table "pgtt_schema.test_gtt_table"
  5. Column | Type | Collation | Nullable | Default
  6. ‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐
  7. id | integer | | |
  8. lbl | text | | |
  9. Indexes:
  10. test_gtt_table_id_idxbtree (id)

8、添加约束

  1. test=> load'$libdir/plugins/pgtt'
  2. LOAD
  3. CREATE /*GLOBAL*/ TEMPORARY TABLE t2 (
  4. c1 serial PRIMARY KEY,
  5. c2 VARCHAR (50) UNIQUE NOT NULL,
  6. c3 boolean DEFAULT false
  7. );

但不支持外键

  1. CREATE /*GLOBAL*/ TEMPORARY TABLE t3 (
  2. c1 int,
  3. FOREIGN KEY (c1) REFERENCES tb1 (id)
  4. );
  5. ERROR: attempt to create referential integrity constraint on global tempora ry table
  6. CONTEXT: SQL statement "CREATE UNLOGGED TABLE pgtt_schema.t3 ( c1 int,
  7. FOREIGN KEY (c1) REFERENCES tb1 (id)
  8. )"

也不支持分区表
注意:

  1. 使用普通用户安装注意第2步
  2. 全局临时表不能随便删除,未使用之前可以删除
  3. 每次创建全局临时表需要先load
  4. 支持约束,但不支持外键引用贺分区表