ch04 PostgreSQL 中的全局对象
简介
PostgreSQL 中包含一些安装时就创建的对象, 并且这些对象不会被绑定到任何独立的数据库中. 这些对象可以操作, 或在多个数据库或数据库对象 (例如 tables, indexes, functions 等) 中共享. 了解这些对象可以更好的操作 PostgreSQL.
结构
主要内容
- Users/Groups/Roles
- Tablespaces/Databases
目标
学习一些全局对象, 并介绍它的一些操作.
Users/Groups/Roles
你一定听过用户和组. 访问数据库的就是用户, 组是为了方便管理的对象. 但是什么是角色呢? 下面进行讨论.
在 PostgreSQL 8.1 之前, 用户和组是普遍使用的概念. 它们是两个独立的实体. 但是现在引入了角色, 它可以是用户与组的合体.
因此现在在 PostgreSQL 中讨论角色的时候, 本质上是在说一个数据库用户, 或一组数据库用户 (组). 这取决于如何设置. 使用角色就可以控制谁允许访问什么.
角色可以拥有不同的数据库对象, 可以持有多个权限. 它可以赋值给其他角色, 更进一步, 也可以将多个成员授予给其他角色.
可以使用 \du
来查看现有角色.
角色 (Roles) 是全局对象, 是在数据库集群安装时创建的. 它不属于某个独立的数据库.
在安装新的 PostgreSQL 实例, 并使用 initdb
命令初始化时, 一个新的角色就会被创建, 同时该角色具有 superuser
特性. 该角色具有所有权限. 因此该角色可以创建其他角色, 并设置其特权, 也可以创建数据库. 该 "管理员" 角色会命名为初始化 PostgreSQL 的操作系统用户的名字, 通常是 postgres
. 我们应该保护该用户的凭证, 因其超管的权限, 避免对系统造成破坏.
创建角色可以使用下面的语法. 同时可以为新与用户添加可选项. 例如 LOGIN
设置准备连接, PASSWORD
来设置密码:
CREATE ROLE demouser LOGIN PASSWORD 'supersecurepass';
进入 psql
后, 可以使用 \h CREATE ROLE
来查看帮助, 可以查看可选项:
创建角色一个比较好的习惯是带上 CREATEROLE
和 CREATEDB
, 而不是使用 SUPERUSER
. 然后使用这个角色来创建其他角色与数据库.
如果想要删除角色, 可以使用:
DROP ROLE demouser;
注意结尾的分号, 与 MySQL 一样, 表示语句输入结束. 也可以使用
\g
.使用
\! clear
可以清屏
如果使用其他客户端连接到数据库, 而不是 psql
, 可以查询 pg_roles
视图来查看角色:
SELECT * FROM pg_roles;
上述以经了解到如何创建角色或用户, 并使其具有 LOGIN
特性. 这个用户可以在数据库中开启一个新的会话. 然而我们必须记住什么角色具有什么权限, 以及将其成员扩展到其他角色中. 比较好的处理办法是权限挂载到组中, 然后将用户添加到组中.
将角色作为组来使用, 通常不会使用它来连接数据库, 开启新的会话. 因此不会添加 LOGIN
, PASSWORD
特性. 因此一般可以使用下面代码来创建角色:
CREATE ROLE admins;
再一次解释了, 为什么角色是用户与组的结合体. 根据处理逻辑的不同, 有时角色就是用户, 有时是组.
然后, 为该组 (角色) 附加权限, 例如:
GRANT SELECT ON public.table1 TO admins;
GRANT SELECT ON public.table2 TO admins;
最后, 添加一个, 多多个用户到该组中 (通过授予角色到用户上)
GRANT admins TO demouser, testuser, produser;
实际上这里的用户, 组, 角色, 是一个类型的对象.
然后, 所有用户 demouser
, testuser
, produser
都可以在 public.table1
, public.table2
上执行 SELECT
语句了.
创建角色时, 可以使用 INHERIT
或 NOINHERIT
来控制层级结构. 默认, 所有角色均可以从授予权限的角色上继承权限. 但是, 在创建角色时, 指定了 NOINHERIT
, 那么该角色无法从已授予权限的角色中继承权限. 如此, 可已设计一些特别的控制. 例如:
CREATE ROLE sampleuser LOGIN INHERIT;
CREATE ROLE admin NOINHERIT;
CREATE ROLE reader NOINHERIT;
GRANT admin TO sampleuser;
GRANT reader TO admin;
任何授予 admin
的权限, sampleuser
都具备, 因为它配置了 INHERIT
.
但是, 即使 sampleuser
间接的成为了 reader
的成员, 但是它不会含有 reader
的任何权限. 因为, 这个关系经过了 admin
, 它不允许继承权限 (admin
是 NOINHERIT
, 它无法继承其他角色的权限).
最后, 看看被称之为预定义的角色. 这些角色在数据库初始化时被创建. 这些角色组含有特定的特性与权限, 并且使用其作用来命名. 这么处理有利于管理与之有关的任务.
然后作者给出一个表格, 列举出了一个角色与其作用的表. 这个表可以在社区文档中可以查阅到, 但需要注意这些可能会随版本的变化而变化.
社区文档中给出了 11 个预定义角色, 而本书中列举出了 9 个.
角色 | 允许访问 |
---|---|
pg_read_all_data | 允许从所有的数据表, 视图, 和序列中读取数据. 因为在这些对象上具有 SELECT 权限, 在所有的 Schema 上具有 USAGE 权限. |
pg_write_all_data | 允许在所有的表, 视图, 和序列中写入数据. 因为这些对象具有 INSERT , UPDATE , 和 DELETE 权限. 同时所有的 Schema 中具有 USAGE 权限. |
pg_read_all_settings | 允许读取所有配置变量, 包括仅对超级用户可见的配置变量. |
pg_read_all_stats | 允许读取所有 pg_stat_* 视图, 并使用各种统计相关扩展. |
pg_monitor | 允许读取/执行各种监控视图和功能. 这是设置监视应用程序用户的最佳选项. |
pg_signal_backend | 允许向另一个后端发送信号以取消查询或终止其会话. |
pg_read_server_files | 允许从数据库在服务器上可以访问的任何位置读取文件. |
pg_write_server_files | 允许写入数据库在服务器上可以访问的任何位置的文件. |
pg_execute_server_program | 允许以数据库运行用户的身份在数据库服务器上执行程序. |
表空间 (Tablespaces)
PostgreSQL 中表空间就是操作系统上的一个路径, 用于存储数据库对象. 如表, 索引等.
当 PostgreSQL Database Cluster 初始化时, 在 Data Directory 中会默认创建两个表空间. 分别是: pd_global
和 pg_default
.
pg_global
用于存储所有的 catelog system data.pg_default
是默认表空间, 用于存储所有的template0
,template1
数据库的数据.
因此, 在创建新数据库时, 不作任何处理, 该属性会将数据库当做 template 数据库.
要创建表空间, 我们需要一个已存在的路径, 同时运行 postres
实例的用户也需要拥有路径的访问权限. 通常是 postgres
用户.
CREATE TABLESPACE newspace LOCATION
'/var/lib/postgresql/newspace'
查询已存在的表空间, 使用 psql
命令 \db
, 获得查询视图 pg_tablespace
使用 \db+
可以获得更为详细的信息
表空间主要有两个作用:
- 扩展磁盘时扩展数据存储.
- 充分利用存储设备性能 (将数据按磁盘存放, 可以提升 IO, 例如索引, 热数据等).
数据库
首先介绍数据库和实例.
实例由端口, 数据域 (数据目录) 构成, 它包含一个服务.
服务器上可以含有一个, 或多个数据库实例. 它们有独立的端口, 数据目录.
数据库集群 (database cluster), 包含多个数据库, 用户/角色, 以及多个表空间.
一个 postgres 实例总是恰好的管理一个 database cluster 中的数据.
database 是 instance/cluster 的一部分.
每一个 DB Instance/DB Cluster 都包含多个 database.
一个 database 是多个 database schema 的集合. 而 database schema 存储 database 对象, 如表, 视图, 包, 函数等.
数据库是实例的一部分, 在 PostgreSQL 对象架构中的顶层.
然后作者用, 屋子, 房间, 衣柜, 抽屉来比喻实例, 数据库, 架构, 数据库对象.
使用 \l
可以查看默认安装的数据库
CREATE DATABASE
命令
创建数据库使用 CREATE DATABASE
命令, 使用 psql
的元数据命令 (meta-command) \h
可以查看语法:
最简单的创建数据库的语法为:
CREATE DATABASE <database_name>;
createdb
程序
该程序是 CREATE DATABASE
的包装程序:
使用 createdb --help
可获得帮助
使用 pgAdmin
向导
pgAdmin
是一个 GUI 程序. 网址: https://www.pgadmin.org/
下载与安装
下载后, 双击安装. 然后下一步, ...即可
看起来是 Electron 进行开发的.
安装完成后双击运行, 进入初始化也没, 第一次会等待一段时间.
前期准备
数据库配置
连接到 PostgreSQL 需要一些配置
- 修改配置文件, 设置监听端口.
- 创建秘密.
- 修改
pg_hba.conf
配置文件中绑定的 IP.
通过查看后台进程, 来查看配置文件目录:
ps -ef | grep postgres
配置文件目录为: /etc/postgresql/14/main/postgresql.conf
, 打开配置文件, 找到 listen_addresses
, 修改为服务器 IP.
sudo vim /etc/postgresql/14/main/postgresql.conf
默认 PostgreSQL 监听 localhost
.
在配置文件所在的目录, 还有一个文件: pg_hba.conf
在该文件结尾处添加:
host all all 0.0.0.0/0 md5
最后重启数据库服务.
使用二进制安装后, 会自动添加后台服务:
可以使用下面命令查看运行状态:
/etc/init.d/postgresql status
使用下面命令重启 PostgreSQL 服务:
sudo systemctl restart postgresql
或使用 service
命令
sudo service postgresql restart
也可以使用 pg_ctl
程序:
sudo -u postgres pg_ctl restart -D /var/lib/postgresql/<version>/main
注意版本, 以及路径. 细节可以参考: https://www.postgresqltutorial.com/postgresql-administration/postgresql-restart-ubuntu/
设置数据库密码
进入数据库后, 使用 \password [USER]
来设置密码
使用 pgAdmin 连接
连接成功后即可看到数据库运行状态:
使用 pgAdmin
创建数据库
右击, 左侧树中的 Database Cluster, 在弹出上下文菜单中选择 Create Database 选项.
或在 Database 节点上右键.
在弹出的向导对话框中输入数据库名字, 以及所有者. 并编辑注释.
然后, 在 Definition 选项卡中设置表空间
设置完成后可以切换至 SQL 选项卡, 会自动生成对应的 SQL 语句:
创建后可以在左侧树中看到新数据库
最后除了创建, 还有 ALTER DATABASE
, DROP DATABASE
, 以及 dropdb
可以使用, 来进行修改, 删除数据库.