当我们用 psql 登录输入 \l+ 或者 select * from pg_database;的时候,我们可以看到除了 postgres,还有 template1 和 template0 这两个数据库。当我切换template1数据库然后 \dt+想看看该数据库下有什么表的时候,却发现返回的是Did not find any relations.,也就是该库下没有表,这我就有点好奇了,这两个库是干嘛用的,抱着好学的态度,学完之后对所学知识点做个总结。
template 的作用和设计思想
template1 和template0 是模板库,顾名思义,就是当创建库的时候,一些信息直接从模板库里获取。我们先来看看创建库的相关参数:
test=# \help create database
Command: CREATE DATABASE
Description: create a new database
Syntax:
CREATE DATABASE name
[ WITH ] [ OWNER [=] user_name ]
[ TEMPLATE [=] template ]
[ ENCODING [=] encoding ]
[ STRATEGY [=] strategy ]
[ LOCALE [=] locale ]
[ LC_COLLATE [=] lc_collate ]
[ LC_CTYPE [=] lc_ctype ]
[ ICU_LOCALE [=] icu_locale ]
[ ICU_RULES [=] icu_rules ]
[ LOCALE_PROVIDER [=] locale_provider ]
[ COLLATION_VERSION = collation_version ]
[ TABLESPACE [=] tablespace_name ]
[ ALLOW_CONNECTIONS [=] allowconn ]
[ CONNECTION LIMIT [=] connlimit ]
[ IS_TEMPLATE [=] istemplate ]
[ OID [=] oid ]
可以看到有一个TEMPLATE 的参数,该参数缺省为template1。其实template1 和template0 都是一样,但是template0 不允许修改。
我们可以理解为副本,即使template1 收到污染了,那我们还有template0 可以重新创建。
在这里,我们重点关注pg_database中的三个字段:datname、datistemplate和datallowconn. 其中datname指定数据库名,datistemplate指明当前数据库是否为模板数据库(t-是,f-否);datallowconn表示当前数据库是否允许用户连接登录。
postgres=# select datname,datistemplate,datallowconn from pg_database;
datname | datistemplate | datallowconn
-----------+---------------+--------------
postgres | f | t
template1 | t | t
template0 | t | f
对于template0、template1和postgres三个系统数据库,它们具有以下几个特点:
template0和template1数据库的datistemplate字段值是t,而postgres数据库的datistemplate字段值是f。表明template[0,1]这两个数据库是模板数据库,而postgres非模板数据库。
postgres和template1数据库的datallowconn字段为t,而template0数据库f。表明数据库postgres和template1是允许用户(包括psql)连接,而template0不允许连接
那为什么要设计这种模板继承的方式呢?
1. 用户可自定义,如果你在创建库的时候,有一些表,视图,函数,存储过程啥的需要创建,那就可以在模板库里先自定义,新建库的时候就会继承到。只需创建一次即可。
2. 保证多数据库环境的一致性,在企业级场景中,多个业务数据库往往需要相同的基础配置(如统一的字符集 uft8,排序规则,扩展依赖),这些我们都可以先通过模板库设置好。
那我们能不能自己创建自己的模板库呢?
答案当然是可以的,创建模板就跟创建一个普通的数据库一样,然后更新库属性 alter database t1 is_template true;接着创建新库的时候指定TEMPLATE 就可以了。
删除模板库需要把is_template 属性改为 false。
如果我们把template1 和template0 都给删除了会怎么样?那么当你创建新库的时候肯定就失败了,如果这个时候有备份还好说一点,要是没有的话,那只能重新初始化了,感兴趣的小伙伴可以自己动手尝试下。
评论