schema的特色html
使用schema的做用sql
好比要设计一个复杂系统,由众多模块构成,有时候模块间又须要有独立性。各模块存放单独的数据库显然是不合适的。 这时候使用schema来分类各模块间的对象,再对用户进行适当的权限控制,这样逻辑也很是清晰。数据库
经常使用数据库中的schema异同bash
大多数数据库都有schema或者同等意义的概念,可是含义和具体操做不一样。函数
本次测试软件环境以下post
CentOS 7 x64测试
PostgreSQL 11.1ui
咱们须要在PostgreSQL中创建一个database,而且在这个db下创建多个schema。每一个schema有本身的owner,而且db owner能够操做全部schema。spa
简单的权限关系矩阵以下设计
user \ schema | S00 | S01 | S02 |
---|---|---|---|
db_demo_owner (db owner 主用户) | Y | Y | Y |
schema_owner_01(子用户) | N | Y | N |
schema_owner_02(子用户) | N | N | Y |
-- 使用superuser登陆(admin是提早创建的superuser,避免直接使用postgres)
psql --username=admin --dbname=postgres --password
复制代码
-- 新建用户,这个用户将成为Master用户
drop user if exists db_demo_owner;
create user db_demo_owner with password 'xxx';
-- 新建一个子用户
drop user if exists schema_owner_01;
create user schema_owner_01 with password 'xxx';
-- 经过设置权限组的方式让主用户拥有子用户的权限
-- db_demo_owner is member of schema_owner_01,即主用户db_demo_owner拥有schema_owner_01的权限
grant schema_owner_01 to db_demo_owner;
-- 另外一个子用户
drop user if exists schema_owner_02;
create user schema_owner_02 with password 'xxx';
grant schema_owner_02 to db_demo_owner;
复制代码
-- 新建一个测试用DB并分配给主用户
drop database if exists db_demo;
create database db_demo with encoding='utf8' owner=db_demo_owner;
复制代码
-- 主用户登陆
psql --username=db_demo_owner --dbname=db_demo --password
复制代码
-- 不指定schema owner,默认是当前用户(主用户)
drop schema s00 cascade;
create schema s00 ;
-- 用主用户创建schema并设置子用户为owner
drop schema s01 cascade;
create schema s01 authorization schema_owner_01 ;
drop schema s02 cascade;
create schema s02 authorization schema_owner_02 ;
复制代码
-- 主用户登陆
psql --username=db_demo_owner --dbname=db_demo --password
-- 主用户在每一个schema中建表t00
create table s00.t00(id int);
insert into s00.t00 values(1);
create table s01.t00(id int);
insert into s01.t00 values(1);
create table s02.t00(id int);
insert into s02.t00 values(1);
复制代码
不一样子用户在本身的schema中建表
-- 子用户1 登陆
psql --username=schema_owner_01 --dbname=db_demo --password
create table s01.t01(id int);
insert into s01.t01 values(1);
复制代码
-- 子用户2 登陆
psql --username=schema_owner_02 --dbname=db_demo --password
create table s02.t02(id int);
insert into s02.t02 values(1);
复制代码
-- 主用户是DB Owner
postgres=# \l db_demo
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
---------+---------------+----------+-------------+-------------+-------------------
db_demo | db_demo_owner | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
(1 row)
-- 主用户在子用户组里面,即已经拥有子用户的权限
postgres=# \du *owner*
List of roles
Role name | Attributes | Member of
-----------------+------------+-----------------------------------
db_demo_owner | | {schema_owner_01,schema_owner_02}
schema_owner_01 | | {}
schema_owner_02 | | {}
复制代码
-- 三个schema分属于不一样用户
db_demo=> \dn s*
List of schemas
Name | Owner
------+-----------------
s00 | db_demo_owner
s01 | schema_owner_01
s02 | schema_owner_02
(3 rows)
复制代码
-- 五张表分属于不一样的用户
db_demo=> \dt s*.
List of relations
Schema | Name | Type | Owner
--------+------+-------+-----------------
s00 | t00 | table | db_demo_owner
s01 | t00 | table | db_demo_owner
s01 | t01 | table | schema_owner_01
s02 | t00 | table | db_demo_owner
s02 | t02 | table | schema_owner_02
(5 rows)
复制代码
没有单独受权的时候,子用户仅能访问本身的表
-- 子用户1 登陆
psql --username=schema_owner_01 --dbname=db_demo --password
-- 无权限
db_demo=> select * from s00.t00;
ERROR: permission denied for schema s00
db_demo=> select * from s02.t02;
ERROR: permission denied for schema s02
-- 有权限
db_demo=> select * from s01.t01;
id
----
1
(1 row)
复制代码
主用户可以访问全部表
-- 主用户登陆
psql --username=db_demo_owner --dbname=db_demo --password
-- 都有权限
db_demo=> select * from s00.t00;
id
----
1
(1 row)
db_demo=> select * from s01.t01;
id
----
1
(1 row)
db_demo=> select * from s02.t02;
id
----
1
(1 row)
复制代码
s02原来属于owner02,如今变动为owner01
-- 主用户登陆
psql --username=db_demo_owner --dbname=db_demo --password
-- 变动前
db_demo-> \dn s02
List of schemas
Name | Owner
------+-----------------
s02 | schema_owner_02
(1 row)
-- 变动schema的owner到另外一个子用户
alter schema s02 owner to schema_owner_01;
-- 变动后
db_demo=> \dn s02
List of schemas
Name | Owner
------+-----------------
s02 | schema_owner_01
(1 row)
复制代码
重要提示:仅仅变动owner并不能修改已有表的权限,必须经过显式赋权
-- 变动指定表owner
alter table s02.t02 owner to schema_owner_01;
-- 或者在不变动owner的状况下,批量赋权schema下的全部表
grant all on all tables in schema s02 to schema_owner_01;
复制代码
通过前面的操做,子用户02已经没有任何访问权限了。咱们但愿这个子用户在全部schema都有只读权限。
-- 主用户登陆
psql --username=db_demo_owner --dbname=db_demo --password
-- 重要提示:这种方式仅对已经存在的表有效。之后创建的表不会自动有只读权限
grant usage on schema s00, s01, s02 to schema_owner_02;
grant select on all tables in schema s00, s01, s02 to schema_owner_02;
复制代码
若是咱们但愿之后创建的全部新表均可以自动得到只读权限(对已经存在的表无效),可使用以下语句。
-- 对子用户01,02之后在schema s00,s01,s02下新建的表都有效
alter default privileges
for user schema_owner_01, schema_owner_02
in schema s00, s01, s02
grant select on tables to schema_owner_02;
复制代码