CREATE DATABASE实际上是通过复制一个现有数据库来创建新数据库。默认情况下,它复制名为template1的标准系统数据库。因此,该数据库就是创建新数据库时使用的“模板”。如果你向template1中添加对象,这些对象也会被复制到以后创建的用户数据库中。这种行为允许对数据库中的标准对象集合进行站点本地修改。例如,如果你将过程语言PL/Perl安装到template1中,那么以后创建用户数据库时无需额外操作,它就会自动可用。
然而,CREATE DATABASE不会复制附着在源数据库上的数据库级GRANT权限。新数据库将具有默认的数据库级权限。
还有第二个标准系统数据库,名为template0。该数据库包含与template1初始内容相同的数据,也就是说,只包含你的PostgreSQL版本预定义的标准对象。在数据库集簇初始化之后,template0就不应再被修改。通过指示CREATE DATABASE复制template0而不是template1,你可以创建一个“纯净的”用户数据库(其中不存在用户定义对象,系统对象也未被改动),它不包含template1中的任何站点本地附加对象。这在恢复pg_dump转储时特别方便:转储脚本应当恢复到一个纯净的数据库中,以确保重建出被转储数据库的正确内容,而不会与后来可能加入template1的对象发生冲突。
复制template0而不是template1的另一个常见原因是:复制template0时可以指定新的编码和区域设置,而template1的副本则必须使用与它相同的设置。这是因为template1可能包含依赖特定编码或区域设置的数据,而已知template0不会包含这类数据。
要通过复制template0创建数据库,可在 SQL 环境中使用:
CREATE DATABASE dbname TEMPLATE template0;
或在 shell 中使用:
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和template0除了template1这个名字是CREATE DATABASE默认源数据库名这一点之外,并无任何特殊地位。例如,可以删除template1,然后再从template0重新创建它,而不会有任何不良后果。如果有人不小心在template1里加入了许多杂项对象,这样做也许是可取的。(要删除template1,必须先令其具有pg_database.datistemplate = false。)
初始化数据库集簇时也会创建postgres数据库。这个数据库被用作用户和应用连接时的默认数据库。它只是template1的一个副本,因此在必要时也可以删除并重建。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。