Postgres数据库

Postgres数据库

基本操作

1、连接数据库实例

# 在shell命令中,username是用户名,比如 postgres,dbname是要进入的数据库名
psql -U [username] -d [dbname]
# 如何已经进入了数据,可以用下面的sql切换数据库 dbname是要进入的数据库名
\c [dbname]

2、展示数据库列表

-- 都是在sql的交互式终端中运行
\list
\l
select datname from pg_database;

3、创建数据库

CREATE DATABASE [数据库名] WITH ENCODING = 'UTF8';

4、删除数据库

DROP DATABASE database_name;

如果删除失败 ERROR: database "database_name" is being accessed by other users DETAIL: There are 3 other sessions using the database.

SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'database_name';

确认无用连接,可以直接关闭

SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'database_name';

5、查询当前连接信息

\conninfo

响应示例

postgres=# \conninfo
You are connected to database "database_test" as user "postgres" via socket in "/var/run/postgresql" at port "5432".

6、查询连接数

-- 总连接数、空闲连接数和最大连接数
SELECT
(SELECT COUNT(*) FROM pg_stat_activity) AS total_connections,
(SELECT COUNT(*) FROM pg_stat_activity WHERE state = 'idle') AS idle_connections,
(SELECT COUNT(*) AS idle_in_transaction_connections FROM pg_stat_activity WHERE state = 'idle in transaction') AS idle_transaction_connections,
current_setting('max_connections')::int AS max_connections;

7、清屏

1、liunx 系统

\! clear

2、windows 系统

\! cls

角色权限管理

1、摘要实例

1.1 如何对一个新的数据库进行最简单粗略的授权

此实例授权非常粗略,但可以以此为基础进行细粒度的授权。

# 1、连接上数据库实例
# shell终端切换数据库超级用户
su postgres
# 并连接上实例
psql

# 2、新建角色
# 创建角色并设置登录密码 sahdiohdiqwho
create role [角色名] LOGIN PASSWORD 'sahdiohdiqwho';

create role anime_time_test LOGIN PASSWORD 'kLYSE*XbFAu3RN6l';
create role anime_time_prod LOGIN PASSWORD 'kLYSE*XbFAu3RN6l';

# 3、赋予角色权限
# 授权角色在数据库 test的 连接、创建新模式等权限
GRANT ALL PRIVILEGES ON DATABASE [数据库名] TO [角色名];

# 进入需要赋权的数据库(test数据库)中
\c test
# 授权角色在数据库 test 的 public 模式上所以权限
GRANT ALL PRIVILEGES ON SCHEMA public TO [角色名];


# 将 public 模式下现存的所有表的所有可用权限赋给角色
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO [角色名];
# 表创建者自动有该表的所以权限,也可以显示授权,此步骤可用可不用(当数据库中有多角色是,这条命令就很有用,比如生产上,可能增删改查的应用连接角色,另一个是仅有查询权限的角色。就可以让 表创建的时候自动默认给 仅查询角色 赋予查询权限)
# 这可就是当 test_role 在 public 模式下创建表,都会执行 GRANT ALL PRIVILEGES ON TABLES TO test_role;
ALTER DEFAULT PRIVILEGES FOR ROLE test_role IN SCHEMA public
GRANT ALL PRIVILEGES ON TABLES TO test_role;

GRANT ALL PRIVILEGES ON SCHEMA public TO anime_time_prod;

2、授权注意事项

  • 在 PostgreSQL 中,角色(Role)是一个通用的概念,既可以是普通的数据库用户,也可以是数据库中的组(用户组)。有 LOGIN 权限的角色被称为用户角色。而且ALTER USER现在是 ALTER ROLE 的一种别名。

  • PostgreSQL 中的授权模型是分层的,这点需要注意,数据库、模式、表、视图、等是相对独立的授权对象。即在数据库授权 ALL PRIVILEGES 并不会给数据库下的模式也授权,模式与表、视图也一样,所以都需要进行单独授权。

3、权限属性

3.1 角色基本操作

3.1.1 创建角色

ps:角色和操作系统用户之间维护一个名字对应关系通常是很方便的

