管理数据库

少数对象(如角色、数据库和表空间名称)在集群级别定义并存储在pg_global表空间中。集群内部有多个数据库,它们彼此隔离但可以访问集群级对象。每个数据库内部有多个架构,其中包含表和函数等对象。因此,完整的层次结构是:集群、数据库、架构、表(或其他类型的对象,例如函数)。

数据库使用CREATE DATABASE命令创建(参见第 22.2 节),使用DROP DATABASE命令销毁(参见第 22.5 节)。要确定现有数据库集,请检查pg_database系统目录,例如

 

SELECT datname FROM pg_database;

创建数据库

为了创建数据库,PostgreSQL服务器必须启动并运行

CREATE DATABASE name;

由于您需要连接到数据库服务器才能执行CREATE DATABASE命令,因此问题仍然是如何在任何给定站点创建第一个数据库。第一个数据库始终是在初始化数据存储区域时由initdb命令创建的。此数据库称为postgres。因此,要创建第一个“普通”数据库,您可以连接到postgres

在数据库集群初始化期间还会创建第二个数据库template1。每当在集群中创建新数据库时,template1实质上都会被克隆。这意味着您在template1中所做的任何更改都会传播到所有后续创建的数据库。因此,除非您希望将对象传播到每个新创建的数据库,否则请避免在template1中创建对象。更多详细信息请参见第 22.3 节

为方便起见,您可以从 shell 执行一个程序createdb来创建新的数据库。

createdb dbname

createdb并没有什么神奇之处。它连接到postgres数据库并发出CREATE DATABASE命令,正如上面所述。createdb参考页面包含调用详细信息。请注意,不带任何参数的createdb将使用当前用户名创建一个数据库。

有时你想为其他人创建一个数据库,并让他们成为新数据库的所有者,以便他们可以自己配置和管理它。要实现这一点,请使用以下命令之一:

CREATE DATABASE dbname OWNER rolename;

from the SQL environment, or:

createdb -O rolename dbname

模板数据库

CREATE DATABASE实际上通过复制现有数据库来工作。默认情况下,它会复制名为template1的标准系统数据库。因此,该数据库是创建新数据库的“模板” 。如果您将对象添加到template1 ,这些对象将被复制到随后创建的用户数据库中。此行为允许对数据库中的标准对象集进行站点本地修改。例如,如果您在template1中安装过程语言PL/Perl,它将自动在用户数据库中可用,而无需在创建这些数据库时采取任何额外操作。

还有一个名为template0的第二个标准系统数据库。此数据库包含与template1的初始内容相同的数据,即仅包含由您的PostgreSQL版本预定义的标准对象。初始化数据库集群后,绝不应更改template0 。通过指示CREATE DATABASE复制template0而不是template1,您可以创建一个“原始”用户数据库,其中不包含template1中的任何站点本地添加内容。这在恢复pg_dump转储时特别方便:应在原始数据库中恢复转储脚本,以确保重新创建转储数据库的正确内容,而不会与稍后可能添加到template1 的对象发生冲突。

复制template0而不是template1的另一个常见原因是,复制template0时可以指定新的编码和语言环境设置,而template1的副本必须使用相同的设置。这是因为template1可能包含特定于编码或特定于语言环境的数据,而template0则不包含这些数据。

要通过复制template0创建数据库,请使用:

CREATE DATABASE dbname TEMPLATE template0;

from the SQL environment, or:

createdb -T template0 dbname

 

数据库配置

PostgreSQL服务器提供了大量的运行时配置变量。您可以为其中许多设置设置特定于数据库的默认值。

例如,如果出于某种原因,您想要为给定数据库禁用GEQO优化器,您通常必须为所有数据库禁用它,或者确保每个连接客户端都小心发出SET geqo TO off。要将此设置为特定数据库中的默认设置,您可以执行以下命令:

ALTER DATABASE mydb SET geqo TO off;

这将保存设置(但不会立即设置)。在随后连接到此数据库时,它将看起来像是在会话开始前执行了SET geqo TO off;。请注意,用户仍然可以在会话期间更改此设置;它只是默认设置。要撤消任何此类设置,请使用ALTER DATABASE dbname RESET varname

销毁数据库

使用命令DROP DATABASE销毁数据库:

DROP DATABASE name;

只有数据库的所有者或超级用户可以删除数据库。删除数据库会删除数据库中包含的所有对象。数据库的销毁无法撤消

 

