↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 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

23.3. 模板数据库 #

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 的一个副本,因此在必要时也可以删除并重建。

报告文档问题

阅读 上游文档. 通过 PostgreSQL 文档反馈表单.