23.3. 模板数据库#
CREATE DATABASE
实际上通过复制现有数据库来工作。默认情况下,它复制名为template1
的标准系统数据库。因此,该数据库是制作新数据库的“模板”。如果将对象添加到template1
,这些对象将被复制到随后创建的用户数据库中。此行为允许对数据库中标准对象集进行站点本地修改。例如,如果在template1
中安装过程语言PL/Perl,那么在创建这些数据库时无需执行任何额外操作,它将自动在用户数据库中可用。
但是,CREATE DATABASE
不会复制附加到源数据库的数据库级GRANT
权限。新数据库具有默认数据库级权限。
有一个名为template0
的第二个标准系统数据库。此数据库包含与template1
的初始内容相同的数据,即仅包含PostgreSQL版本预定义的标准对象。在数据库集群初始化后,template0
永远不应更改。通过指示CREATE DATABASE
复制template0
而不是template1
,您可以创建一个“原始”用户数据库(其中不存在用户定义的对象,并且系统对象未被更改),该数据库不包含template1
中的任何站点本地添加项。在还原pg_dump
转储时,这特别方便:转储脚本应还原在原始数据库中,以确保重新创建转储数据库的正确内容,而不会与以后可能添加到template1
中的对象冲突。
复制template0
而不是template1
的另一个常见原因是,在复制template0
时可以指定新的编码和区域设置,而template1
的副本必须使用与它相同的设置。这是因为template1
可能包含特定于编码或特定于区域设置的数据,而template0
已知不包含此类数据。
要通过复制template0
创建数据库,请使用
CREATE DATABASE dbname TEMPLATE template0;
SQL 环境,或
createdb -T template0 dbname
shell。
可以创建其他模板数据库,实际上可以通过将某个数据库指定为CREATE DATABASE
的模板来复制群集中的任何数据库。但是,了解这一点很重要,即这(目前)并非旨在作为通用“COPY DATABASE
”工具。主要的限制是,在复制源数据库时,不允许任何其他会话连接到该数据库。如果在启动时存在任何其他连接,CREATE DATABASE
将失败;在复制操作期间,将阻止与源数据库建立新连接。
在pg_database
中,为每个数据库存在两个有用的标志:列datistemplate
和datallowconn
。可以将datistemplate
设置为指示某个数据库旨在作为CREATE DATABASE
的模板。如果设置此标志,则具有CREATEDB
权限的任何用户都可以克隆该数据库;如果未设置此标志,则只有超级用户和数据库所有者才能克隆该数据库。如果datallowconn
为 false,则不允许与该数据库建立任何新连接(但仅仅通过将标志设置为 false 不会终止现有会话)。template0
数据库通常标记为datallowconn = false
,以防止其被修改。template0
和template1
都应始终标记为datistemplate = true
。
注意
template1
和template0
除template1
名称是CREATE DATABASE
的默认源数据库名称这一事实之外,没有任何特殊状态。例如,可以删除template1
并从template0
重新创建它,而不会产生任何不良影响。如果不小心在template1
中添加了一堆垃圾,则建议采取此操作。(要删除template1
,它必须具有pg_database.datistemplate = false
。)初始化数据库集群时也会创建postgres
数据库。此数据库旨在作为用户和应用程序连接的默认数据库。它只是template1
的副本,必要时可以删除并重新创建。