postgresql 模式与用户,及跨库访问

1 控制台命令
\h:查看SQL命令的解释,比如\h select。
\?:查看psql命令列表。\l:列出所有数据库。
\c [database_name]:连接其他数据库。
\d:列出当前数据库的所有表格。 \c test
\d [table_name]:列出某一张表格的结构。
\d+ tablename 查看指定表的基本情况
\du:列出所有用户和权限。
\e:打开文本编辑器。
\conninfo:列出当前数据库和连接的信息。
\q 退出
\o file_path 查询结果存储到输出文件
postgres=# \?
\dt #mysql> show tables;
\d test; //相当于mysql的,mysql> desc test;
\di //相当于mysql的,mysql> show index from test;
\l 列出所有的数据库
\d 列出用户当前模式下的表

--pg的这些控制台命令真是反人类------

2 模式
一个数据库包含一个或多个命名模式,模式中包含着表。
模式还包含其他类型的命名对象,包括数据类型、函数和操作符。
相同的对象名称可以被用于不同的模式中二不会出现冲突,例如schema1和myschema都可以包含名为mytable的表。
和数据库不同,模式并不是被严格地隔离:一个用户可以访问他所连接的数据库中的所有模式内的对象,只要他有足够的权限。
下面是一些使用模式的原因:--习惯了oracle和mysql,这个模式是真的扯淡
  允许多个用户使用一个数据库并且不会互相干扰
  将数据库对象组织成逻辑组以便更容易管理。
  第三方应用的对象可以放在独立的模式中,这样它们就不会与其他对象的名称发生冲突。
CREATE SCHEMA myschema;
在一个模式中创建或访问对象,需要使用由模式名和表名构成的限定名,模式名和表名之间以点号分隔
CREATE TABLE myschema.mytable (
...
);

hq=# create schema hq;
hq=# CREATE TABLE hq.cities1 (
name text,
population real,
altitude int -- (in ft)
);
在任何需要一个表名的地方都可以这样用,包括表修改命令和后续章节要讨论的数据访问命令
DROP SCHEMA myschema; #删除一个为空的模式
DROP SCHEMA myschema CASCADE; #删除一个模式以及其中包含的所有对象
CREATE SCHEMA schemaname AUTHORIZATION username; #创建一个由其他人所拥有的模式

公共模式
创建的表都没有指定任何模式名称,默认情况下这些表(以及其他对象)会自动的被放入一个名为“public”的模式中
CREATE TABLE products ( ... );
CREATE TABLE public.products ( ... );

模式搜索路径
hq=# SHOW search_path;
search_path
-----------------
"$user", public
第一个元素说明一个和当前用户同名的模式会被搜索。如果不存在这个模式,该项将被忽略。第二个元素指向我们已经见过的公共模式。

模式和权限
默认情况下,用户不能访问不属于他们的模式中的任何对象。要允许这种行为,模式的拥有者必须在该模式上授予USAGE权限。
要把新模式放在搜索路径中,我们可以使用:
SET search_path TO myschema,public;

user/role
hq=# create role test1_role password 'test1_role';  #创建角色
CREATE ROLE
hq=# create user test1_user password 'test1_user';  #创建用户
CREATE ROLE

hq=# select * from pg_roles; #test1_user 用户也存在表roles里面,test1_user 比test1_role 多了rolcanlogin权限
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolconnlimit | rolpassword | rolvaliduntil | rolbypassrls | rolconfig | oid
------------+----------+------------+---------------+-------------+-------------+----------------+--------------+-------------+---------------+--------------+-----------+-------
postgres | t | t | t | t | t | t | -1 | ******** | | t | | 10
dbuser | f | t | f | f | t | f | -1 | ******** | | f | | 16384
test1_role | f | t | f | f | f | f | -1 | ******** | | f | | 25330
test1_user | f | t | f | f | t | f | -1 | ******** | | f | | 25331
(4 rows)

hq=# select * from pg_user; #只有user
usename | usesysid | usecreatedb | usesuper | userepl | usebypassrls | passwd | valuntil | useconfig
------------+----------+-------------+----------+---------+--------------+----------+----------+-----------
postgres | 10 | t | t | t | t | ******** | |
dbuser | 16384 | f | f | f | f | ******** | |
test1_user | 25331 | f | f | f | f | ******** | |
登录用户 test1_user,能看见数据库hq,模式public,但看不见下面的表
select *from hq.cities1;