-- 以下命令都在 数据的交互命令行中执行
-- [name] 填写自定义的角色名
create role [name];
# 需要使用 postgres 用户进行执行
su postgres
createuser [name]

3.1.2 删除角色

--  以下命令都在 数据的交互命令行中执行
-- [name] 填写需要删除的角色名
drop role [name];
# 需要使用 postgres 用户进行执行
su postgres
dropuser [name]

4、权限操作

4.1 权限赋予

1.4 权限赋予

登录权限(LOGIN)、超级用户状态(SUPERUSER)、数据库创建(CREATEDB)、启动复制(REPLICATION LOGIN 需要权限生效必须要有登录权限)、密码(PASSWORD *‘密码字符串’*)

1.5 角色权限修改

ALTER ROLE role_specification [ WITH ] option [ ... ]

其中option可以是:

      SUPERUSER | NOSUPERUSER
    | CREATEDB | NOCREATEDB
    | CREATEROLE | NOCREATEROLE
    | INHERIT | NOINHERIT
    | LOGIN | NOLOGIN
    | REPLICATION | NOREPLICATION
    | BYPASSRLS | NOBYPASSRLS
    | CONNECTION LIMIT connlimit
    | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL
    | VALID UNTIL 'timestamp'

ALTER ROLE name RENAME TO new_name

