打印

PostgreSQL学习文档 8.0 四

PostgreSQL学习文档 8.0 四

Chapter 17. 数据库用户权限
Table of Contents
17.1. 数据库用户
17.2. 用户属性
17.3. 组
17.4. 权限
17.5. 函数和触发器
每个数据库集群都包含一个数据库用户的集合。 这些用户是和那些在同一个服务上运行的操作系统的用户相独立的。 用户拥有数据库对象(比如说,表)以及可以把这些对象的权限赋予其它用户,这样就能控制谁可以访问哪些对象。

本章描述如何创建和管理用户,以及介绍权限系统。 有关各种类型的数据库对象和权限的效果可以在 Chapter 5 中找到。

17.1. 数据库用户
数据库用户从概念上与操作系统用户是完全无关的。 在实际使用中把它们对应起来可能比较方便,但不是必须的。 数据库用户名在整个数据库集群中是全局的(而不是每个库不同)。 要创建一个用户,使用 SQL 命令 CREATE USER:

CREATE USER name;
name 遵循 SQL 标识的规则: 要么完全没有特殊字符,要么用双引号引起。 要删除一个现有用户,使用类似的命令 DROP USER:

DROP USER name;

为了方便,程序 createuser 和 dropuser 提供了对了这些 SQL 命令的封装。 我们可以在 shell 命令上直接调用它们:

createuser name
dropuser name

要判断一套现有用户,检查 pg_user 系统表,比如

SELECT usename FROM pg_user;
psql 的元命令 \du 也可以用于列出现有用户。

为了能初创数据库系统,新建立的数据库总是包含一个预定义的用户。 这个用户将有固定的 ID 1, 并且缺省时(除非在运行 initdb 时更改过)他将和初始化该数据库集群的用户有相同的名称。 通常,这个用户叫postgres。 为了创建更多用户,你必须首先以这个初始用户身份联接。

一个和数据库的活跃连接只能有一个用户身份进行。 和特定数据库联接的用户名是由初始化联接请求的应用以应用相关的方式声明的, 比如,psql 程序使用-U命令行选项声明它代表的进行联接的用户。 许多应用以当前操作系统的用户名为缺省(这样的应用包括 createuser 和 psql)。 这样我们就可以很方便地维护这两个用户集合之间地映射关系。

一个客户端联接可以用来联接的数据库用户集合是由客户认证设置决定的, 在 Chapter 19 里面有解释。 (因此,一个客户端并不局限于以它的操作系统用户同名的用户进行联接, 就象你登录系统的名称不一定要是你的真实姓名一样。) 因为用户地身份决定了一个已连接地客户端可用的权限, 所以在多用户环境里仔细配置这些内容是非常重要的。

TOP

17.2. 用户属性
一个数据库用户可以有一系列属性,这些属性定义他的权限,以及与客户认证系统的交互。



超级用户
数据库超级用户超越所有权限检查。同样,只有超级用户才能创建新的用户。 要创建数据库超级用户,用 CREATE USER name CREATEUSER。

创建数据库
用户要想创建数据库,必须明确给出权限(对于超级用户是例外,因为他们超越所有权限检查)。 要创建这样的用户,用 CREATE USER name CREATEDB。

口令
只有在对客户认证方法要求客户在与数据库建立连接是使用口令的时候,口令才比较重要。 password,md5,和 crypt 认证方法使用口令。 数据库口令与操作系统口令是无关的。在创建用户的时候声明一个口令是这样: CREATE USER name PASSWORD 'string'。

一个用户的属性可以在创建后用 ALTER USER 修改。 参考 CREATE USER 和 ALTER USER 的手册获取细节。

一个用户也可以为许多运行时配置设置个人缺省, 那些配置在 Section 16.4 里描述。 比如,如果出于某种原因你想在所有你做的连接中关闭索引扫描(提示:不是个好主意), 你可以用

ALTER USER myname SET enable_indexscan TO off;
这样就会保存该设置(但是不是立即设置)。 这么做后,在随后的连接中就好像在会话开始之后都马上 SET enable_indexscan TO off;了一样。 你也可以在会话中修改这个设置;它只是缺省。要撤销任何这样的设置, 使用 ALTER USER username RESET varname;。

TOP

17.3. 组
和 Unix 里一样,组是一个逻辑上对用户分组,进而简化权限管理的方法: 权限可以赋予整个组,也可以对整个组撤除。要创建一个组,使用 SQL 命令 CREATE GROUP:

CREATE GROUP name;
要向组中增加用户或删除用户,用 SQL 命令 ALTER GROUP:

ALTER GROUP name ADD USER uname1, ... ;
ALTER GROUP name DROP USER uname1, ... ;
要删除一个阻,使用 DROP GROUP:

DROP GROUP name;
这样只会删除组,不删除成员用户。

