postgresql中,用戶創建的所有對象都被創建在指定的schema(或namespace)中。其他用戶可能擁有、也可能不擁有訪問這些對象的權限,甚至都不可以在對應的schema中創建對象。

從上面的表可以看出,用戶(或角色)是全局對象,不是定義在數據庫中,而是定義在實例的級別。schema是用戶在指定的數據庫中創建的,其中包含數據庫對象。
$ psql psql (11.9) Type "help" for help. postgres=# create table t1(a int); CREATE TABLE postgres=#
在這個創建表的語句中,並沒有指定schema。那這些表會在哪里呢?
postgres=# select schemaname from pg_tables where tablename ='t1';
schemaname
------------
public
(1 rows)
postgres=# \d t1
Table "public.t1"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
a | integer | | |
postgres=#
當你刪除了public schema后嘗試創建一個表,會發生什么呢?
postgres=# drop schema public cascade;
NOTICE: drop cascades to table t1
DROP SCHEMA
postgres=# create table t1 ( a int );
ERROR: no schema has been selected to create in
LINE 1: create table t1 ( a int );
^
postgres=#
我們現在沒有schema了:
postgres=# \dn List of schemas Name | Owner ------+------- (0 rows)
postgresql不知道去哪里創建表。這里也可以看出,在postgresql中schema和user是不同的了。我們是以postgres用戶登錄,但是沒有schema可以創建對象。
現在,我們來創建一個schema:
postgres=# create schema my_schema;
CREATE SCHEMA
postgres=# create table t1(a int);
ERROR: no schema has been selected to create in
LINE 1: create table t1(a int);
^
postgres=#
仍然不可以創建表。這里可能會問:為什么有public schema就可以呢?在上面的演示中我們並沒有指定public schema呀!這里就需要提到參數search_path了:
postgres=# show search_path; search_path ----------------- "$user", public (1 row) postgres=#
缺省情況下,search_path包含當前用戶名和public。所以會創建失敗。
postgres=# create table my_schema.t1 ( a int );
CREATE TABLE
postgres=# \d my_schema.t1
Table "my_schema.t1"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
a | integer | | |
或者調整search_path的值:
postgres = # set search_path = 'my_schema',"$user",public; SET postgres = # show search_path ; search_path ---------------------------- my_schema, "$user", public (1 row) postgres = # create table t2 ( a int ); CREATE TABLE postgres = # \d t2 Table "my_schema.t2" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- a | integer | | | postgres = #
