少数核心对象(例如角色名称、数据库名称以及表空间名称)在整个数据库集群实例层级全局定义,并集中持久化存储在 pg_global 全局表空间中。在集群内部包含多个彼此隔离的数据库,它们彼此无法直接穿透访问,但均能透明访问集群级的全局对象。在每个数据库内部,又可以细分包含多个模式(Schemas),模式内部分组存放着具体的数据表、视图与函数。因此系统的完整层级脉络为:集群实例 → 数据库 → 模式 → 数据表(或其他具体对象)。
当客户端连接到数据库服务器时,必须在连接握手协议中明确指定待连接的目标数据库名称。在单次连接会话内无法直接跨库访问多张不同数据库。不过,客户端可以通过开启多个并发连接分别访问不同的数据库。数据库层级的安全机制由两部分构成:基于连接策略的访问控制(参见 Section 20.1),以及基于授权体系的对象操作权限管理(参见 Section 5.8)。借助外部数据包装器(参见 postgres_fdw),也可以在一个数据库中将其他数据库中的表作为远程代理表进行跨库联合查询。
如果计划在一个 PostgreSQL 集群内承载互不相关的独立项目或租户,且他们理应彼此完全隔离,强烈推荐将它们部署在不同的独立数据库中,并相应收紧权限。反之,如果各业务之间存在紧密的数据关联与资源互访需求,则应将其置于同一个数据库下的不同模式(Schema)中;这样既提供了清晰的命名空间隔离,又便于在单事务内执行跨模式高效关联。关于模式管理的更多信息,参见 Section 5.10。
虽然单集群内允许创建任意数量的数据库,但在架构设计上应当充分评估其运维代价。特别需要指出的是,同一集群内的所有数据库共享同一套底层的预写式日志 WAL(参见 Chapter 28),这意味着集群级的备份与物理恢复是以实例为单元全局联动的。从业务用户视角看各个库是隔离的,但从数据库管理员(DBA)视角看它们物理深度绑定。
创建数据库使用 CREATE DATABASE 命令(参见 Section 22.2);销毁数据库使用 DROP DATABASE 命令(参见 Section 22.5)。查看当前集群中已存在的所有数据库,可查询系统目录视图 pg_database:
SELECT datname FROM pg_database;
在命令行终端客户端 psql 中,也可以直接通过元命令 \l 列出全量数据库清单。