[Err] ERROR: permission denied for schema hq
LINE 1: select *from hq.cities1;
修改用户属性
hq=# alter role test1_role with login;  #赋予角色test1_role 能够登录的权限
ALTER ROLE

hq=# CREATE DATABASE test1_user OWNER test1_user;#创建数据库
CREATE DATABASE
create schema test1_user; #创建模式
hq=# GRANT ALL PRIVILEGES ON DATABASE test1_user to test1_user; #赋予权限
GRANT

CREATE TABLE test1_user111 (
name text,
population real,
altitude int -- (in ft)
);#创建表成功,是在public模式下
CREATE TABLE test1_user.test1_user111 (
name text,
population real,
altitude int -- (in ft)
); #创建表失败,在模式test1_user下,[Err] ERROR: permission denied for schema test1_user
#postgres用户,创建CREATE TABLE test1_user.test1_user111 成功,说明不是模式的问题,是连接用户的权限问题。但用户test1_user可以在public模式下创建表
#难道是用户和模式的共同权限??

#在命令执行
hq=# \c test1_user
You are now connected to database "test1_user" as user "postgres".
test1_user=# \z
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+---------------+-------+-------------------+-------------------+----------
public | test1_user111 | table | | |
test1_user=# GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA test1_user TO test1_user;
GRANT

CREATE TABLE test1_user.test1_user222 (
name text,
population real,
altitude int -- (in ft)
); #[Err] ERROR: permission denied for schema test1_user
test1_user=# ALTER ROLE test1_user WITH CREATEROLE CREATEDB LOGIN REPLICATION ;
ALTER ROLE


===正确逻辑
1 创建用户
create user test1_user password 'test1_user';
2 赋予权限
# ALTER ROLE test1_user WITH CREATEROLE CREATEDB LOGIN REPLICATION ;
3 登录用户test1_user并创建模式
create schema test2_user;
4 打开模式并创建表test2_user
create table test2_user.TESTCASE(
id INTEGER,
task_class INTEGER,
age TEXT,
PRIMARY KEY(id, task_class)
);
===navicat看到的表脚本
CREATE TABLE "test2_user"."testcase" (
"id" int4 NOT NULL,
"task_class" int4 NOT NULL,
"age" text COLLATE "default",
CONSTRAINT "testcase_pkey" PRIMARY KEY ("id", "task_class")
)
WITH (OIDS=FALSE)
;

ALTER TABLE "test2_user"."testcase" OWNER TO "test1_user";
===在之前创建的表中test1_user.test1_user222看到的是OWNER TO "postgres";
test1_user=# \dt
List of relations
Schema | Name | Type | Owner
--------+---------------+-------+------------
public | test1_user111 | table | test1_user
public | testcase | table | test1_user
(2 rows)


\z或\dp指令显示用户访问权限。
\h GRANT显示所有可设置的访问权限
特殊符号:ALL代表所访问权限,PUBLIC代表所有用户

hq=# GRANT SELECT ON ALL TABLES IN SCHEMA PUBLIC to test1_user; #--赋予test1_user所有表的SELECT权限
GRANT

select * from pg_tables;
#默认只能看见自己模式与pg_catalog,information_schema的表
#比如在public下执行,只能看见public,pg_catalog,information_schema的表
#而在hq模式下,只能看见hq,pg_catalog,information_schema的表

REVOKE CREATE ON SCHEMA public FROM PUBLIC;
第一个“public”是模式,第二个“public”指的是 “每一个用户”。
除public和用户创建的模式之外,每一个数据库还包括一个pg_catalog模式,它包含了系统表和所有内建的数据类型、函数以及操作符
 

========
一个数据库角色可以有一些属性,它们定义角色的权限并且与客户端认证系统交互
login privilege
CREATE ROLE name LOGIN;
CREATE USER name; (CREATE USER和CREATE ROLE等效,除了CREATE USER默认假定有LOGIN,而CREATE ROLE不这样认为)
superuser status
CREATE ROLE name SUPERUSER
database creation
CREATE ROLE name CREATEDB
role creation
CREATE ROLE name CREATEROLE
initiating replication
CREATE ROLE name REPLICATION LOGIN
password
CREATE ROLE name PASSWORD ’string’