要判断现存组的集合,检查系统表 pg_group,比如

SELECT groname FROM pg_group;
psql 程序的 \dg 元命令也用于列出现有组。

TOP

17.4. 权限
当创建一个数据库对象时,它属于一个用户。该用户就是执行创建命令的那位。 要改变一个表,索引,序列,或者视图的所有者,使用 ALTER TABLE 命令。 缺省时,只有所有者(或者超级用户)可以对该对象做任何事情。为了让别的用户也能用它,必须赋予那些用户权限。

我们有以下几种权限:SELECT(读), INSERT(追加), UPDATE(写),DELETE, RULE(规则),REFERENCES(外键), TRIGGER, CREATE,TEMPORARY,EXECUTE, USAGE,和 ALL PRIVILEGES。 有关PostgreSQL所支持的权限的更多信息, 请参阅 Part VI 里面的 GRANT 页获取更多详细的信息。 修改或者删除一个对象的权限总是只有该对象的所有者才有。 要赋予权限,必需使用 GRANT 命令。 要赋权限,用GRANT命令。因此,如果 joe 是一个现存用户,而 accounts是一个现存表,那么可以这样赋予更新权限

GRANT UPDATE ON accounts TO joe;
执行这条命令的用户必须是表的所有者。要给一个组赋权限,用

GRANT SELECT ON accounts TO GROUP staff;
特殊的"用户"名 PUBLIC可以用于给系统中的每一个用户赋权限。 写 ALL 在权限声明位置上表明赋予所有权限。

要废除一个权限,用 REVOKE 命令:

REVOKE ALL ON accounts FROM PUBLIC;
表所有者的特殊权限(也就是说,做 DROP,GRANT, REVOKE 等等的权限)总是隐含给所有者的,并且不能赋予或者删除。 但是表所有者可以废除他的普通权限,比如给自己做一个只读的表,就象给别人做一样。

TOP

17.5. 函数和触发器
函数和触发器允许用户向后端服务器插入代码,这样其他用户可以在不知觉的情况下执行这些代码。 因此,两种机制都可以让用户相当隐蔽地给别人设置 "Trojan horse(木马)", 唯一的有效防护就是严格控制谁可以定义函数。

后端服务器里面运行的函数都是以数据库服务器守护进程的操作系统权限运行的。 如果所使用的编程语言允许无检查的内存访问,那么是可能修改服务器的内部数据结构也是可能的。 因此,除了其他问题外,这样的函数可以绕过任何系统访问控制。 允许这样访问的函数语言都被认为是"不可信的(untrusted)", PostgreSQL 只允许超级用户使用这样的语言书写函数。

TOP

Chapter 18. 管理数据库
Table of Contents
18.1. 概述
18.2. 创建数据库
18.3. 模板数据库
18.4. 数据库配置
18.5. 删除数据库
18.6. 表空间
每个正在运行的PostgreSQL服务器实例都管理着一个或多个数据库。 因此,在组织SQL("数据库对象")对象的层次中,数据库位于最顶层。 本章描述数据库的属性,以及如何创建,管理,和删除它们。

18.1. 概述
数据库是一些SQL对象("数据库对象")的命名集合; 通常每个数据库对象(表,函数等等)属于并且只属于一个数据库。 (不过有几个系统表,比如 pg_database,属于整个集群并且可以在集群之内的每个数据库里访问。) 更准确地说,一个数据库是一个模式的集合,而模式包含表,函数等等。 因此完整的层次是这样的:服务器,数据库,模式,表(或者其他类型对象,比如函数)。

在与数据库服务器联接的时候,应用应该在它的联接请求里面带有它想与之联接的数据库名称。 不允许在一次联接里面对多个数据库访问.(不过没有限制一个应用与同一个或者其他数据库可以建立的联接数量.) 数据库是物理上相互隔离的, 对它们的访问控制是在联接层次进行控制的。如果一个PostgreSQL 服务器实例用于承载那些应该分隔并且相互之间并不知晓的用户和项目, 那么我们建议把它们放在不同的数据库里。如果项目或者用户是相互关联的, 并且可以相互使用对方的资源,那么应该把它们放在同一个数据库里, 但可能是不同的模式里。模式只是一个纯粹的逻辑结构,谁能访问某个模式由权限系统控制。 有关管理模式的更多信息在 Section 5.8 里。

数据库是使用 CREATE DATABASE 命令创建的(参阅 Section 18.2), 用 DROP DATABASE 命令删除(参阅 Section 18.5)。 要判断现有数据库的集合,检查系统表 pg_database,比如

SELECT datname FROM pg_database;
psql 程序的 \l 元命令和 -l 命令行选项也可以用来列出现存数据库。

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

TOP