ALTER ROLE { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter { TO | = } { value | DEFAULT }
ALTER ROLE { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter FROM CURRENT
ALTER ROLE { role_specification | ALL } [ IN DATABASE database_name ] RESET configuration_parameter
ALTER ROLE { role_specification | ALL } [ IN DATABASE database_name ] RESET ALL

其中role_specification可以是:

    role_name
  | CURRENT_ROLE
  | CURRENT_USER
  | SESSION_USER

4.2 撤销授权

4.2.1 基础格式

REVOKE [要移除的权限] ON [在什么对象上] FROM [角色]

4.2.2 删除角色,提示依赖错误解决ERROR: role "test_role" cannot be dropped because some objects depend on it

4.2.2.1 DETAIL: owner of database database_test

当前角色是数据库 database_test 的所有者,需要删除该库或者将这个库的所有权转移给其它角色

4.2.2.2 DETAIL: privileges for database database_test

角色在数据库 database_test 中有权限依赖,先撤销该数据库上的所有权限

REVOKE ALL PRIVILEGES ON DATABASE [数据库名] FROM [角色名];
4.2.2.3 DETAIL: privileges for schema public

角色在 public 模式下具有 all privileges 权限,撤销它

REVOKE ALL PRIVILEGES ON SCHEMA public FROM [角色名];
4.2.2.4 DETAIL: privileges for tablespace pg_default

角色在表空间 pg_default 中有 ALL PRIVILEGES 权限,撤销它。

查询 pg_default 上有哪些角色权限

SELECT spcname, spcowner::regrole AS owner, array_agg(spcacl) AS privileges
FROM pg_tablespace
WHERE spcname = 'pg_default'
GROUP BY spcname, spcowner;

响应示例:

  spcname   |  owner   |                     privileges                     
------------+----------+----------------------------------------------------
 pg_default | postgres | {{postgres=C/postgres,test_role=C/postgres}}
(1 row)

撤销权限

REVOKE ALL PRIVILEGES ON TABLESPACE [表空间] FROM [角色];
4.2.2.5 privileges for table XXXX

角色在 xxx 表上有权限,可以先验证权限

-- 查询所有
SELECT grantee, table_name, privilege_type
FROM information_schema.role_table_grants
WHERE table_schema = 'public' AND grantee = '[角色名]';
-- 查询指定表名
SELECT grantee, table_name, privilege_type
FROM information_schema.role_table_grants
WHERE table_schema = 'public' AND grantee = '[角色名]' AND table_name IN ('[表名]');

撤销权限

-- 撤销单个表
REVOKE ALL PRIVILEGES ON TABLE [表名] FROM [角色名];
-- 撤销所有表
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM [角色名];
4.2.2.6 DETAIL: owner of table xxx

角色是 xxx 表的拥有者

SELECT schemaname AS schema, 
       tablename AS table, 
       tableowner AS owner
FROM pg_tables
WHERE tableowner = '[角色名]';

转移权限或删除表

-- 单个表转移所有者权限
ALTER TABLE [表名] OWNER TO [转给的目标角色];

-- 批量
DO $$ 
DECLARE 
    rec RECORD;
BEGIN
    FOR rec IN (SELECT schemaname, tablename 
                FROM pg_tables 
                WHERE tableowner = '[被转移的角色]' AND schemaname NOT IN ('pg_catalog', 'information_schema')) 
    LOOP
        EXECUTE format('ALTER TABLE %I.%I OWNER TO [转给的目标角色]', rec.schemaname, rec.tablename);
    END LOOP;
END $$;
4.2.2.7 DETAIL: privileges for default privileges on new relations belonging to role postgres in schema public

或者第二种提示

DETAIL: owner of default privileges on new relations belonging to role xxx_role_name in schema public

角色在 模式public中与自己有关联的默认权限行为,关联的角色名 如果是 owner 就是自己或者提示中的角色名。

SELECT 
    defaclrole::regrole AS role,
    defaclnamespace::regnamespace AS schema,
    defaclobjtype AS object_type,
    defaclacl AS privileges
FROM pg_default_acl
WHERE defaclnamespace = 'public'::regnamespace 
  AND defaclrole = (SELECT oid FROM pg_roles WHERE rolname = '[提示中的角色名]');

撤销

ALTER DEFAULT PRIVILEGES FOR ROLE [提示中的角色名] IN SCHEMA public
	REVOKE ALL ON TABLES FROM [要删除的角色];
	
ALTER DEFAULT PRIVILEGES FOR ROLE [提示中的角色名] IN SCHEMA public
	REVOKE ALL ON SEQUENCES FROM [要删除的角色];
	
ALTER DEFAULT PRIVILEGES FOR ROLE [提示中的角色名] IN SCHEMA public
	REVOKE ALL ON FUNCTIONS FROM [要删除的角色];
	
ALTER DEFAULT PRIVILEGES FOR ROLE [提示中的角色名] IN SCHEMA public
	REVOKE ALL ON TYPES FROM [要删除的角色];
	
ALTER DEFAULT PRIVILEGES FOR ROLE [提示中的角色名] IN SCHEMA public
	REVOKE ALL ON SCHEMAS FROM [要删除的角色];

ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public
	REVOKE ALL ON TABLES FROM anime_time_test;
4.2.2.8 DETAIL: 8 objects in database database_test

需要先进入这个库中 database_test 在进行删除角色,此将会提示该角色在该数据库中权限

5、检查授权

5.1 查询角色

1、第一种使用元命令,返回预设 postgres 角色以及 自定义创建的角色列表

-- 不填角色名,显示所以
\du [role_name]

响应示例

                                      List of roles
    Role name    |                         Attributes                         | Member of 
-----------------+------------------------------------------------------------+-----------
 nacos           | Create DB                                                  | {}
 postgres        | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

2、使用 sql 语句查询;这个语句返回包括预定义的角色 ( pg_ 开头) 以及具体的授权结果

SELECT * FROM pg_roles;

响应示例

 rolname  | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolconnlimit | rolpassword | rolvali
duntil | rolbypassrls | rolconfig | oid 
----------+----------+------------+---------------+-------------+-------------+----------------+--------------+-------------+--------
-------+--------------+-----------+-----
 postgres | t        | t          | t             | t           | t           | t              |           -1 | ********    |        
       | t            |           |  10

5.2 查询模式的授权信息

展示数据库下模式的授权信息

\dn+

响应示例

                                       List of schemas
  Name  |       Owner       |           Access privileges            |      Description       
--------+-------------------+----------------------------------------+------------------------
 public | pg_database_owner | pg_database_owner=UC/pg_database_owner+| standard public schema
        |                   | =U/pg_database_owner                  +| 
        |                   | test_role=UC/pg_database_owner         | 
(1 row)

5.3 查询表的授权信息

1、查询显示授权信息

-- 不填表名查询所有表
\dp [table_name]

响应示例:

其中 test 表是 postgres 创建的 test2test_role 创建的,其中 test2 有隐式授权,当前此命令无法显示出。

                                         Access privileges
 Schema |      Name       | Type  |        Access privileges         | Column privileges | Policies 
--------+-----------------+-------+----------------------------------+-------------------+----------
 public | test            | table | postgres=arwdDxt/postgres       +|                   | 
        |                 |       | test_role=arwdDxt/postgres       |                   | 
 public | test2           | table |                                  |                   | 
        |                 |       |                                  |                   |                   
(2 rows)

2、查询隐式授权,或者说是表的所有者

-- 查询模式 public 下所有的表
SELECT schemaname, tablename, tableowner
FROM pg_tables
WHERE schemaname = 'public';

-- 查询特定的表
SELECT schemaname, tablename, tableowner
FROM pg_tables
WHERE tablename = 'test';

响应示例:

tableowner 是 PostgreSQL 系统目录视图 pg_tables 中的一列。它表示该表的所有者,即最初创建表的用户。这个用户通常具有对该表的所有权限。

 schemaname |    tablename    |   tableowner    
------------+-----------------+-----------------
 public     | test            | postgres
 public     | test2           | test_role
(2 rows)

3、查询表更详细的授权

SELECT grantee, table_catalog, table_schema, table_name, privilege_type
FROM information_schema.role_table_grants
WHERE table_name = 'cc';

响应示例:

table_catalog 是数据库名称

     grantee     |  table_catalog  | table_schema | table_name | privilege_type 
-----------------+-----------------+--------------+------------+----------------
 anime_time_test |  database_test  | public       | test       | INSERT
 anime_time_test |  database_test  | public       | test       | SELECT
 anime_time_test |  database_test  | public       | test       | UPDATE
 anime_time_test |  database_test  | public       | test       | DELETE
 anime_time_test |  database_test  | public       | test       | TRUNCATE
 anime_time_test |  database_test  | public       | test       | REFERENCES
 anime_time_test |  database_test  | public       | test       | TRIGGER
(7 rows)

5.4 查询角色上绑定的默认授权

查询所有角色上绑定的默认授信信息

SELECT 
    defaclrole::regrole AS role,
    defaclnamespace::regnamespace AS schema,
    defaclobjtype AS object_type,
    defaclacl AS privileges
FROM pg_default_acl;

查询 postgres 角色上绑定的默认授信信息

SELECT 
    defaclrole::regrole AS role,
    defaclnamespace::regnamespace AS schema,
    defaclobjtype AS object_type,
    defaclacl AS privileges
FROM pg_default_acl
WHERE defaclrole = (SELECT oid FROM pg_roles WHERE rolname = '[角色名]');

响应示例:

其中,object_type的权限含义

权限简写对应权限类型含义
rTABLES表类型
SSEQUENCES序列
fFUNCTIONS函数
TTYPES类型

其中,privileges里的权限含义如下

权限简写权限全称含义
rSELECT允许读取(查询)表的内容
wUPDATE允许更新表的现有行
aINSERT允许插入新行到表中
dDELETE允许删除表中的行
DTRUNCATE允许使用 TRUNCATE 命令清空表
xREFERENCES允许在其他表中创建引用此表列的外键
tTRIGGER允许在表上创建触发器
UUSAGE主要用于 SEQUENCESSCHEMAS,允许使用这些对象
   role   | schema | object_type |                        privileges                         
----------+--------+-------------+-----------------------------------------------------------
 postgres | -      | T           | {postgres=arwdDxt/postgres,test_role=arwdDxt/postgres}
 postgres | -      |            | {postgres=rwU/postgres}
(2 row)

数据库配置

1、连接配置

max_connections (integer)

决定数据库的最大并发连接数。默认值是 100 个连接。这个数值包括所有普通用户和超级用户的连接。并且这个设置是实例级别的,如果实例中有多个库,需要注意此设置

superuser_reserved_connections (integer)

为PostgreSQL超级用户(通常是 postgres 用户)连接而保留的连接数。默认值是 3 连接 。

!ps:所以非必要的情况下,日常不要去使用超级用户连接数据库