PG模板数据库之template1 和 template0
Tags: PGtemplate0template1其它模板数据库脚本
简介
参考官网:http://postgres.cn/docs/13/manage-ag-templatedbs.html
template1和template0是PostgreSQL的模板数据库。所谓模板数据库就是创建新database时,PostgreSQL会基于模板数据库制作一份副本,其中会包含所有的数据库设置和数据文件。PostgreSQL安装好以后会默认附带两个模板数据库:template0和template1。
PostgreSQL默认初始化数据库后,模板数据库template0和template1包含的内容是一致的。
在PG中创建数据库时,默认是从template1模板数据库中克隆出来的!!
1 2 3 4 5 6 7 8 9 10 11 12 | postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+------------+------------+----------------------- db1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | lhrdb1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres (5 rows) |
我们知道创建数据库时的语法为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | postgres=# \help create database Command: CREATE DATABASE Description: create a new database Syntax: CREATE DATABASE name [ [ WITH ] [ OWNER [=] user_name ] [ TEMPLATE [=] template ] [ ENCODING [=] encoding ] [ LOCALE [=] locale ] [ LC_COLLATE [=] lc_collate ] [ LC_CTYPE [=] lc_ctype ] [ TABLESPACE [=] tablespace_name ] [ ALLOW_CONNECTIONS [=] allowconn ] [ CONNECTION LIMIT [=] connlimit ] [ IS_TEMPLATE [=] istemplate ] ] URL: https://www.postgresql.org/docs/13/sql-createdatabase.html |
如:create database aaaa with template='template0' encoding ='UTF8' lc_collate='C' lc_ctype='en_US.utf8' owner='test123';
其中template表示模板数据库。建库时如果不指定 TEMPLATE 属性,默认用的是 template1 模板库。
template1和template0的区别是什么?
区别主要有两点:
1、template1 可以连接,template0 不可以连接。
1 2 3 4 5 6 7 | postgres=# \c template1 psql (13.3, server 13.2) You are now connected to database "template1" as user "postgres". template1=# \c template0 FATAL: database "template0" is not currently accepting connections Previous connection kept template1=# |
2、使用 template1 模板库建库时不可指定新的 encoding 和 locale,而 template0 可以。这里的“新的”指的是非UTF8
使用\l 命令查看template0和template1的encoding和locale
1 2 3 4 5 6 7 8 9 10 11 12 13 | postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+------------+------------+----------------------- db1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | lhrdb1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres (5 rows) |
我们看到template0和template1的encoding是UTF8、Collate为en_US.utf8、Ctype为en_US.utf8
1 2 3 4 5 6 7 8 9 10 11 | postgres=# CREATE DATABASE DB6 WITH ENCODING 'sql_ascii' LC_COLLATE='C' LC_CTYPE='C' TEMPLATE=template1; ERROR: new encoding (SQL_ASCII) is incompatible with the encoding of the template database (UTF8) HINT: Use the same encoding as in the template database, or use template0 as template. postgres=# postgres=# postgres=# CREATE DATABASE DB6 WITH ENCODING 'sql_ascii' LC_COLLATE='C' LC_CTYPE='C' TEMPLATE=template0; CREATE DATABASE postgres=# postgres=# postgres=# CREATE DATABASE DB7 WITH ENCODING 'UTF8' TEMPLATE=template1; CREATE DATABASE |
注:template0和template1都不能被删除(需要特殊手段)。
1 2 3 4 | lhrdb1=# drop database template0; ERROR: cannot drop a template database lhrdb1=# drop database template1; ERROR: cannot drop a template database |
常用的字符集参考:http://postgres.cn/docs/13/multibyte.html
怎么创建模板数据库?
除了template0和template1,能创建自定义模板库吗?可以。
方法是指定is_template
1 | create database lhrtmpdb with template template0 lc_collate 'en_US.utf8' lc_ctype 'en_US.utf8' is_template=true; |
如何删除刚创建模板数据库?
解决需要先把模板库改成普通库再删除。
1 2 3 4 5 6 7 8 9 | lhrdb1=# drop database lhrtmpdb; ERROR: cannot drop a template database lhrdb1=# alter database lhrtmpdb is_template false; ALTER DATABASE lhrdb1=# lhrdb1=# lhrdb1=# drop database lhrtmpdb; DROP DATABASE lhrdb1=# |
模板template1
在PG中创建数据库时,默认是从template1模板数据库中克隆出来的!!
CREATE DATABASE
实际上通过拷贝一个已有数据库进行工作。默认情况下,它拷贝名为template1
的标准系统数据库。所以该数据库是创建新数据库的“模板”。 如果你为template1
数据库增加对象,这些对象将被拷贝到后续创建的用户数据库中。 这种行为允许对数据库中标准对象集合的站点本地修改。例如,如果你把过程语言PL/Perl安装到 template1
中,那么你在创建用户数据库后不需要额外的操作就可以使用该语言。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | lhrdb1=# \c template1 psql (13.3, server 13.2) You are now connected to database "template1" as user "postgres". template1=# template1=# create table test(id int); CREATE TABLE template1=# create database db2; CREATE DATABASE template1=# \c db2 psql (13.3, server 13.2) You are now connected to database "db2" as user "postgres". db2=# \d List of relations Schema | Name | Type | Owner --------+------+-------+---------- public | test | table | postgres (1 row) |
总结
CREATE DATABASE
实际上通过拷贝一个已有数据库进行工作。默认情况下,它拷贝名为template1
的标准系统数据库。所以该数据库是创建新数据库的“模板”。 如果你为template1
数据库增加对象,这些对象将被拷贝到后续创建的用户数据库中。 这种行为允许对数据库中标准对象集合的站点本地修改。例如,如果你把过程语言PL/Perl安装到 template1
中,那么你在创建用户数据库后不需要额外的操作就可以使用该语言。
系统里还有名为template0
的第二个标准系统数据库。 这个数据库包含和template1
初始内容一样的数据,也就是说,只包含你的PostgreSQL版本预定义的标准对象。 在数据库集簇被初始化之后,不应该对template0
做任何修改。 通过指示CREATE DATABASE
使用template0
取代template1
进行拷贝, 你可以创建一个“原始的”用户数据库(其中不存在用户定义的对象,并且系统对象没有被改变),它不会包含任何template1
中的站点本地附加物。 这一点在恢复一个pg_dump
转储时非常方便:转储脚本应该在一个原始的数据库中恢复以确保我们重建被转储数据库的正确内容,而不和任何现在可能已经被加入到template1
中的附加物相冲突。
另一个从template0
而不是template1
复制的常见原因是, 可以在复制template0
时指定新的编码和区域设置,而一个template1
的副本必须使用和它相同的设置。这是因为的template1
可能包含编码相关或区域相关的数据,而template0
中没有。
要通过拷贝template0
来创建一个数据库,使用:SQL 环境中的
1 | CREATE DATABASE dbname TEMPLATE template0; |
或者 shell 中的
1 | createdb -T template0 dbname |
可以创建额外的模板数据库,并且实际上可以通过将集簇中任意数据库指定为CREATE DATABASE
的模板来从该数据库拷贝。不过,我们必需明白,这个功能并不是设计作为一般性的“COPY DATABASE
”功能。主要的限制是当源数据库被拷贝时,不能有其他会话连接到它。如果在CREATE DATABASE
开始时存在任何其它连接,那么该命令将会失败。在拷贝操作期间,到源数据库的新连接将被阻止。
对于每一个数据库在pg_database
中存在两个有用的标志: datistemplate
和datallowconn
列。datistemplate
可以被设置来指示该数据库是不是要作为CREATE DATABASE
的模板。如果设置了这个标志,那么该数据库可以被任何有 CREATEDB
权限的用户克隆;如果没有被设置,那么只有超级用户和该数据库的拥有者可以克隆它。如果datallowconn
为假,那么将不允许与该数据库建立任何新的连接(但已有的会话不会因为把该标志设置为假而被中止)。template0
通常被标记为datallowconn = false
来阻止对它的修改。template0
和template1
通常总是被标记为datistemplate = true
。
注意
除了template1
是CREATE DATABASE
的默认源数据库名之外, template1
和template0
没有任何特殊的状态。例如,我们可以删除template1
然后从template0
重新创建它而不会有任何不良效果。如果我们不小心在template1
中增加了一堆垃圾,那么我们就会建议做这样的操作(要删除template1
,它必须有pg_database.datistemplate = false
)。
当数据库集簇被初始化时,也会创建postgres
数据库。这个数据库用于做为用户和应用连接的默认数据库。它只是 template1
的一个拷贝,需要时可以删除并重建。
在PG中,服务端不支持汉字字符集GBK和GB18030
参考:http://postgres.cn/docs/13/multibyte.html,服务端不支持的字符集包括:BIG5、GB18030、GBK、JOHAB、SJIS、SHIFT_JIS_2004、UHC