PostgreSQL中的template0和template1库使用实战
postgresql中默认会有三个数据库:postgres、template0、template1。
postgres=#\l Listofdatabases Name|Owner|Encoding|Collate|Ctype|Accessprivileges -----------+----------+----------+-------------+-------------+----------------------- postgres|postgres|UTF8|en_US.UTF-8|en_US.UTF-8|=T/postgres+ |||||postgres=CTc/postgres template0|postgres|UTF8|en_US.UTF-8|en_US.UTF-8|=c/postgres+ |||||postgres=CTc/postgres template1|postgres|UTF8|en_US.UTF-8|en_US.UTF-8|=c/postgres+ |||||postgres=CTc/postgres (3rows) postgres=#
客户端默认会连接到postgres库。可以删除该库,不过会影响默认客户端连接。
删除了postgres库之后,可以借助模板库template1再创建postgres库:
$psqltemplate1 psql(11.9) Type"help"forhelp. template1=#dropdatabasepostgres; DROPDATABASE template1=#\l Listofdatabases Name|Owner|Encoding|Collate|Ctype|Accessprivileges -----------+----------+----------+-------------+-------------+----------------------- template0|postgres|UTF8|en_US.UTF-8|en_US.UTF-8|=c/postgres+ |||||postgres=CTc/postgres template1|postgres|UTF8|en_US.UTF-8|en_US.UTF-8|=c/postgres+ |||||postgres=CTc/postgres (2rows) template1=#createdatabasepostgres; CREATEDATABASE template1=#\l Listofdatabases Name|Owner|Encoding|Collate|Ctype|Accessprivileges -----------+----------+----------+-------------+-------------+----------------------- postgres|postgres|UTF8|en_US.UTF-8|en_US.UTF-8| template0|postgres|UTF8|en_US.UTF-8|en_US.UTF-8|=c/postgres+ |||||postgres=CTc/postgres template1|postgres|UTF8|en_US.UTF-8|en_US.UTF-8|=c/postgres+ |||||postgres=CTc/postgres (3rows) template1=#
其实,在使用createdatabasedb_name语句创建新库的时候,就是创建模板库template1的一个拷贝。
那如果我修改了template1库会怎样呢?
$psqltemplate1 psql(11.9) Type"help"forhelp. template1=#createtablemy_test_tab(aint); CREATETABLE template1=#createextensionhstore; CREATEEXTENSION template1=#\dx Listofinstalledextensions Name|Version|Schema|Description ---------+---------+------------+-------------------------------------------------- hstore|1.5|public|datatypeforstoringsetsof(key,value)pairs plpgsql|1.0|pg_catalog|PL/pgSQLprocedurallanguage (2rows) template1=#
修改以后,再创建新库的时候,新库也会包含上面的表和扩展:
template1=#createdatabasedb_test; CREATEDATABASE template1=#\cdb_test Youarenowconnectedtodatabase"db_test"asuser"postgres". db_test=#\dx Listofinstalledextensions Name|Version|Schema|Description ---------+---------+------------+-------------------------------------------------- hstore|1.5|public|datatypeforstoringsetsof(key,value)pairs plpgsql|1.0|pg_catalog|PL/pgSQLprocedurallanguage (2rows) db_test=#\d Listofrelations Schema|Name|Type|Owner --------+-------------+-------+---------- public|my_test_tab|table|postgres (1row) db_test=#
无论,在template1中加入了什么,都会在之后新建的库中。
那template0的用途是什么呢?
db_test=#selectdatname,datallowconn,datistemplatefrompg_databaseorderby3; datname|datallowconn|datistemplate -----------+--------------+--------------- postgres|t|f db_test|t|f template1|t|t template0|f|t (4rows) db_test=#
从这里可以看到,只有template0库对应的datallowconn字段的值是F。这就是上面重建postgres的时候先登录template1而不是template0的原因。
template0是默认的不可修改的数据库。不建议用户对template0做任何修改。在初始化后的空实例中,template0和template1是完全相同的。
为什么需要两个模板库呢?假设你搞乱了template1,还可以通过template0恢复template1。
如果你想创建自己的模板库,只需将你选中库对应的datistemplate(pg_database中的列)设置为T即可。
当然,在创建新库的时候,还可以选择其他的库做为源库:
db_test=#createdatabasedb_test_2templatedb_test; CREATEDATABASE db_test=#
但是,要求不能有其他连接连接到模板库,否则会报错:
db_test=#createdatabasedb_test_2templatedb_test; ERROR:sourcedatabase"db_test"isbeingaccessedbyotherusers DETAIL:Thereis1othersessionusingthedatabase. db_test=#
补充:重建postgresql模板数据库template1
$psql-Upostgrespostgres postgres=#updatepg_databasesetdatistemplate=falsewheredatname='template1'; UPDATE1 postgres=#dropdatabasetemplate1; DROPDATABASE postgres=#createdatabasetemplate1template=template0; CREATEDATABASE postgres=#updatepg_databasesetdatistemplate=truewheredatname='template1'; UPDATE1 postgres=#
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。