连接到受害数据库时,您无法执行DROP DATABASE命令。但是,您可以连接到任何其他数据库,包括template1数据库。template1是删除给定集群的最后一个用户数据库的唯一选项。

为了方便起见,还有一个用于删除数据库的 shell 程序,dropdb

dropdb dbname

表空间

PostgreSQL中的表空间允许数据库管理员在文件系统中定义表示数据库对象的文件存储位置。创建表空间后,在创建数据库对象时可以通过名称引用表空间。

通过使用表空间,管理员可以控制PostgreSQL安装的磁盘布局。这至少在两个方面很有用。首先,如果初始化集群的分区或卷空间不足且无法扩展,则可以在不同的分区上创建表空间并使用它,直到系统可以重新配置为止。

其次,表空间允许管理员利用数据库对象的使用模式来优化性能。例如,可以将使用频率很高的索引放在速度非常快、可用性高的磁盘上,例如昂贵的固态设备。同时,可以将存储很少使用或性能不重要的归档数据的表存储在较便宜但速度较慢的磁盘系统上。

 

警告

尽管位于 PostgreSQL 主数据目录之外,表空间也是数据库集群不可或缺的一部分,不能被视为独立的数据文件集合。它们依赖于主数据目录中的元数据,因此不能附加到其他数据库集群或单独备份。同样,如果您丢失了表空间(文件删除、磁盘故障等),数据库集群可能会变得无法读取或无法启动。将表空间放在 RAM 磁盘等临时文件系统上会危及整个集群的可靠性。

要定义表空间,请使用CREATE TABLESPACE命令,例如:

CREATE TABLESPACE fastspace LOCATION '/ssd1/postgresql/data';

该位置必须是PostgreSQL操作系统用户拥有的现有空目录随后在表空间内创建的所有对象都将存储在此目录下的文件中。该位置不能位于可移动或临时存储上,因为如果表空间缺失或丢失,集群可能无法运行。

注意:通常,为每个逻辑文件系统创建多个表空间没有什么意义,因为您无法控制逻辑文件系统中各个文件的位置。但是,PostgreSQL不会强制执行任何此类限制,而且它实际上并不直接了解您系统上的文件系统边界。它只是将文件存储在您告诉它使用的目录中。

表空间本身的创建必须以数据库超级用户的身份进行,但之后您可以允许普通数据库用户使用它。为此,请授予他们CREATE权限。

可以将表、索引和整个数据库分配给特定的表空间。为此,具有给定表空间的CREATE权限的用户必须将表空间名称作为参数传递给相关命令。例如,以下命令在表空间space1中创建一个表

CREATE TABLE foo(i int) TABLESPACE space1;

或者,使用default_tablespace参数:

SET default_tablespace = space1;
CREATE TABLE foo(i int);

default_tablespace设置为非空字符串时,它会为没有显式TABLESPACE子句的CREATE TABLECREATE INDEX命令提供隐式TABLESPACE子句。

还有一temp_tablespaces参数,它决定临时表和索引以及用于排序大型数据集等目的的临时文件的位置。这可以是表空间名称的列表,而不是只有一个,以便与临时对象相关的负载可以分散到多个表空间中。每次要创建临时对象时,都会从列表中随机挑选一个成员。

与数据库关联的表空间用于存储该数据库的系统目录。此外,如果没有给出TABLESPACE子句,并且default_tablespacetemp_tablespaces(视情况而定)没有指定其他选择,则它是用于在数据库中创建的表、索引和临时文件的默认表空间。如果创建数据库时未为其指定表空间,则它使用与其复制自的模板数据库相同的表空间。

初始化数据库集群时会自动创建两个表空间。pg_global空间用于共享系统目录。pg_default 表空间是template1template0数据库的默认空间(因此,也将是其他数据库的默认表空间,除非被CREATE DATABASE中的TABLESPACE子句覆盖)。

一旦创建,只要请求用户具有足够的权限,就可以从任何数据库使用表空间。这意味着,只有在删除了使用表空间的所有数据库中的所有对象后,才能删除表空间。

要删除空表空间,请使用DROP TABLESPACE命令。

要确定现有表空间的集合,请检查pg_tablespace系统目录,例如

SELECT spcname FROM pg_tablespace;

 

posted @ 2024-05-27 17:27  wongchaofan  阅读(2)  评论(0编辑  收藏  举报