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
除了 CREATE DATABASE
命令默认源数据库名称是 template1
之外,没有其他特殊之处。例如,可以删除 template1
并从 template0
重新创建它,而不会产生任何不良影响。如果用户不小心在 template1
中添加了大量无用对象,则可能建议采取此措施。(要删除 template1
,它必须具有 pg_database.datistemplate = false
。)
数据库集群初始化时也会创建 postgres
数据库。该数据库是用作用户和应用程序连接的默认数据库。它只是 template1
的副本,如有必要,可以删除并重新创建。
如果您在文档中看到任何不正确的内容、与您使用该功能时的体验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。