18.2. 创建数据库
为了创建和删除数据库, 必须先运行PostgreSQL服务器(参阅 Section 16.3)。

数据库是用 SQL 命令 CREATE DATABASE: 创建的:

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

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

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

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

另外,为了方便,你还可以用一个可以在 shell 中执行的程序来创建新数据库,createdb。

createdb dbname
createdb 没变什么魔术,它和template1连接并执行 CREATE DATABASE 命令。 createdb 的手册页包含使用它的细节。尤其是不带任何参数调用 createdb 将以当前用户名为名称创建数据库, 这可能是也可能不是你要的。

注意: Chapter 19 包含有关如何限制某个用户可以连接的数据库的信息。

有时候你想为其他什么人创建一个数据库。那个用户应该成为新数据库的所有者,这样他就可以自己配置和管理这个数据库。要实现这个目标, 使用下列命令中的某一条:

CREATE DATABASE dbname OWNER username;
上面的是在 SQL 环境中,或者是

createdb -O username dbname
要想为其他用户创建一个数据库,你自己必须是数据库的超级用户。

TOP

18.3. 模板数据库
CREATE DATABASE 实际上是通过拷贝一个现有的数据库进行工作的。 缺省时,它拷贝名字叫 template1 的标准系统数据库。 所以该数据库是创建新数据库的"模板"。如果你给 template1 增加对象,这些对象将被拷贝到随后创建的用户数据库中。 这样的行为允许节点对数据库中的标准套件进行修改。 比如,如果你把过程语言 PL/pgSQL 安装到 template1 里,那么你在创建用户数据库的时候它们就会自动可得,而不需要额外的动作。

系统里还有第二个标准的系统数据库,叫 template0。 这个数据库包含和 template1 一开始时一样的数据内容, 也就是说,只有你使用的版本的 PostgreSQL 标准的对象。在 initdb 之后,我们不应该对 template0 做任何修改。通过告诉 CREATE DATABASE 使用 template0 而不是 template1 进行拷贝, 你可以创建一个"纯净"的用户数据库,它不会包含任何 template1 里节点所特有的东西。 这一点在恢复 pg_dump 转储的时候是非常方便的: 转储脚本应该在一个纯洁的数据库中恢复以确保我们创建了被转储出的数据库中的正确内容, 而不和任何现在可能已经存在在 template1 中的附加物相冲突。

要通过拷贝 template0 的方法创建一个数据库, 使用

CREATE DATABASE dbname TEMPLATE template0;
这条命令是在 SQL 环境里的,或者是在 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。

完成模板数据库的准备之后,或者对某个数据库做了任何标记修改之后, 在该数据库中执行一次 VACUUM FREEZE 是一个好主意。 如果做这些的时候在同一个数据库中没有其它打开的事务,那么系统保证在数据库中的行是"冻结"的, 并且不会受事务 ID 重叠的影响。这个动作对那些 datallowconn 设置为假的数据库特别重要, 因为在这样的数据库上没有办法做日常维护性的VACUUM。 参阅 Section 21.1.3 获取更多信息。

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

TOP

18.4. 数据库配置
回顾一下 Section 16.4,我们知道PostgreSQL 服务器提供了大量的运行时配置变量。你可以为许多这样的变量设置数据库相关的缺省数值。

比如,如果由于某种原因,你想关闭某个数据库上的 GEQO 优化器,你就不得不要么在一开始就在所有数据库中关闭它,要么是保证每个连接过来的客户端都很小心地发出了 SET geqo TO off; 命令。要令这个设置在特定数据库里成为缺省,你可以执行下面的命令

ALTER DATABASE mydb SET geqo TO off;
这样将保存该设置(但不是立即设置它)。 在随后的连接中它将表现出像在会话开始后马上调用了 SET geqo TO off;的性质。 请注意用户仍然可以在该会话中更改这个设置;它只是缺省。要撤消这样的设置,使用 ALTER DATABASE dbname RESET varname;.

TOP

18.5. 删除数据库
数据库是用命令 DROP DATABASE: 删除的:

DROP DATABASE name;
只有数据库的所有者(也就是说,创建数据库的用户),或者超级用户可以删除数据库。 删除数据库会删除数据库中包括的所有对象。数据库的删除是不可恢复的。

你不能在与目标库联接的时候执行 DROP DATABASE 命令。 不过,你可以和其他数据库联接,包括template1数据库, template1也是你删除一个集群上的最后一个库的唯一方法。

为了方便,有一个在shell上运行的删除数据库的程序dropdb:

dropdb dbname
(和createdb不一样,dropdb 没有缺省删除名称为当前用户名的数据库的设置。)

TOP


感谢一直以来您对我们的支持!
当前时区 GMT+8, 现在时间是 2008-10-11 03:07 京ICP证060528 号

Designed By 17DST