Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

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 的副本,如有必要,可以删除并重新创建。