==============跨库访问
postgres=# \dn #查看当前数据库中的模式
List of schemas
Name | Owner
--------+----------
public | postgres
(1 row)
postgres=# select user; #查看当前连接数据库的user
current_user
--------------
postgres
(1 row)
postgres=# create schema test1; #创建一个test模式
CREATE SCHEMA
postgres=# create table test1.a(id int);#在模式test1下,创建a表
CREATE TABLE
postgres=# \d #查看表,发现并没有a
List of relations
Schema | Name | Type | Owner
--------+----------+-------+----------
public | capitals | table | postgres
public | cities | table | postgres
public | cities1 | table | postgres
public | myview | view | postgres
public | weather | table | postgres
postgres=# select * from test1.a; #加上模式,能访问到表a
id
----
(0 rows)
postgres=# show search_path; #查看模式,搜索路径
search_path
-----------------
"$user", public
(1 row)
postgres=# set search_path to public,test1; #把创建的模式test1添加到模式搜索路径
SET
postgres=# show search_path;
search_path
---------------
public, test1
(1 row)

postgres=# \d #能查询到a表
List of relations
Schema | Name | Type | Owner
--------+----------+-------+----------
public | capitals | table | postgres
public | cities | table | postgres
public | cities1 | table | postgres
public | myview | view | postgres
public | weather | table | postgres
test1 | a | table | postgres
(6 rows)
postgres=# select * from test1.a; #能访问到表a
id
----
(0 rows)
==
postgres=# create schema test2;
CREATE SCHEMA
postgres=# create table test2.b(id int);
CREATE TABLE
postgres=# create role test1 login password 'test1';
CREATE ROLE
postgres=# create role test2 login password 'test2';
CREATE ROLE
postgres=# \c postgres test2;
FATAL: Peer authentication failed for user "test2"
Previous connection kept
postgres=# \c postgres
You are now connected to database "postgres" as user "postgres".
postgres=# \d
List of relations
Schema | Name | Type | Owner
--------+----------+-------+----------
public | capitals | table | postgres
public | cities | table | postgres
public | cities1 | table | postgres
public | myview | view | postgres
public | weather | table | postgres
(5 rows)

postgres=# show search_path ;
search_path
-----------------
"$user", public
(1 row)

postgres=# set search_path to public,test1;
SET
postgres=# \d
List of relations
Schema | Name | Type | Owner
--------+----------+-------+----------
public | capitals | table | postgres
public | cities | table | postgres
public | cities1 | table | postgres
public | myview | view | postgres
public | weather | table | postgres
test1 | a | table | postgres
(6 rows)
postgres-# \du #列出所有用户和权限
List of roles
Role name | Attributes | Member of
------------+------------------------------------------------------------+-----------
dbuser | | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
test1 | | {}
test1_role | | {}
test1_user | Create role, Create DB, Replication | {}
test2 | | {}
postgres-# \conninfo
You are connected to database "postgres" as user "postgres" via socket in "/var/run/postgresql" at port "5432".
postgres=# set search_path to public,test2;
SET
postgres=# \d
List of relations
Schema | Name | Type | Owner
--------+----------+-------+----------
public | capitals | table | postgres
public | cities | table | postgres
public | cities1 | table | postgres
public | myview | view | postgres
public | weather | table | postgres
test2 | b | table | postgres
(6 rows)
postgres=# select * from test2.b;
id
----
(0 rows)

postgres=# select * from b;
id
----
(0 rows)
postgres=# \c test2_user test2_user
FATAL: Peer authentication failed for user "test2_user"
Previous connection kept
postgres=# \c test2_user
You are now c
test2_user=# \d
No relations found.
test2_user=# show search_path;
search_path
-----------------
"$user", public
test2_user=# set search_path to public,test2_user;
SET
test2_user=# \d
List of relations
Schema | Name | Type | Owner
------------+----------+-------+------------
test2_user | testcase | table | test1_user

--真心觉得pg的这个,user,role,schema的定义真得是与oralce天差地别,,,感觉这个schema真是设计多余。。就单纯的角色,用户,数据库 不好吗

猜你喜欢

转载自www.cnblogs.com/yhq1314/p/10114310.html