pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
数据库是一个命名的 SQL 对象(“数据库对象”)集合。通常,每个数据库对象(表、函数等)都属于且只属于一个数据库。(不过也有少量系统目录,例如 pg_database,属于整个安装,可以从安装中的每个数据库访问。) 连接到数据库服务器的应用在它的连接请求中指定它想要连接的数据库的名称。每个连接不能访问多于一个数据库。(但一个应用可以打开的到同一数据库或其他数据库的连接数量不受限制。)
SQL 把数据库称为“目录”,但在实践中没有区别。
要创建或删除数据库,PostgreSQL postmaster 必须已经启动并正在运行(见 第 3.3 节)。
数据库使用查询语言命令 CREATE DATABASE 创建:
CREATE DATABASE name
其中name遵循SQL标识符的通常规则。当前用户自动成为新数据库的所有者。数据库的所有者有权在以后删除它(这也会删除其中的所有对象,即使它们有不同的所有者)。
创建数据库是一项受限操作。关于如何授予该权限,见第 7.1.1 节。
引导(Bootstrapping):. 由于执行CREATE DATABASE命令时必须先连接到数据库服务器,因此还会有一个问题:某个站点上的第一个数据库是如何创建的?第一个数据库总是由initdb命令在初始化数据存储区时创建的(见第 3.2 节)。这个数据库按惯例叫做 template1。因此,要创建第一个“真正”的数据库,你可以连接到 template1。
“template1” 这个名字并非偶然:每当创建一个新数据库时,模板数据库都会被实质性地克隆。这意味着你在 template1 中所做的任何更改,都会传播到后来创建的所有数据库中。这暗示你不应把模板数据库用于实际工作,但如果使用得当,这一特性可以带来便利。更多细节见下文。
为了方便,还可以从 shell 中执行一个程序来创建新数据库,即 createdb。
createdb dbname
createdb并没有什么特殊之处。它连接到 template1 数据库并发出CREATE DATABASE命令,和上面描述的完全一样。它在内部使用 psql 程序。createdb 的参考页包含调用细节。注意,不带任何参数的createdb会创建一个与当前用户名同名的数据库,这未必是你想要的。
CREATE DATABASE实际上是通过复制一个现有数据库来创建新数据库。默认情况下,它复制名为 template1 的标准系统数据库。因此,该数据库就是创建新数据库时使用的“模板”。如果你向 template1 中添加对象,这些对象也会被复制到以后创建的用户数据库中。这种行为允许对数据库中的标准对象集合进行站点本地修改。例如,如果你将过程语言 plpgsql 安装到 template1 中,那么以后创建用户数据库时无需额外操作,它就会自动可用。
还有第二个标准系统数据库,名为 template0。该数据库包含与 template1 初始内容相同的数据,也就是说,只包含你的PostgreSQL版本预定义的标准对象。在 initdb 之后绝不应当更改 template0。通过指示CREATE DATABASE复制 template0 而不是 template1,你可以创建一个“纯净的”用户数据库,它不包含template1中的任何站点本地附加对象。这在恢复pg_dump转储时特别方便:转储脚本应当恢复到一个纯净的数据库中,以确保重建出被转储数据库的正确内容,而不会与现在可能存在于 template1 中的附加对象发生冲突。
可以创建额外的模板数据库,实际上也可以通过将安装中任意数据库的名称指定为 CREATE DATABASE 的模板来复制它。但重要的是要理解,这(至少目前)并不是一个通用的“COPY DATABASE” 功能。特别地,在复制操作期间,源数据库必须是空闲的(没有正在进行的更改数据的 事务),这一点至关重要。CREATE DATABASE 会检查操作开始时没有其他后端进程(它自己除外)连接到源数据库,但这并不能保证复制进行期间不会发生更改,那样会导致复制出的数据库不一致。因此,我们建议把用作模板的数据库当作只读的。
对每个数据库,pg_database 中都有两个有用的标志:datistemplate 和 datallowconn。datistemplate可设置为表明某个数据库将作为CREATE DATABASE的模板。如果设置了该标志,任何拥有CREATEDB权限的用户都可以克隆该数据库;如果未设置,则只有超级用户和数据库拥有者才能克隆它。如果datallowconn为假,则不允许建立到该数据库的新连接(但仅仅把该标志设为假并不会终止已有会话)。为了防止被修改,template0 数据库通常被标记为 datallowconn = false。template0 和 template1 始终都应标记为 datistemplate = true。
准备好模板数据库或对其做任何更改之后,最好在该数据库中执行一次 VACUUM FREEZE 或 VACUUM FULL FREEZE。如果在同一数据库中没有其他打开的事务时执行,就可以保证该数据库中的所有元组都已被“冻结”,不会出现事务 ID 回卷问题。这对于将把 datallowconn 设为假的数据库尤为重要,因为在这样的数据库中将无法对它进行例行的 VACUUM 维护。更多信息见 第 8.2.3 节。
template1 和 template0 除了以下事实之外没有任何特殊地位:template1 这个名字是 CREATE DATABASE 的默认源数据库名,也是多种脚本(如 createdb)的默认连接数据库。例如,可以删除 template1,然后再从 template0 重新创建它,而不会有任何不良后果。如果有人不小心在 template1 里加入了许多杂项对象,这样做也许是可取的。
可以在安装的默认位置之外的地方创建数据库。请记住,所有数据库访问都是通过数据库服务器进行的,因此所指定的任何位置都必须是服务器可以访问的。
备选数据库位置通过一个环境变量来引用,该变量给出预期存储位置的绝对路径。这个环境变量必须存在于服务器的环境中,因此它必须在服务器启动之前已被定义。(因此,可用备选位置的集合由站点管理员控制;普通用户不能更改它。)任何有效的环境变量名都可以用来引用备选位置,不过建议使用以 PGDATA 为前缀的变量名,以避免与其他变量混淆和冲突。
要在服务器进程的环境中创建变量,你必须先关闭服务器、定义变量、初始化数据区域,最后重新启动服务器。(见 第 3.6 节 和 第 3.3 节。)要设置环境变量,在 Bourne shell 中输入
PGDATA2=/home/postgres/data export PGDATA2
或者在 csh 或 tcsh 中输入
setenv PGDATA2 /home/postgres/data
你必须确保这个环境变量始终在服务器环境中有定义,否则你将无法访问那个数据库。因此你大概会想在某个 shell 启动文件或服务器启动脚本中设置它。
要在 PGDATA2 中创建一个数据存储区域,请确保包含它的目录(这里是 /home/postgres)已经存在,并且运行服务器的用户账号可以写入它(见 第 3.1 节)。然后在命令行输入
initlocation PGDATA2
然后 就可以重新启动服务器了。
要在新位置中创建数据库,使用命令
CREATE DATABASEnameWITH LOCATION = 'location'
其中 location 是你使用的环境变量,本例中即 PGDATA2。createdb 命令有 -D 选项用于此目的。
在备选位置创建的数据库可以像任何其他数据库一样被访问和删除。
也可以直接向 CREATE DATABASE 命令指定绝对路径而不定义环境变量。默认情况下这是不允许的,因为它有安全风险。要允许这样做,你必须在编译 PostgreSQL 时定义 C 预处理器宏 ALLOW_ABSOLUTE_DBPATHS。一种做法是这样运行编译步骤:
gmake CPPFLAGS=-DALLOW_ABSOLUTE_DBPATHS all
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。