四时宝库

程序员的知识宝库

Postgresql逻辑结构之schema和表(四)

schame是位于database之下容器,用来组织数据库对象,如表、视图、索引等,表、视图等必须位于某一个schema下。

database之间是无法互相访问,但同一个database下的不同schame的对象是可以互相访问。

每一个数据库中都存在一个名称为public的schema,public用来存放在创建对象时未明确指定schema的对象,public的属主为postgres。

mydb=# \dn
  List of schemas
  Name  |  Owner   
--------+----------
 myq    | myq
 public | postgres
(2 rows)

创建schema,创建时可以指定schema的属主用户,如果不指定则为当前用户

mydb=# \dn
  List of schemas
  Name  |  Owner   
--------+----------
 public | postgres
 s1     | myq
(2 rows)

mydb=# create schema s2;
CREATE SCHEMA
mydb=# \dn
  List of schemas
  Name  |  Owner   
--------+----------
 public | postgres
 s1     | myq
 s2     | myq
(3 rows)

创建表,创建表时可以指定表位于哪个schema,如果忽略,则按照search_path的规则存放

#不指定schema
mydb=# create table a(name varchar(10));
CREATE TABLE
mydb=# \dt
       List of relations
 Schema | Name | Type  | Owner 
--------+------+-------+-------
 public | a    | table | myq
(1 row)

#指定schema
mydb=# create table s2.b(name varchar(10));
CREATE TABLE
mydb=# \dt s2.*
       List of relations
 Schema | Name | Type  | Owner 
--------+------+-------+-------
 s2     | b    | table | myq
(1 row)

搜索路径(search_path)

如一个database下有多个schema,多个schema中都有同名的对象,那么在访问对象时如何确定要访问的对象呢?

pg中有一个变量名为search_path,定义的查找对象的顺序,可以使用show search_path;命令显示变量的值

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

search_path变量的默认值为"$user", public。变量的值是schema的列表,"$user"表示与用户同名的schame,public为publicschema。

pg在查找对象时就是按照search_path中定义的schema顺序查找的。先在列表中的第一个schema即与用户同名的schame中查找对象是否存在,如果未找到继续查找第二个schema,找到即停止搜索。

mydb=# \dt
       List of relations
 Schema | Name | Type  | Owner 
--------+------+-------+-------
 myq    | a    | table | myq
(1 row)

mydb=# \dt public.*
       List of relations
 Schema | Name | Type  | Owner 
--------+------+-------+-------
 public | a    | table | myq
(1 row)

mydb=# \dt s1.*
         List of relations
 Schema |   Name   | Type  | Owner 
--------+----------+-------+-------
 s1     | a        | table | myq
 s1     | accounts | table | myq
 s1     | t        | table | myq
(3 rows)

mydb=# select * from myq.a;
 name 
------
 myq
(1 row)

mydb=# select * from public.a;
  name  
--------
 public
(1 row)

mydb=# select * from s1.a;
 name 
------
 s1
(1 row)

如果在查询时不指定schema,看下查询结果是哪个schema下的表

#存在与用户同名的schema
mydb=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 myq       | Superuser                                                  | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

mydb=# \dn
  List of schemas
  Name  |  Owner   
--------+----------
 myq    | myq
 public | postgres
 s1     | myq
(3 rows)

mydb=# select * from a;
 name 
------
 myq
(1 row)

#不存在与用户同名的schame
mydb=# \dn
  List of schemas
  Name  |  Owner   
--------+----------
 public | postgres
 s1     | myq
(2 rows)

mydb=# select * from a;
  name  
--------
 public
(1 row)

总结:

1. schema为表的容器,表必须存放于某个schema中

2. 创建表时如果未指定schema,则会按照search_path的规则查找schema存放。指定schema的语法为schema.tablename

3. search_path定义了查找对象的schema的顺序,依次搜索列表中的schema查找对象,找到即停止搜索,找到最后没找到就会报表不存在错误

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接