2024 年 9 月 26 日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3

22.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 中每个数据库都存在两个有用的标志:列 datistemplatedatallowconn。可以设置 datistemplate 来指示数据库是作为 CREATE DATABASE 的模板。如果设置了此标志,则任何具有 CREATEDB 权限的用户都可以克隆该数据库;如果没有设置,则只有超级用户和数据库所有者才能克隆它。如果 datallowconn 为 false,则不允许任何新的连接到该数据库(但现有会话不会仅因为将标志设置为 false 而终止)。template0 数据库通常被标记为 datallowconn = false,以防止对其进行修改。template0template1 都应该始终标记为 datistemplate = true

注意

template1template0 除了 template1CREATE DATABASE 的默认源数据库名称这一事实外,没有其他特殊状态。例如,可以删除 template1 并从 template0 重新创建它,而不会产生任何不良影响。如果不小心在 template1 中添加了一堆垃圾,则可能建议采取此措施。(要删除 template1,它必须具有 pg_database.datistemplate = false。)

当数据库集群初始化时,也会创建 postgres 数据库。该数据库是用户和应用程序连接到的默认数据库。它只是 template1 的副本,如果需要可以删除并重新创建。

提交更正

如果您在文档中看到任何不正确的内容,不符合您对特定功能的体验,或者需要进一步说明,请使用 此表格 报告文档问题。