您的位置:寻梦网首页编程乐园数据库PostgreSQL 7.2 Documentation

Chapter 6. 管理数据库

Table of Contents
6.1. 创建数据库
6.1.1. 模板数据库
6.1.2. 变更位置
6.2. 删除数据库

数据库是一些 SQL 对象( "数据库对象" )的命名集合; 通常每个数据库对象(表,函数等等)属于并且只属于一个数据库. (不过有几个系统表,比如 pg_database ,属于整个安装 并且可以在安装之内的每个数据库里访问.) 一个与数据库服务器联接的应用应该在它的联接请求里面带有它想于之联接 的数据库名称.不允许在一次联接里面对多个数据库访问.(不过 没有限制一个应用与同一个或者其他数据库可以建立的联接数量.)

注意: SQL 把数据库称作 "目录" ,不过这两个东西实际上 没有什么区别.

为了创建和删除数据库, PostgreSQL postmaster 必须已经运行(参阅 Section 3.3 ).

6.1. 创建数据库

数据库是用查询语言命令 CREATE DATABASE 创建的: CREATE DATABASE :

CREATE DATABASE 

name

这里的 name 遵循 SQL 标识符的一般规则. 当前用户自动成为此新数据库的所有者.同时,以后删除这个数据库 也是这个用户的特权(同时还会删除其中的所有对象,即使那些对象 有不同的所有者也一样.)

创建数据库是一个有限制的操作.参阅 Section 7.1.1 获取如何赋权限的信息.

创世之初∶. 因为你需要与数据库服务器联接才能执行命令 CREATE DATABASE , 那么还有一个问题是任意节点的 第一个 数据库是怎样创建的? 第一个数据库总是由 initdb 命令在初始化数据存储区的时候 创建的.(参阅 Section 3.2 .)通常这个数据库叫 template1 而且不能被删除. 因此要创建第一个 "真正" 的数据库的时候 你可以与 template1 联接.

"template1" 的名字可不是随便取的,当创建一个新的数据库时, 实际上就是克隆了(复制)了模板数据库. 这就意味着你对 template1 做的任何修改都会传播到所有 随后创建的数据库.这就意味着说你不能把模板数据库用于真正的工作中, 但是如果明智地使用这个特性,那它可以带来许多方便.下面有更多细节. (译注:比如增加用户定义函数等等.)

另外,为了更方便一些,你还可以用一个 shell 脚本来创建新数据库, createdb .

createdb 

dbname

createdb 没变什么魔术,它和 template1 联接并执行 CREATE DATABASE 命令. 和上面介绍地完全一样.它在内部使用 psql 程序. createdb 的手册页包含使用它的细节.尤其是不带任何参数调用 createdb 将以当前用户名为名称创建数据库, 这可能是也可能不是你要的.

6.1.1. 模板数据库

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 . 参阅 Section 8.2.3 获取更多信息.

注意: template1 template0 没有任何特殊的状态, 除了 template1 这个名字是 CREATE DATABASE 以及各种象 createdb 这样的脚本的缺省源数据库名之外. 比如,我们可以删除 template1 ,然后从 template0 中创建它而不会有任何不良效果.如果我们不小心在 template1 里加了一堆垃圾,那么我们就会建议做这样的操作.

6.1.2. 变更位置

我们可以不在缺省位置创建的数据库.请注意所有数据库访问发生在数据 库服务器后端,因此声明的任何位置必须可以被后端访问.

可选数据库位置是通过环境变量引用的,环境变量里给出你想用的 存储位置的绝对路径.这个环境变量必须出现在服务器的环境里, 因此必须在后端启动之前定义.(这样,可选位置就可以在节点管理员的 控制之下;而普通用户则无法修改它.) 任何有效 的环境变量名都可以用于引用一个可选路径,尽管我们建议使 用带有 PGDATA 前缀的环境变量名以避免和其他变量混淆或冲突。

要在服务器进程的环境里定义环境变量,你必须先停止服务器,然后定义变量, 初始化数据区,最后重新启动服务器. (参阅 Section 3.6 Section 3.3 .) 要设置环境变量,在 Bourne shell 系列里面键入

PGDATA2=/home/postgres/data
export PGDATA2

或者是在 csh tcsh 里面键入

setenv PGDATA2 /home/postgres/data

你必须确保这些环境变量总是在服务器环境中存在,否则你就不能 访问数据库.因此你可能会希望把它们设置在 shell 启动脚本文件 或者服务器启动脚本里.

要使用环境变量 PGDATA2 创建数据存储区,确信 内容目录,(在这里是 /home/postgres ) 已经存 在并且可以被启动服务器的用户帐户写 (参阅 Section 3.1 )。然后在命令行上键入:

initlocation PGDATA2

然后重新启动服务器.

要在新的位置创建一个数据库,使用下面命令

CREATE DATABASE 

name

 WITH LOCATION = '

location

'

这里 location 是你用的环境变量, 本例中是 PGDATA2 createdb 命令有个选项 -D 做此用途.

在变更的位置创建的数据库可以象其他数据库一样访问和删除.

注意: 也可以直接给 CREATE DATABASE 命令声明一个绝对路径 而不需要定义环境变量.缺省时这是不允许的,因为有安全风险. 要允许这么做,你必须带着 C 预编译宏 ALLOW_ABSOLUTE_DBPATHS 编译 PostgreSQL .你可以这么干:

gmake CPPFLAGS=-DALLOW_ABSOLUTE_DBPATHS all